**Always consult [better-auth.com/docs](https://better-auth.com/docs) for code examples and latest API.** Better Auth is a TypeScript-first, framework-agnostic auth framework supporting email/password, OAuth, magic links, passkeys, and more via plugins. * * *
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 toolsappNamebaseURLBETTER_AUTH_URL not setbasePath/api/auth. Set / for root.secretBETTER_AUTH_SECRET not setdatabasesecondaryStorageemailAndPassword{ enabled: true } to activatesocialProviders{ google: { clientId, clientSecret }, ... }pluginstrustedOriginspg.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>().