| name | better-auth |
| description | Integrate better-auth into Next.js 16 apps. Use for email/password, social OAuth, magic links, passkeys, 2FA setup. Covers database adapters (Prisma/Drizzle), session management, and route protection. |
better-auth Integration
Next.js 16 Breaking Changes
| Change | Before | After |
|---|
| Route protection file | middleware.ts | proxy.ts |
| Function export | export function middleware | export function proxy |
headers() | Sync | Async (await) |
cookies() | Sync | Async (await) |
params | Object | Promise (await) |
searchParams | Object | Promise (await) |
| Edge runtime in proxy | Supported | NOT supported |
npx @next/codemod@latest middleware-to-proxy .
What Matters Here
- Secret must be 32+ chars - Weak secrets = broken auth
- Database schema must match your plugins - CLI generates it:
npx @better-auth/cli generate
- Session cookies require headers - Server-side:
auth.api.getSession({ headers: await headers() })
- Email functions are YOUR responsibility - better-auth calls them, you implement sending
Required Clarifications
Before implementing, clarify:
- Which auth methods? (email/password, social, magic link, passkey)
- Which database adapter? (Prisma, Drizzle, or built-in Kysely)
- Which social providers? (Google, GitHub, Discord, etc.)
- Need 2FA? (TOTP authenticator apps)
- Email provider? (Resend, SendGrid, Nodemailer, etc.)
Fastest Correct Path
1. Install: npm install better-auth
2. Create lib/auth.ts (server config)
3. Create lib/auth-client.ts (client config)
4. Create app/api/auth/[...all]/route.ts
5. Run: npx @better-auth/cli generate
6. Run: npx prisma db push (or drizzle equivalent)
7. Add proxy.ts for route protection (Next.js 16)
8. Build your custom UI forms
What Can Go Wrong
| Problem | Cause | Fix |
|---|
| "Invalid secret" | AUTH_SECRET < 32 chars | Generate: openssl rand -base64 32 |
| Session always null | Missing headers in getSession | Pass headers: await headers() |
| DB errors on auth | Schema mismatch | Re-run npx @better-auth/cli generate |
| OAuth callback fails | Wrong redirectURI | Must match provider console exactly |
headers() type error | Not awaited | Use await headers() in Next.js 16 |
params type error | Not awaited | Use await params in Next.js 16 |
| Proxy not working | Wrong filename/export | Use proxy.ts with export function proxy |
How Do I Know I'm Done?
Must Follow
- Store ALL secrets in environment variables
- Use
auth.api.getSession() server-side, NOT client methods
- Always run CLI generate after adding plugins
- Enable email verification for production
- Use HTTPS in production (required for secure cookies)
- Use
proxy.ts for route protection in Next.js 16
Must Avoid
- Hardcoding secrets in source code
- Using edge runtime in
proxy.ts (not supported)
- Skipping email verification in production
- Calling
authClient.getSession() in server components
- Manual schema creation (use CLI instead)
- Forgetting
await on headers(), params, searchParams
Reference Files
Official Documentation
Quick Start Commands
npm install better-auth
npx @better-auth/cli generate
npx prisma db push
npx drizzle-kit generate && npx drizzle-kit migrate
npx @next/codemod@latest middleware-to-proxy .