A seamless integration between Better Auth and InstantDB that allows you to use InstantDB as your authentication database.
- Own Your Auth
π @daveycodez
bun add better-auth-instantdb@latest- π Complete Authentication: Leverage Better Auth's authentication features with InstantDB as your database
- π Session Sync: Automatically synchronize auth sessions between Better Auth and InstantDB
- π οΈ Customizable: Configure the adapter to match your specific needs
- π§© Type-Safe: Fully typed with TypeScript for improved developer experience
First you need to add the InstantDB Adapter to your Better Auth config.
import { betterAuth } from "better-auth"
import { instantDBAdapter } from "better-auth-instantdb"
import { init } from "@instantdb/admin"
import schema from "@/instant.schema"
// Create InstantDB admin client
export const adminDb = init({
schema,
appId: process.env.VITE_INSTANT_APP_ID as string,
adminToken: process.env.INSTANT_ADMIN_TOKEN,
useDateObjects: true
})
// Create Better Auth instance with InstantDB adapter
export const auth = betterAuth({
database: instantDBAdapter({
db: adminDb,
usePlural: true, // Optional: set to true if your schema uses plural table names
debugLogs: false // Optional: set to true to see detailed logs
}),
// Other Better Auth configuration options
emailAndPassword: {
enabled: true
},
})Synchronize authentication state between Better Auth and InstantDB:
import authClient from "@/lib/auth-client"
import { init } from "@instantdb/react"
import { useInstantAuth } from "better-auth-instantdb"
// Initialize InstantDB client
const db = init({
appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID
})
export function Providers({ children }) {
return (
<>
<InstantAuth db={db} authClient={authClient} persistent />
{children}
</>
)
}Run the following command in terminal:
npx @better-auth/cli generateCreate an instant.perms.ts file to secure your schema:
// instant.perms.ts
import type { InstantRules } from "@instantdb/react";
const rules = {
// Prevent creation of new attributes without explicit schema changes
attrs: {
allow: {
$default: "false",
},
},
// Auth entities permissions
users: {
bind: ["isOwner", "auth.id != null && auth.id == data.id"],
allow: {
view: "isOwner",
create: "false",
delete: "false",
update: "isOwner && (newData.email == data.email) && (newData.emailVerified == data.emailVerified) && (newData.createdAt == data.createdAt)",
},
},
accounts: {
bind: ["isOwner", "auth.id != null && auth.id == data.userId"],
allow: {
view: "isOwner",
create: "false",
delete: "false",
update: "false",
},
},
sessions: {
bind: ["isOwner", "auth.id != null && auth.id == data.userId"],
allow: {
view: "isOwner",
create: "false",
delete: "false",
update: "false",
},
},
verifications: {
allow: {
$default: "false"
}
},
// Optional permissions (public profile example)
profiles: {
bind: ["isOwner", "auth.id != null && auth.id == data.id"],
allow: {
view: "true",
create: "false",
delete: "false",
update: "isOwner",
},
},
// Add your custom entity permissions here
} satisfies InstantRules;
export default rules;After creating these files, use the InstantDB CLI to push them to your app:
# Push schema
npx instant-cli@latest push schema
# Push permissions
npx instant-cli@latest push permsUpdate your client-side InstantDB initialization to use your schema:
import { init } from "@instantdb/react"
import schema from "../../instant.schema"
export const db = init({
appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID,
schema
})Creates an adapter that allows Better Auth to use InstantDB as its database.
| Option | Type | Default | Description |
|---|---|---|---|
db |
InstantAdminDatabase |
(required) | An InstantDB admin client instance |
usePlural |
boolean |
true |
Set to false if your schema uses singular table names |
debugLogs |
boolean |
false |
Set to true to enable detailed logging |
A React hook that synchronizes authentication state between Better Auth and InstantDB.
| Parameter | Type | Description |
|---|---|---|
db |
InstantReactWebDatabase |
An InstantDB client instance |
authClient |
AuthClient |
The authClient from Better Auth |
persistent |
boolean? |
Whether to enable offline persistence for session |
MIT