Configure Better Auth server and client, set up database adapters, manage sessions, add plugins, and handle environment variables. Use when users mention Better Auth, betterauth, auth.ts, or need to set up TypeScript authentication with email/password, OAuth, or plugin configuration.
npm install better-authBETTER_AUTH_SECRET and BETTER_AUTH_URLauth.ts with database + confignpx @better-auth/cli@latest migrateGET /api/auth/ok — should return { status: "ok" }BETTER_AUTH_SECRET - Encryption secret (min 32 chars). Generate: openssl rand -base64 32BETTER_AUTH_URL - Base URL (e.g., https://example.com)baseURL/secret in config if env vars are NOT set.auth.ts in: ./, ./lib, ./utils, or under ./src. Use --config for custom path.npx @better-auth/cli@latest migrate - Apply schema (built-in adapter)npx @better-auth/cli@latest generate - Generate schema for Prisma/Drizzlenpx @better-auth/cli mcp --cursor - Add MCP to AI tools| Option | Notes |
|---|---|
appName | Optional display name |
baseURL | Only if BETTER_AUTH_URL not set |
basePath | Default /api/auth. Set / for root. |
secret | Only if BETTER_AUTH_SECRET not set |
database | Required for most features. See adapters docs. |
secondaryStorage | Redis/KV for sessions & rate limits |
emailAndPassword | { enabled: true } to activate |
socialProviders | { google: { clientId, clientSecret }, ... } |
plugins | Array of plugins |
trustedOrigins | CSRF whitelist |
pg.Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.User mapping to table users, use modelName: "user" (Prisma reference), not "users".secondaryStorage defined → sessions go there (not DB)session.storeSessionInDatabase: true to also persist to DBcookieCache → fully stateless modecompact (default) - Base64url + HMAC. Smallest.jwt - Standard JWT. Readable but signed.jwe - Encrypted. Maximum security.session.expiresIn (default 7 days), session.updateAge (refresh interval), session.cookieCache.maxAge, session.cookieCache.version (change to invalidate all sessions).user.modelName, user.fields (column mapping), user.additionalFields, user.changeEmail.enabled (disabled by default), user.deleteUser.enabled (disabled by default).account.modelName, account.accountLinking.enabled, account.storeAccountCookie (for stateless OAuth).email and name fields.emailVerification.sendVerificationEmail - Must be defined for verification to workemailVerification.sendOnSignUp / sendOnSignIn - Auto-send triggersemailAndPassword.sendResetPassword - Password reset email handleradvanced:useSecureCookies - Force HTTPS cookiesdisableCSRFCheck - ⚠️ Security riskdisableOriginCheck - ⚠️ Security riskcrossSubDomainCookies.enabled - Share cookies across subdomainsipAddress.ipAddressHeaders - Custom IP headers for proxiesdatabase.generateId - Custom ID generation or "serial"/"uuid"/falserateLimit.enabled, rateLimit.window, rateLimit.max, rateLimit.storage ("memory" | "database" | "secondary-storage").hooks.before / hooks.after - Array of { matcher, handler }. Use createAuthMiddleware. Access ctx.path, ctx.context.returned (after), ctx.context.session.databaseHooks.user.create.before/after, same for session, account. Useful for adding default values or post-creation actions.ctx.context): session, secret, authCookies, password.hash()/verify(), adapter, internalAdapter, generateId(), tables, baseURL.import { twoFactor } from "better-auth/plugins/two-factor"
from "better-auth/plugins".twoFactor, organization, passkey, magicLink, emailOtp, username, phoneNumber, admin, apiKey, bearer, jwt, multiSession, sso, oauthProvider, oidcProvider, openAPI, genericOAuth.createAuthClient({ plugins: [...] }).better-auth/client (vanilla), better-auth/react, better-auth/vue, better-auth/svelte, better-auth/solid.signUp.email(), signIn.email(), signIn.social(), signOut(), useSession(), getSession(), revokeSession(), revokeSessions().typeof auth.$Infer.Session, typeof auth.$Infer.Session.user.createAuthClient<typeof auth>().