diff --git a/better-auth/best-practices/SKILL.md b/better-auth/best-practices/SKILL.md index 3e6a4e1..ddeedc8 100644 --- a/better-auth/best-practices/SKILL.md +++ b/better-auth/best-practices/SKILL.md @@ -15,7 +15,10 @@ description: Configure Better Auth server and client, set up database adapters, 2. Set env vars: `BETTER_AUTH_SECRET` and `BETTER_AUTH_URL` 3. Create `auth.ts` with database + config 4. Create route handler for your framework -5. Run `npx @better-auth/cli@latest migrate` +5. Run migrations: + - **Built-in adapter:** `npx @better-auth/cli@latest migrate` + - **Drizzle:** `npx @better-auth/cli@latest generate --output src/db/auth-schema.ts` then `npx drizzle-kit push` (dev) or `npx drizzle-kit generate && npx drizzle-kit migrate` (prod) + - **Prisma:** `npx @better-auth/cli@latest generate --output prisma/schema.prisma` then `npx prisma migrate dev` 6. Verify: call `GET /api/auth/ok` — should return `{ status: "ok" }` --- @@ -59,10 +62,12 @@ CLI looks for `auth.ts` in: `./`, `./lib`, `./utils`, or under `./src`. Use `--c ## Database -**Direct connections:** Pass `pg.Pool`, `mysql2` pool, `better-sqlite3`, or `bun:sqlite` instance. +**Direct connections:** Pass `pg.Pool`, `mysql2` pool, `better-sqlite3`, or `bun:sqlite` instance. For Postgres, also supports `postgres` (postgres.js) and `@neondatabase/serverless`. **ORM adapters:** Import from `better-auth/adapters/drizzle`, `better-auth/adapters/prisma`, `better-auth/adapters/mongodb`. +**Drizzle provider values:** `"pg"` (PostgreSQL), `"mysql"` (MySQL), `"sqlite"` (SQLite). Must match the driver used. + **Critical:** Better Auth uses adapter model names, NOT underlying table names. If Prisma model is `User` mapping to table `users`, use `modelName: "user"` (Prisma reference), not `"users"`. --- @@ -163,6 +168,8 @@ For separate client/server projects: `createAuthClient()`. 4. **Cookie cache** - Custom session fields NOT cached, always re-fetched 5. **Stateless mode** - No DB = session in cookie only, logout on cache expiry 6. **Change email flow** - Sends to current email first, then new email +7. **Drizzle: db not initialized** - `drizzleAdapter(db, ...)` requires a `db` instance from `drizzle()`. See `create-auth` skill for setup examples (node-postgres, postgres.js, Neon). +8. **Drizzle: missing drizzle.config.ts** - `drizzle-kit` commands require a `drizzle.config.ts` pointing to the generated schema file and DB credentials. --- diff --git a/better-auth/create-auth/SKILL.md b/better-auth/create-auth/SKILL.md index 515e6dd..db3ca12 100644 --- a/better-auth/create-auth/SKILL.md +++ b/better-auth/create-auth/SKILL.md @@ -1,5 +1,5 @@ --- -name: create-auth-skill +name: create-auth description: Scaffold and implement authentication in TypeScript/JavaScript apps using Better Auth. Detect frameworks, configure database adapters, set up route handlers, add OAuth providers, and create auth UI pages. Use when users want to add login, sign-up, or authentication to a new or existing project with Better Auth. --- @@ -19,7 +19,7 @@ Before writing any code, gather requirements by scanning the project and asking Analyze the codebase to auto-detect: - **Framework** — Look for `next.config`, `svelte.config`, `nuxt.config`, `astro.config`, `vite.config`, or Express/Hono entry files. -- **Database/ORM** — Look for `prisma/schema.prisma`, `drizzle.config`, `package.json` deps (`pg`, `mysql2`, `better-sqlite3`, `mongoose`, `mongodb`). +- **Database/ORM** — Look for `prisma/schema.prisma`, `drizzle.config.ts`, `package.json` deps (`pg`, `postgres`, `@neondatabase/serverless`, `mysql2`, `better-sqlite3`, `mongoose`, `mongodb`). If `drizzle.config.ts` exists, read its `dialect` field to determine the DB type (e.g., `"postgresql"` → Drizzle + Postgres). Also check which Drizzle driver is installed (`drizzle-orm/node-postgres` → `pg`, `drizzle-orm/postgres-js` → `postgres`, `drizzle-orm/neon-http` → Neon). - **Existing auth** — Look for existing auth libraries (`next-auth`, `lucia`, `clerk`, `supabase/auth`, `firebase/auth`) in `package.json` or imports. - **Package manager** — Check for `pnpm-lock.yaml`, `yarn.lock`, `bun.lockb`, or `package-lock.json`. @@ -236,7 +236,10 @@ Add OAuth secrets as needed: `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `GOOGLE |---------|---------| | Built-in Kysely | `npx @better-auth/cli@latest migrate` (applies directly) | | Prisma | `npx @better-auth/cli@latest generate --output prisma/schema.prisma` then `npx prisma migrate dev` | -| Drizzle | `npx @better-auth/cli@latest generate --output src/db/auth-schema.ts` then `npx drizzle-kit push` | +| Drizzle (dev) | `npx @better-auth/cli@latest generate --output src/db/auth-schema.ts` then `npx drizzle-kit push` | +| Drizzle (prod) | `npx @better-auth/cli@latest generate --output src/db/auth-schema.ts` then `npx drizzle-kit generate` then `npx drizzle-kit migrate` | + +> **Note:** `drizzle-kit push` skips migration files and is only safe for development. Use `drizzle-kit generate` + `drizzle-kit migrate` in production. **Re-run after adding plugins.** @@ -250,9 +253,75 @@ Add OAuth secrets as needed: `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `GOOGLE | PostgreSQL | Pass `pg.Pool` instance directly | | MySQL | Pass `mysql2` pool directly | | Prisma | `prismaAdapter(prisma, { provider: "postgresql" })` from `better-auth/adapters/prisma` | -| Drizzle | `drizzleAdapter(db, { provider: "pg" })` from `better-auth/adapters/drizzle` | +| Drizzle (pg) | `drizzleAdapter(db, { provider: "pg" })` from `better-auth/adapters/drizzle` | +| Drizzle (mysql) | `drizzleAdapter(db, { provider: "mysql" })` from `better-auth/adapters/drizzle` | +| Drizzle (sqlite) | `drizzleAdapter(db, { provider: "sqlite" })` from `better-auth/adapters/drizzle` | | MongoDB | `mongodbAdapter(db)` from `better-auth/adapters/mongodb` | +### Drizzle + PostgreSQL Setup + +Before using `drizzleAdapter`, initialize the `db` instance: + +```ts +// Option 1: node-postgres (pg) +import { drizzle } from "drizzle-orm/node-postgres" +import { Pool } from "pg" +import * as schema from "./auth-schema" + +const pool = new Pool({ connectionString: process.env.DATABASE_URL }) +export const db = drizzle(pool, { schema }) +``` + +```ts +// Option 2: postgres.js +import { drizzle } from "drizzle-orm/postgres-js" +import postgres from "postgres" +import * as schema from "./auth-schema" + +const client = postgres(process.env.DATABASE_URL!) +export const db = drizzle(client, { schema }) +``` + +```ts +// Option 3: Neon serverless +import { drizzle } from "drizzle-orm/neon-http" +import { neon } from "@neondatabase/serverless" +import * as schema from "./auth-schema" + +const sql = neon(process.env.DATABASE_URL!) +export const db = drizzle(sql, { schema }) +``` + +Then pass to Better Auth: + +```ts +import { betterAuth } from "better-auth" +import { drizzleAdapter } from "better-auth/adapters/drizzle" +import { db } from "./db" + +export const auth = betterAuth({ + database: drizzleAdapter(db, { provider: "pg" }), + // ... +}) +``` + +### Drizzle Config (`drizzle.config.ts`) + +Required for `drizzle-kit` commands to find your schema: + +```ts +import { defineConfig } from "drizzle-kit" + +export default defineConfig({ + schema: "./src/db/auth-schema.ts", + out: "./drizzle", + dialect: "postgresql", + dbCredentials: { + url: process.env.DATABASE_URL!, + }, +}) +``` + --- ## Common Plugins diff --git a/better-auth/organization/SKILL.md b/better-auth/organization/SKILL.md index 0e84a84..6f2f644 100644 --- a/better-auth/organization/SKILL.md +++ b/better-auth/organization/SKILL.md @@ -7,7 +7,7 @@ description: Configure multi-tenant organizations, manage members and invitation 1. Add `organization()` plugin to server config 2. Add `organizationClient()` plugin to client config -3. Run `npx @better-auth/cli migrate` +3. Run `npx @better-auth/cli@latest migrate` (built-in adapter) or generate + push for Drizzle/Prisma 4. Verify: check that organization, member, invitation tables exist in your database ```ts diff --git a/better-auth/twoFactor/SKILL.md b/better-auth/twoFactor/SKILL.md index cf9c30b..74acac8 100644 --- a/better-auth/twoFactor/SKILL.md +++ b/better-auth/twoFactor/SKILL.md @@ -7,7 +7,7 @@ description: Configure TOTP authenticator apps, send OTP codes via email/SMS, ma 1. Add `twoFactor()` plugin to server config with `issuer` 2. Add `twoFactorClient()` plugin to client config -3. Run `npx @better-auth/cli migrate` +3. Run `npx @better-auth/cli@latest migrate` (built-in adapter) or generate + push for Drizzle/Prisma 4. Verify: check that `twoFactorSecret` column exists on user table ```ts