PromptShop

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-practices

Details

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

OptionNotes
app. NameOptional display name
baseURLOnly if BETTER_AUTH_URL not set
base. PathDefault /api/auth. Set / for root.
secretOnly if BETTER_AUTH_SECRET not set
databaseRequired for most features. See adapters docs.
secondary. StorageRedis/KV for sessions & rate limits
email. AndPassword{ enabled: true } to activate
social. Providers{ google: { client. Id, client. Secret }, ... }
pluginsArray of plugins
trusted. OriginsCSRF 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

OptionNotes
app. NameOptional display name
baseURLOnly if BETTER_AUTH_URL not set
base. PathDefault /api/auth. Set / for root.
secretOnly if BETTER_AUTH_SECRET not set
databaseRequired for most features. See adapters docs.
secondary. StorageRedis/KV for sessions & rate limits
email. AndPassword{ enabled: true } to activate
social. Providers{ google: { client. Id, client. Secret }, ... }
pluginsArray of plugins
trusted. OriginsCSRF whitelist

Database

  • Direct connections: Pass pg.
  • Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.

ORM adapters: Import f