Better Auth Best Practices
It outlines the necessary environment variables, CLI commands, core configuration options, and database setup for seamless authentication.
Install
npx promptshop add better-auth-best-practicesDetails
What This Skill Does
- This skill provides a quick reference and setup guide for integrating Better Auth into applications.
- It outlines the necessary environment variables, CLI commands, core configuration options, and database setup for seamless authentication.
- This is useful for developers looking to quickly implement and configure Better Auth.
When to Use
- Quickly set up Better Auth in a new project.
- Troubleshoot common configuration issues.
- Understand the required environment variables.
- Use CLI commands for schema migrations.
- Configure database adapters for different OR.
- Ms.
- Customize authentication flows with plugins.
Key Features
- Provides setup workflow steps.
- Lists required environment variables.
- Details CLI commands for schema management.
- Explains core configuration options.
- Offers guidance on database adapter setup.
- Highlights the use of plugins for customization.
Manual Installation
- Manual installation.
- View Full Skill Content.
- The complete markdown content that gets installed.
- Better Auth Integration Guide.
Always consult better-auth.com/docs for code examples and latest API.
Setup Workflow
Install: npm install better-auth Set env vars: BETTER_AUTH_SECRET and BETTER_AUTH_URL Create auth.ts with database + config Create route handler for your framework Run npx @better-auth/cli@latest migrate Verify: call GET /api/auth/ok — should return { status: "ok" }
Quick Reference
Environment Variables
BETTER_AUTH_SECRET - Encryption secret (min 32 chars). Generate: openssl rand -base64 32 BETTER_AUTH_URL - Base URL (e.g., https://example.com)
Only define baseURL/secret in config if env vars are NOT set.
File Location
- CLI looks for auth.ts in: ./, ./lib, ./utils, or under ./src.
- Use --config for custom path.
CLI Commands
npx @better-auth/cli@latest migrate - Apply schema (built-in adapter) npx @better-auth/cli@latest generate - Generate schema for Prisma/Drizzle npx @better-auth/cli mcp --cursor - Add MCP to AI tools
Re-run after adding/changing plugins.
Core Config Options
| Option | Notes |
|---|---|
| app. Name | Optional display name |
| baseURL | Only if BETTER_AUTH_URL not set |
| base. Path | Default /api/auth. Set / for root. |
| secret | Only if BETTER_AUTH_SECRET not set |
| database | Required for most features. See adapters docs. |
| secondary. Storage | Redis/KV for sessions & rate limits |
| email. AndPassword | { enabled: true } to activate |
| social. Providers | { google: { client. Id, client. Secret }, ... } |
| plugins | Array of plugins |
| trusted. Origins | CSRF whitelist |
Database
- Direct connections: Pass pg.
- Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.
ORM adapters: Import from better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.
Critical: Better Auth uses adapter model names, NOT underlying table names. If Prisma model is User mapping to table users, use model. Name: "user" (Prisma reference), not "users".
Session Management
Storage priority: If secondary. Storage defined → sessions go there (not DB) Set session.store. SessionIn. Database: true to also persist to DB No database + cookie. Cache → fully stateless mode
Cookie cache strategies: compact (default) - Base64url + HMAC. Smallest. jwt - Standard JWT. Readable but signed. jwe - Encrypted. Maximum security.
Key options: session.expires. In (default 7 days), session.update. Age (refresh interval), session.cookie. Cache.max. Age, session.cookie. Cache.version (change to invalidate all sessions).
User & Account Config
- User: user.model.
- Name, user.fields (column mapping), user.additional.
- Fields, user.change.
- Email.enabled (disabled by default), user.delete.
- User.enabled (disabled by default).
Account: account.model. Name, account.account. Linking.enabled, account.store. AccountCookie (for stateless OAuth).
Required for registration: email and name fields.
Email Flows
- email.
- Verification.send.
- VerificationEmail - Must be defined for verification to work. email. Verification.send. OnSign. Up / send. OnSign. In - Auto-send triggers email. AndPassword.send. ResetPassword - Password reset email handler
Security
In advanced:
use. SecureCookies - Force HTTPS cookies
disableCSRF. Check - ⚠️ Security risk
disable. OriginCheck - ⚠️ Security risk
cross. SubDomain. Cookies.enabled - Share cookies across subdomains
ip. Address.ip. AddressHeaders - Custom IP headers for proxies
database.generate. Id - Custom ID generation or "serial"/"uuid"/false
Rate limiting: rate. Limit.enabled, rate. Limit.window, rate. Limit.max, rate. Limit.storage ("memory" | "database" | "secondary-storage").
Hooks
- Endpoint hooks: hooks.before / hooks.after - Array of { matcher, handler }.
- Use create.
- AuthMiddleware.
- Access ctx.path, ctx.context.returned (after), ctx.context.session.
Database hooks: database. Hooks.user.create.before/after, same for session, account. Useful for adding default values or post-creation actions.
Hook context (ctx.context): session, secret, auth. Cookies, password.hash()/verify(), adapter, internal. Adapter, generate. Id(), tables, baseURL.
Plugins
Import from dedicated paths for tree-shaking: import { two. Factor } from "better-auth/plugins/two-factor" NOT from "better-auth/plugins".
Popular plugins: two. Factor, organization, passkey, magic. Link, email. Otp, username, phone. Number, admin, api. Key, bearer, jwt, multi. Session, sso, oauth. Provider, oidc. Provider, openAPI, genericOAuth.
Client
- plugins go in create.
- AuthClient({ plugins: [...] }).
Client
Import from: better-auth/client (vanilla), better-auth/react, better-auth/vue, better-auth/svelte, better-auth/solid.
Key methods: sign. Up.email(), sign. In.email(), sign. In.social(), sign. Out(), use. Session(), get. Session(), revoke. Session(), revoke. Sessions().
Type Safety
- Infer types: typeof auth.$Infer.
- Session, typeof auth.$Infer.
- Session.user.
For separate client/server projects: create. AuthClient().
Common Gotchas
Model vs table name - Config uses ORM model name, not DB table name Plugin schema - Re-run CLI after adding plugins Secondary storage - Sessions go there by default, not DB Cookie cache - Custom session fields NOT cached, always re-fetched Stateless mode - No DB = session in cookie only, logout on cache expiry Change email flow - Sends to current email first, then new email
Resources
Docs Options Reference LL. Ms.txt Git. Hub Init Options Source. Better Auth Integration Guide
Always consult better-auth.com/docs for code examples and latest API.
Setup Workflow
Install: npm install better-auth Set env vars: BETTER_AUTH_SECRET and BETTER_AUTH_URL Create auth.ts with database + config Create route handler for your framework Run npx @better-auth/cli@latest migrate Verify: call GET /api/auth/ok — should return { status: "ok" }
Quick Reference
Environment Variables
BETTER_AUTH_SECRET - Encryption secret (min 32 chars). Generate: openssl rand -base64 32 BETTER_AUTH_URL - Base URL (e.g., https://example.com)
Only define baseURL/secret in config if env vars are NOT set.
File Location
- CLI looks for auth.ts in: ./, ./lib, ./utils, or under ./src.
- Use --config for custom path.
CLI Commands
npx @better-auth/cli@latest migrate - Apply schema (built-in adapter) npx @better-auth/cli@latest generate - Generate schema for Prisma/Drizzle npx @better-auth/cli mcp --cursor - Add MCP to AI tools
Re-run after adding/changing plugins.
Core Config Options
| Option | Notes |
|---|---|
| app. Name | Optional display name |
| baseURL | Only if BETTER_AUTH_URL not set |
| base. Path | Default /api/auth. Set / for root. |
| secret | Only if BETTER_AUTH_SECRET not set |
| database | Required for most features. See adapters docs. |
| secondary. Storage | Redis/KV for sessions & rate limits |
| email. AndPassword | { enabled: true } to activate |
| social. Providers | { google: { client. Id, client. Secret }, ... } |
| plugins | Array of plugins |
| trusted. Origins | CSRF whitelist |
Database
- Direct connections: Pass pg.
- Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.
ORM adapters: Import f