Auth
Better Auth
Pre-configured authentication with ORM adapter integration, API routes, and shared auth package for monorepos.
Supported frameworks
Dependencies
Requirements: Database + ORM (Drizzle or Prisma)
What create-faster adds
Files added:
src/
├── lib/auth/
│ ├── auth.ts # Server auth config
│ └── auth-client.ts # Client auth helpers
└── app/api/auth/[...all]/
└── route.ts # Auth API handler
# Turborepo only:
packages/auth/
├── src/
│ ├── auth.ts
│ ├── auth-client.ts
│ ├── route.ts
│ └── types.ts
├── package.json # @repo/auth
└── tsconfig.jsonEnvironment variables:
BETTER_AUTH_SECRET- Auth secret key (scoped to auth package + app)BETTER_AUTH_URL- Auth URL (scoped to app)
auth.ts
Server-side auth configuration with ORM adapter. Shown here with Drizzle + PostgreSQL:
import { db, userAccountTable, userSessionTable, userTable, userVerificationTable } from '@/lib/db';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { betterAuth } from 'better-auth';
import { nextCookies } from 'better-auth/next-js';
const HOUR = 60 * 60;
const DAY = 24 * HOUR;
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: 'pg',
usePlural: false,
schema: {
user: userTable,
account: userAccountTable,
session: userSessionTable,
verification: userVerificationTable,
},
}),
plugins: [nextCookies()],
emailAndPassword: {
enabled: true,
minPasswordLength: 6,
revokeSessionsOnPasswordReset: true,
},
user: {
modelName: 'user',
fields: {
name: 'username',
email: 'email',
emailVerified: 'emailVerified',
image: 'avatarUrl',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
},
session: {
modelName: 'session',
expiresIn: 15 * DAY,
},
account: { modelName: 'account' },
verification: { modelName: 'verification' },
});Adapts automatically based on ORM and database selection:
- Drizzle: Uses
drizzleAdapterwithpgormysqlprovider - Prisma: Uses
prismaAdapterwithpostgresqlormysqlprovider
auth-client.ts
Client-side auth helpers with type inference:
import { inferAdditionalFields } from 'better-auth/client/plugins';
import { createAuthClient } from 'better-auth/react';
import type { auth } from './auth';
export const authClient = createAuthClient({
baseURL: process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_BETTER_AUTH_URL,
plugins: [inferAdditionalFields<typeof auth>()],
});route.ts
Next.js API route handler:
import { toNextJsHandler } from 'better-auth/next-js';
import { auth } from '@/lib/auth/auth';
export const { GET, POST } = toNextJsHandler(auth.handler);In turborepo mode, the app re-exports from @repo/auth/route-nextjs instead.
Turborepo mode:
Creates @repo/auth package depending on @repo/db for database access. Auth config lives in the package, app imports handlers.

