Guide for adding authentication to TypeScript/JavaScript applications using Better Auth. **For code examples and syntax, see [better-auth.com/docs](https://better-auth.com/docs).** * * *
Is this a new/empty project? ├─ YES → New project setup │ 1. Identify framework │ 2. Choose database │ 3. Install better-auth │ 4. Create auth.ts + auth-client.ts │ 5. Set up route handler │ 6. Run CLI migrate/generate │ 7. Add features via plugins │ └─ NO → Does project have existing auth? ├─ YES → Migration/enhancement │ • Audit current auth for gaps │ • Plan incremental migration │ • See migration guides in docs │ └─ NO → Add auth to existing project 1. Analyze project structure 2. Install better-auth 3. Create auth config 4. Add route handler 5. Run schema migrations 6. Integrate into existing pages
npm install better-auth@better-auth/passkey@better-auth/sso@better-auth/stripe@better-auth/scim@better-auth/expoBETTER_AUTH_SECRET=<32+ chars, generate with: openssl rand -base64 32> BETTER_AUTH_URL=http://localhost:3000 DATABASE_URL=<your database connection string>
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GOOGLE_CLIENT_ID, etc.lib/auth.ts or src/lib/auth.tsdatabase - Connection or adapteremailAndPassword: { enabled: true } - For email/password authsocialProviders - OAuth providers (google, github, etc.)emailVerification.sendVerificationEmail - Email verification handleremailAndPassword.sendResetPassword - Password reset handlerplugins - Array of feature pluginssession - Expiry, cookie cache settingsaccount.accountLinking - Multi-provider linkingrateLimit - Rate limiting configexport type Session = typeof auth.$Infer.Sessionbetter-auth/reactbetter-auth/vuebetter-auth/sveltebetter-auth/solidbetter-auth/clientcreateAuthClient({ plugins: [...] }).signIn, signUp, signOut, useSession, getSessionapp/api/auth/[...all]/route.tstoNextJsHandler(auth) → export { GET, POST }pages/api/auth/[...all].tstoNextJsHandler(auth) → default exportapp.all("/api/auth/*", toNodeHandler(auth))src/hooks.server.tssvelteKitHandler(auth)solidStartHandler(auth)auth.handler(c.req.raw)nextCookies() plugin to auth config.npx @better-auth/cli@latest migrate (applies directly)npx @better-auth/cli@latest generate --output prisma/schema.prisma then npx prisma migrate devnpx @better-auth/cli@latest generate --output src/db/auth-schema.ts then npx drizzle-kit pushbetter-sqlite3 or bun:sqlite instance directlypg.Pool instance directlymysql2 pool directlyprismaAdapter(prisma, { provider: "postgresql" }) from better-auth/adapters/prismadrizzleAdapter(db, { provider: "pg" }) from better-auth/adapters/drizzlemongodbAdapter(db) from better-auth/adapters/mongodbtwoFactorbetter-auth/pluginstwoFactorClientorganizationbetter-auth/pluginsorganizationClientadminbetter-auth/pluginsadminClientbearerbetter-auth/pluginsopenAPIbetter-auth/pluginspasskey@better-auth/passkeypasskeyClientsso@better-auth/ssosignIn.email({ email, password }) or signIn.social({ provider, callbackURL })error in responseuseSession() hook returns { data: session, isPending }auth.api.getSession({ headers: await headers() })/sign-in if null.BETTER_AUTH_SECRET set (32+ chars)advanced.useSecureCookies: true in productiontrustedOrigins configuredaccount.accountLinking reviewedBETTER_AUTH_SECRET env vartrustedOriginsbaseURL matches domain; enable secure cookies in prod