Better Auth Best Practices
Implementation and migration guide for Better Auth, the framework-agnostic TypeScript authentication and authorization library. This skill contains 42 rules organized by impact across 8 categories, derived from the official documentation and migration guides.
When to Apply
Reference these guidelines when:
- Setting up a fresh Better Auth instance (config, adapter, route handler, client)
- Wiring framework-specific integrations (Next.js App/Pages Router, SvelteKit, Hono, Express, Nuxt, Astro)
- Configuring sessions, cookies, and security (rate limit, trusted origins, password hashing)
- Adding plugins: 2FA, organization, admin, magicLink, JWT, passkey, multi-session
- Migrating from another auth library (NextAuth/Auth.js, Clerk, Auth0, Supabase Auth)
- Debugging "session is null" / "redirect_uri_mismatch" / 403 CSRF errors
- Reviewing PRs that touch
lib/auth.ts, auth-client.ts, or /api/auth/ route handlers
Rule Categories by Priority
| Priority |
Category |
Impact |
Prefix |
| 1 |
Setup & Configuration |
CRITICAL |
setup- |
| 2 |
Database Adapters & Schema |
CRITICAL |
db- |
| 3 |
API Route Handlers |
CRITICAL |
route- |
| 4 |
Session & Cookies |
HIGH |
session- |
| 5 |
Auth Methods & Providers |
HIGH |
auth- |
| 6 |
Security & Hardening |
HIGH |
security- |
| 7 |
Plugins & Extensions |
MEDIUM |
plugins- |
| 8 |
Migration from Other Auth |
MEDIUM |
migrate- |
Quick Reference
1. Setup & Configuration (CRITICAL)
setup-secret — Set a strong BETTER_AUTH_SECRET per environment
setup-base-url — Configure an explicit baseURL per environment
setup-client-base-url — Match the client baseURL to the server
setup-singleton — Export a single auth instance from a server-only module
setup-trusted-origins — Configure trustedOrigins for all non-baseURL callers
2. Database Adapters & Schema (CRITICAL)
db-adapter-selection — Pick the adapter that matches your ORM
db-schema-generate — Run auth generate then ORM migrate before every deploy
db-additional-fields — Extend the user schema via additionalFields
db-plugin-schema-customization — Rename plugin tables via the schema option
db-database-hooks — Use databaseHooks for cross-cutting logic
db-connection-pooling — Share one pooled DB client with the rest of your app
3. API Route Handlers (CRITICAL)
route-mount-catchall — Mount the catch-all handler at /api/auth/[...all]
route-runtime-selection — Use the Node.js runtime for middleware that calls auth.api
route-no-body-consumers — Mount auth before any body-parsing middleware
4. Session & Cookies (HIGH)
session-server-vs-client — Use auth.api.getSession on server, authClient.useSession on client
session-expiry-tuning — Configure expiresIn and updateAge together
session-cookie-cache — Enable cookieCache to cut session DB lookups
session-cookie-attributes — Set sameSite, secure, partitioned for cross-site flows
session-cross-subdomain — Enable crossSubDomainCookies for multi-subdomain apps
session-customsession-fields — Use customSession to add computed fields
5. Auth Methods & Providers (HIGH)
auth-require-email-verification — Enable requireEmailVerification with sendVerificationEmail
auth-oauth-redirect-uri — Match OAuth redirectURI exactly with the provider console
auth-oauth-env-vars — Load OAuth credentials from environment, never inline
auth-magic-link-setup — Implement sendMagicLink before enabling the magicLink plugin
auth-client-sign-in-helpers — Use authClient.signIn.social with callbackURL
auth-infer-additional-fields — Add inferAdditionalFields to the client for type sync
6. Security & Hardening (HIGH)
security-rate-limit — Enable rateLimit with persistent storage in production
security-password-hash-interop — Override hash function when migrating from bcrypt/argon2
security-revoke-on-password-reset — Enable revokeSessionsOnPasswordReset
security-min-password-length — Set minPasswordLength to at least 10
security-trusted-origins-strict — Never wildcard trustedOrigins
7. Plugins & Extensions (MEDIUM)
plugins-next-cookies-last — Place nextCookies() as the LAST plugin in Next.js
plugins-two-factor-issuer — Set appName as the 2FA issuer
plugins-shared-access-control — Define ac + roles once, share server/client
plugins-pair-client-server — Pair every server plugin with its client counterpart
plugins-organization-active-context — Set active organization on session
plugins-jwt-when-to-use — Use the jwt plugin only for external service consumers
plugins-admin-impersonation — Use admin plugin's impersonate method for support access
8. Migration from Other Auth (MEDIUM)
migrate-parallel-cutover — Run Better Auth alongside legacy auth during cutover
migrate-oauth-account-mapping — Map legacy OAuth identities to account rows
migrate-force-allow-id — Use forceAllowId to preserve existing user IDs
migrate-nextauth-schema-mapping — Map NextAuth v5 columns field-by-field
How to Use
For a fresh implementation, read in priority order: start with all setup- rules, then db-, then route- — these CRITICAL categories must be correct or nothing else works. After the foundation, pick the rules that match your scope: session- for cookie/expiry tuning, auth- for provider configuration, security- for production hardening.
For a migration from another auth library, read migrate-parallel-cutover first (strategy), then security-password-hash-interop (preserve user passwords), then migrate-oauth-account-mapping and migrate-nextauth-schema-mapping (data layout).
Read individual reference files for detailed explanations, incorrect vs. correct code examples, and links to the canonical Better Auth documentation.
Reference Files
| File |
Description |
| references/_sections.md |
Category definitions ordered by impact |
| assets/templates/_template.md |
Template for adding new rules |
| metadata.json |
Version, references, and discipline metadata |
1---2name: better-auth3description: Better Auth in TypeScript — setting up the auth instance, picking adapters, wiring framework route handlers, configuring sessions and cookies, adding plugins (2FA, organization, admin, magicLink, JWT), or porting from NextAuth/Auth.js, Clerk, Auth0, or Supabase Auth. Covers Next.js, SvelteKit, Hono, Express, Nuxt, Astro, and React/Vue/Svelte clients. Trigger when writing, reviewing, or migrating Better Auth code — and even when the user doesn't explicitly mention Better Auth but is working on TypeScript authentication, session cookies, OAuth providers, or auth-library migration. Contains 42 rules organized by impact across 8 categories.4---5# Better Auth Best Practices
6
7Implementation and migration guide for [Better Auth](https://www.better-auth.com), the framework-agnostic TypeScript authentication and authorization library. This skill contains 42 rules organized by impact across 8 categories, derived from the official documentation and migration guides.
8
9## When to Apply
10
11Reference these guidelines when:
12
13- Setting up a fresh Better Auth instance (config, adapter, route handler, client)
14- Wiring framework-specific integrations (Next.js App/Pages Router, SvelteKit, Hono, Express, Nuxt, Astro)
15- Configuring sessions, cookies, and security (rate limit, trusted origins, password hashing)
16- Adding plugins: 2FA, organization, admin, magicLink, JWT, passkey, multi-session
17- Migrating from another auth library (NextAuth/Auth.js, Clerk, Auth0, Supabase Auth)
18- Debugging "session is null" / "redirect_uri_mismatch" / 403 CSRF errors
19- Reviewing PRs that touch `lib/auth.ts`, `auth-client.ts`, or `/api/auth/` route handlers
20
21## Rule Categories by Priority
22
23| Priority | Category | Impact | Prefix |
24|----------|----------|--------|--------|
25| 1 | Setup & Configuration | CRITICAL | `setup-` |
26| 2 | Database Adapters & Schema | CRITICAL | `db-` |
27| 3 | API Route Handlers | CRITICAL | `route-` |
28| 4 | Session & Cookies | HIGH | `session-` |
29| 5 | Auth Methods & Providers | HIGH | `auth-` |
30| 6 | Security & Hardening | HIGH | `security-` |
31| 7 | Plugins & Extensions | MEDIUM | `plugins-` |
32| 8 | Migration from Other Auth | MEDIUM | `migrate-` |
33
34## Quick Reference
35
36### 1. Setup & Configuration (CRITICAL)
37
38- [`setup-secret`](references/setup-secret.md) — Set a strong `BETTER_AUTH_SECRET` per environment
39- [`setup-base-url`](references/setup-base-url.md) — Configure an explicit `baseURL` per environment
40- [`setup-client-base-url`](references/setup-client-base-url.md) — Match the client `baseURL` to the server
41- [`setup-singleton`](references/setup-singleton.md) — Export a single auth instance from a server-only module
42- [`setup-trusted-origins`](references/setup-trusted-origins.md) — Configure `trustedOrigins` for all non-baseURL callers
43
44### 2. Database Adapters & Schema (CRITICAL)
45
46- [`db-adapter-selection`](references/db-adapter-selection.md) — Pick the adapter that matches your ORM
47- [`db-schema-generate`](references/db-schema-generate.md) — Run `auth generate` then ORM migrate before every deploy
48- [`db-additional-fields`](references/db-additional-fields.md) — Extend the user schema via `additionalFields`
49- [`db-plugin-schema-customization`](references/db-plugin-schema-customization.md) — Rename plugin tables via the `schema` option
50- [`db-database-hooks`](references/db-database-hooks.md) — Use `databaseHooks` for cross-cutting logic
51- [`db-connection-pooling`](references/db-connection-pooling.md) — Share one pooled DB client with the rest of your app
52
53### 3. API Route Handlers (CRITICAL)
54
55- [`route-mount-catchall`](references/route-mount-catchall.md) — Mount the catch-all handler at `/api/auth/[...all]`
56- [`route-runtime-selection`](references/route-runtime-selection.md) — Use the Node.js runtime for middleware that calls `auth.api`
57- [`route-no-body-consumers`](references/route-no-body-consumers.md) — Mount auth before any body-parsing middleware
58
59### 4. Session & Cookies (HIGH)
60
61- [`session-server-vs-client`](references/session-server-vs-client.md) — Use `auth.api.getSession` on server, `authClient.useSession` on client
62- [`session-expiry-tuning`](references/session-expiry-tuning.md) — Configure `expiresIn` and `updateAge` together
63- [`session-cookie-cache`](references/session-cookie-cache.md) — Enable `cookieCache` to cut session DB lookups
64- [`session-cookie-attributes`](references/session-cookie-attributes.md) — Set `sameSite`, `secure`, `partitioned` for cross-site flows
65- [`session-cross-subdomain`](references/session-cross-subdomain.md) — Enable `crossSubDomainCookies` for multi-subdomain apps
66- [`session-customsession-fields`](references/session-customsession-fields.md) — Use `customSession` to add computed fields
67
68### 5. Auth Methods & Providers (HIGH)
69
70- [`auth-require-email-verification`](references/auth-require-email-verification.md) — Enable `requireEmailVerification` with `sendVerificationEmail`
71- [`auth-oauth-redirect-uri`](references/auth-oauth-redirect-uri.md) — Match OAuth `redirectURI` exactly with the provider console
72- [`auth-oauth-env-vars`](references/auth-oauth-env-vars.md) — Load OAuth credentials from environment, never inline
73- [`auth-magic-link-setup`](references/auth-magic-link-setup.md) — Implement `sendMagicLink` before enabling the `magicLink` plugin
74- [`auth-client-sign-in-helpers`](references/auth-client-sign-in-helpers.md) — Use `authClient.signIn.social` with `callbackURL`
75- [`auth-infer-additional-fields`](references/auth-infer-additional-fields.md) — Add `inferAdditionalFields` to the client for type sync
76
77### 6. Security & Hardening (HIGH)
78
79- [`security-rate-limit`](references/security-rate-limit.md) — Enable `rateLimit` with persistent storage in production
80- [`security-password-hash-interop`](references/security-password-hash-interop.md) — Override hash function when migrating from bcrypt/argon2
81- [`security-revoke-on-password-reset`](references/security-revoke-on-password-reset.md) — Enable `revokeSessionsOnPasswordReset`
82- [`security-min-password-length`](references/security-min-password-length.md) — Set `minPasswordLength` to at least 10
83- [`security-trusted-origins-strict`](references/security-trusted-origins-strict.md) — Never wildcard `trustedOrigins`
84
85### 7. Plugins & Extensions (MEDIUM)
86
87- [`plugins-next-cookies-last`](references/plugins-next-cookies-last.md) — Place `nextCookies()` as the LAST plugin in Next.js
88- [`plugins-two-factor-issuer`](references/plugins-two-factor-issuer.md) — Set `appName` as the 2FA issuer
89- [`plugins-shared-access-control`](references/plugins-shared-access-control.md) — Define `ac` + roles once, share server/client
90- [`plugins-pair-client-server`](references/plugins-pair-client-server.md) — Pair every server plugin with its client counterpart
91- [`plugins-organization-active-context`](references/plugins-organization-active-context.md) — Set active organization on session
92- [`plugins-jwt-when-to-use`](references/plugins-jwt-when-to-use.md) — Use the `jwt` plugin only for external service consumers
93- [`plugins-admin-impersonation`](references/plugins-admin-impersonation.md) — Use admin plugin's `impersonate` method for support access
94
95### 8. Migration from Other Auth (MEDIUM)
96
97- [`migrate-parallel-cutover`](references/migrate-parallel-cutover.md) — Run Better Auth alongside legacy auth during cutover
98- [`migrate-oauth-account-mapping`](references/migrate-oauth-account-mapping.md) — Map legacy OAuth identities to `account` rows
99- [`migrate-force-allow-id`](references/migrate-force-allow-id.md) — Use `forceAllowId` to preserve existing user IDs
100- [`migrate-nextauth-schema-mapping`](references/migrate-nextauth-schema-mapping.md) — Map NextAuth v5 columns field-by-field
101
102## How to Use
103
104For a fresh implementation, read in priority order: start with all `setup-` rules, then `db-`, then `route-` — these CRITICAL categories must be correct or nothing else works. After the foundation, pick the rules that match your scope: `session-` for cookie/expiry tuning, `auth-` for provider configuration, `security-` for production hardening.
105
106For a migration from another auth library, read `migrate-parallel-cutover` first (strategy), then `security-password-hash-interop` (preserve user passwords), then `migrate-oauth-account-mapping` and `migrate-nextauth-schema-mapping` (data layout).
107
108Read individual reference files for detailed explanations, incorrect vs. correct code examples, and links to the canonical Better Auth documentation.
109
110## Reference Files
111
112| File | Description |
113|------|-------------|
114| [references/_sections.md](references/_sections.md) | Category definitions ordered by impact |
115| [assets/templates/_template.md](assets/templates/_template.md) | Template for adding new rules |
116| [metadata.json](metadata.json) | Version, references, and discipline metadata |