create-auth

Andamia e implementa autenticación en aplicaciones TypeScript/JavaScript usando Better Auth. Detecta frameworks, configura adaptadores de base de datos, establece manejadores de rutas,…

npx skills add https://github.com/better-auth/skills --skill create-auth

Create Auth Skill

Guide for adding authentication to TypeScript/JavaScript applications using Better Auth.

For code examples and syntax, see better-auth.com/docs.


Phase 1: Planning (REQUIRED before implementation)

Before writing any code, gather requirements by scanning the project and asking the user structured questions. This ensures the implementation matches their needs.

Step 1: Scan the project

Analyze the codebase to auto-detect:

  • Framework — Look for next.config, svelte.config, nuxt.config, astro.config, vite.config, or Express/Hono entry files.
  • Database/ORM — Look for prisma/schema.prisma, drizzle.config.ts, package.json deps (pg, postgres, @neondatabase/serverless, mysql2, better-sqlite3, mongoose, mongodb). If drizzle.config.ts exists, read its dialect field to determine the DB type (e.g., "postgresql" → Drizzle + Postgres). Also check which Drizzle driver is installed (drizzle-orm/node-postgrespg, drizzle-orm/postgres-jspostgres, drizzle-orm/neon-http → Neon).
  • Existing auth — Look for existing auth libraries (next-auth, lucia, clerk, supabase/auth, firebase/auth) in package.json or imports.
  • Package manager — Check for pnpm-lock.yaml, yarn.lock, bun.lockb, or package-lock.json.

Use what you find to pre-fill defaults and skip questions you can already answer.

Step 2: Ask planning questions

Use the AskQuestion tool to ask the user all applicable questions in a single call. Skip any question you already have a confident answer for from the scan. Group them under a title like "Auth Setup Planning".

Questions to ask:

  1. Project type (skip if detected)

    • Prompt: "What type of project is this?"
    • Options: New project from scratch | Adding auth to existing project | Migrating from another auth library
  2. Framework (skip if detected)

    • Prompt: "Which framework are you using?"
    • Options: Next.js (App Router) | Next.js (Pages Router) | SvelteKit | Nuxt | Astro | Express | Hono | SolidStart | Other
  3. Database & ORM (skip if detected)

    • Prompt: "Which database setup will you use?"
    • Options: PostgreSQL (Prisma) | PostgreSQL (Drizzle) | PostgreSQL (pg driver) | MySQL (Prisma) | MySQL (Drizzle) | MySQL (mysql2 driver) | SQLite (Prisma) | SQLite (Drizzle) | SQLite (better-sqlite3 driver) | MongoDB (Mongoose) | MongoDB (native driver)
  4. Authentication methods (always ask, allow multiple)

    • Prompt: "Which sign-in methods do you need?"
    • Options: Email & password | Social OAuth (Google, GitHub, etc.) | Magic link (passwordless email) | Passkey (WebAuthn) | Phone number
    • allow_multiple: true
  5. Social providers (only if they selected Social OAuth above — ask in a follow-up call)

    • Prompt: "Which social providers do you need?"
    • Options: Google | GitHub | Apple | Microsoft | Discord | Twitter/X
    • allow_multiple: true
  6. Email verification (only if Email & password was selected above — ask in a follow-up call)

    • Prompt: "Do you want to require email verification?"
    • Options: Yes | No
  7. Email provider (only if email verification is Yes, or if Password reset is selected in features — ask in a follow-up call)

    • Prompt: "How do you want to send emails?"
    • Options: Resend | Mock it for now (console.log)
  8. Features & plugins (always ask, allow multiple)

    • Prompt: "Which additional features do you need?"
    • Options: Two-factor authentication (2FA) | Organizations / teams | Admin dashboard | API bearer tokens | Password reset | None of these
    • allow_multiple: true
  9. Auth pages (always ask, allow multiple — pre-select based on earlier answers)

    • Prompt: "Which auth pages do you need?"
    • Options vary based on previous answers:
      • Always available: Sign in | Sign up
      • If Email & password selected: Forgot password | Reset password
      • If email verification enabled: Email verification
    • allow_multiple: true
  10. Auth UI style (always ask)

  • Prompt: "What style do you want for the auth pages? Pick one or describe your own."
  • Options: Minimal & clean | Centered card with background | Split layout (form + hero image) | Floating / glassmorphism | Other (I'll describe)

Step 3: Summarize the plan

After collecting answers, present a concise implementation plan as a markdown checklist. Example:

## Auth Implementation Plan

- **Framework:** Next.js (App Router)
- **Database:** PostgreSQL via Prisma
- **Auth methods:** Email/password, Google OAuth, GitHub OAuth
- **Plugins:** 2FA, Organizations, Email verification
- **UI:** Custom forms

### Steps
1. Install `better-auth` and `@better-auth/cli`
2. Create `lib/auth.ts` with server config
3. Create `lib/auth-client.ts` with React client
4. Set up route handler at `app/api/auth/[...all]/route.ts`
5. Configure Prisma adapter and generate schema
6. Add Google & GitHub OAuth providers
7. Enable `twoFactor` and `organization` plugins
8. Set up email verification handler
9. Run migrations
10. Create sign-in / sign-up pages

Ask the user to confirm the plan before proceeding to Phase 2.


Phase 2: Implementation

Only proceed here after the user confirms the plan from Phase 1.

Follow the decision tree below, guided by the answers collected above.

Is this a new/empty project?
├─ YES → New project setup
│   1. Install better-auth (+ scoped packages per plan)
│   2. Create auth.ts with all planned config
│   3. Create auth-client.ts with framework client
│   4. Set up route handler
│   5. Set up environment variables
│   6. Run CLI migrate/generate
│   7. Add plugins from plan
│   8. Create auth UI pages
│
├─ MIGRATING → Migration from existing auth
│   1. Audit current auth for gaps
│   2. Plan incremental migration
│   3. Install better-auth alongside existing auth
│   4. Migrate routes, then session logic, then UI
│   5. Remove old auth library
│   6. See migration guides in docs
│
└─ ADDING → Add auth to existing project
    1. Analyze project structure
    2. Install better-auth
    3. Create auth config matching plan
    4. Add route handler
    5. Run schema migrations
    6. Integrate into existing pages
    7. Add planned plugins and features

At the end of implementation, guide users thoroughly on remaining next steps (e.g., setting up OAuth app credentials, deploying env vars, testing flows).


Installation

Core: npm install better-auth

Scoped packages (as needed):

PackageUse case
@better-auth/passkeyWebAuthn/Passkey auth
@better-auth/ssoSAML/OIDC enterprise SSO
@better-auth/stripeStripe payments
@better-auth/scimSCIM user provisioning
@better-auth/expoReact Native/Expo

Environment Variables

BETTER_AUTH_SECRET=<32+ chars, generate with: openssl rand -base64 32>
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=<your database connection string>

Add OAuth secrets as needed: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GOOGLE_CLIENT_ID, etc.


Server Config (auth.ts)

Location: lib/auth.ts or src/lib/auth.ts

Minimal config needs:

  • database - Connection or adapter
  • emailAndPassword: { enabled: true } - For email/password auth

Standard config adds:

  • socialProviders - OAuth providers (google, github, etc.)
  • emailVerification.sendVerificationEmail - Email verification handler
  • emailAndPassword.sendResetPassword - Password reset handler

Full config adds:

  • plugins - Array of feature plugins
  • session - Expiry, cookie cache settings
  • account.accountLinking - Multi-provider linking
  • rateLimit - Rate limiting config

Export types: export type Session = typeof auth.$Infer.Session


Client Config (auth-client.ts)

Import by framework:

FrameworkImport
React/Next.jsbetter-auth/react
Vuebetter-auth/vue
Sveltebetter-auth/svelte
Solidbetter-auth/solid
Vanilla JSbetter-auth/client

Client plugins go in createAuthClient({ plugins: [...] }).

Common exports: signIn, signUp, signOut, useSession, getSession


Route Handler Setup

FrameworkFileHandler
Next.js App Routerapp/api/auth/[...all]/route.tstoNextJsHandler(auth) → export { GET, POST }
Next.js Pagespages/api/auth/[...all].tstoNextJsHandler(auth) → default export
ExpressAny fileapp.all("/api/auth/*", toNodeHandler(auth))
SvelteKitsrc/hooks.server.tssvelteKitHandler(auth)
SolidStartRoute filesolidStartHandler(auth)
HonoRoute fileauth.handler(c.req.raw)

Next.js Server Components: Add nextCookies() plugin to auth config.


Database Migrations

AdapterCommand
Built-in Kyselynpx @better-auth/cli@latest migrate (applies directly)
Prismanpx @better-auth/cli@latest generate --output prisma/schema.prisma then npx prisma migrate dev
Drizzle (dev)npx @better-auth/cli@latest generate --output src/db/auth-schema.ts then npx drizzle-kit push
Drizzle (prod)npx @better-auth/cli@latest generate --output src/db/auth-schema.ts then npx drizzle-kit generate then npx drizzle-kit migrate

Note: drizzle-kit push skips migration files and is only safe for development. Use drizzle-kit generate + drizzle-kit migrate in production.

Re-run after adding plugins.


Database Adapters

DatabaseSetup
SQLitePass better-sqlite3 or bun:sqlite instance directly
PostgreSQLPass pg.Pool instance directly
MySQLPass mysql2 pool directly
PrismaprismaAdapter(prisma, { provider: "postgresql" }) from better-auth/adapters/prisma
Drizzle (pg)drizzleAdapter(db, { provider: "pg" }) from better-auth/adapters/drizzle
Drizzle (mysql)drizzleAdapter(db, { provider: "mysql" }) from better-auth/adapters/drizzle
Drizzle (sqlite)drizzleAdapter(db, { provider: "sqlite" }) from better-auth/adapters/drizzle
MongoDBmongodbAdapter(db) from better-auth/adapters/mongodb

Drizzle + PostgreSQL Setup

Before using drizzleAdapter, initialize the db instance:

// Option 1: node-postgres (pg)
import { drizzle } from "drizzle-orm/node-postgres"
import { Pool } from "pg"
import * as schema from "./auth-schema"

const pool = new Pool({ connectionString: process.env.DATABASE_URL })
export const db = drizzle(pool, { schema })
// Option 2: postgres.js
import { drizzle } from "drizzle-orm/postgres-js"
import postgres from "postgres"
import * as schema from "./auth-schema"

const client = postgres(process.env.DATABASE_URL!)
export const db = drizzle(client, { schema })
// Option 3: Neon serverless
import { drizzle } from "drizzle-orm/neon-http"
import { neon } from "@neondatabase/serverless"
import * as schema from "./auth-schema"

const sql = neon(process.env.DATABASE_URL!)
export const db = drizzle(sql, { schema })

Then pass to Better Auth:

import { betterAuth } from "better-auth"
import { drizzleAdapter } from "better-auth/adapters/drizzle"
import { db } from "./db"

export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: "pg" }),
  // ...
})

Drizzle Config (drizzle.config.ts)

Required for drizzle-kit commands to find your schema:

import { defineConfig } from "drizzle-kit"

export default defineConfig({
  schema: "./src/db/auth-schema.ts",
  out: "./drizzle",
  dialect: "postgresql",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
})

Common Plugins

PluginServer ImportClient ImportPurpose
twoFactorbetter-auth/pluginstwoFactorClient2FA with TOTP/OTP
organizationbetter-auth/pluginsorganizationClientTeams/orgs
adminbetter-auth/pluginsadminClientUser management
bearerbetter-auth/plugins-API token auth
openAPIbetter-auth/plugins-API docs
passkey@better-auth/passkeypasskeyClientWebAuthn
sso@better-auth/sso-Enterprise SSO

Plugin pattern: Server plugin + client plugin + run migrations.


Auth UI Implementation

Sign in flow:

  1. signIn.email({ email, password }) or signIn.social({ provider, callbackURL })
  2. Handle error in response
  3. Redirect on success

Session check (client): useSession() hook returns { data: session, isPending }

Session check (server): auth.api.getSession({ headers: await headers() })

Protected routes: Check session, redirect to /sign-in if null.


Security Checklist

  • BETTER_AUTH_SECRET set (32+ chars)
  • advanced.useSecureCookies: true in production
  • trustedOrigins configured
  • Rate limits enabled
  • Email verification enabled
  • Password reset implemented
  • 2FA for sensitive apps
  • CSRF protection NOT disabled
  • account.accountLinking reviewed

Troubleshooting

IssueFix
"Secret not set"Add BETTER_AUTH_SECRET env var
"Invalid Origin"Add domain to trustedOrigins
Cookies not settingCheck baseURL matches domain; enable secure cookies in prod
OAuth callback errorsVerify redirect URIs in provider dashboard
Type errors after adding pluginRe-run CLI generate/migrate

Resources

Más skills de better-auth

better-auth-best-practices
better-auth
Configuración completa del servidor y cliente de Better Auth con adaptadores de base de datos, gestión de sesiones, plugins y configuración de seguridad. Cubre el flujo de trabajo completo desde la instalación hasta la migración de la base de datos, configuración de variables de entorno y creación de manejadores de rutas en múltiples frameworks. Soporta múltiples adaptadores de base de datos (Prisma, Drizzle, MongoDB, conexiones directas) con orientación crítica sobre convenciones de nombres de modelos vs. tablas. Incluye estrategias de almacenamiento de sesiones con almacenamiento secundario (Redis/KV), cookies...
official
better-auth-security-best-practices
better-auth
Configurar limitación de tasa, gestionar secretos de autenticación, configurar protección CSRF, definir orígenes de confianza, asegurar sesiones y cookies, cifrar tokens OAuth, rastrear IP…
official
create-auth
better-auth
Crea e implementa autenticación en aplicaciones TypeScript/JavaScript usando Better Auth. Detecta frameworks, configura adaptadores de base de datos, establece manejadores de rutas,…
official
Email & Password Best Practices
better-auth
email-&-password-best-practices — una habilidad instalable para agentes de IA, publicada por better-auth/skills.
official
email-and-password-best-practices
better-auth
Verificación de correo electrónico, flujos de restablecimiento de contraseña y políticas de contraseña personalizables para Better Auth. Soporta verificación de correo electrónico con aplicación opcional para bloquear el inicio de sesión hasta que se verifique, además de caducidad de token configurable y tokens de restablecimiento de un solo uso. Flujos de restablecimiento de contraseña con seguridad integrada: envío de correo electrónico en segundo plano, prevención de ataques de sincronización, operaciones ficticias en solicitudes no válidas y revocación opcional de sesión al restablecer. Límites de longitud de contraseña configurables (predeterminado de 8 a 256 caracteres) y personalizados...
official
organization-best-practices
better-auth
Configuración de organización multiinquilino con gestión de miembros, control de acceso basado en roles y soporte de equipos a través de Better Auth. Configure organizaciones con reglas de creación personalizables, límites de membresía y restricciones de propiedad; los creadores reciben automáticamente el rol de propietario. Gestione miembros e invitaciones con entrega por correo electrónico, ventanas de expiración y URL de invitación compartibles; soporte para múltiples roles por miembro. Defina roles y permisos personalizados con control de acceso dinámico; verifique permisos...
official
two-factor-authentication-best-practices
better-auth
Autenticación multifactor con TOTP, OTP, códigos de respaldo y gestión de dispositivos confiables para Better Auth. Soporta tres métodos de verificación: aplicaciones de autenticación (TOTP con códigos QR), códigos por correo electrónico/SMS (OTP) y códigos de respaldo de un solo uso. Maneja flujos completos de inicio de sesión con 2FA, incluyendo gestión automática de sesiones, cookies temporales de 2FA y seguimiento de dispositivos confiables con caducidad configurable. Funciones de seguridad integradas que incluyen limitación de velocidad (3 solicitudes por cada 10 segundos) y cifrado en reposo para secretos...
official
create-auth-skill
better-auth
Andamia e implementa autenticación en aplicaciones TypeScript/JavaScript con detección del framework Better Auth, configuración del adaptador de base de datos e integración OAuth. Detecta frameworks (Next.js, SvelteKit, Nuxt, Astro, Express, Hono), bases de datos (Prisma, Drizzle, MongoDB, drivers nativos) y bibliotecas de autenticación existentes mediante escaneo del proyecto. Soporta correo electrónico/contraseña, OAuth (Google, GitHub, Apple, Microsoft, Discord, Twitter), enlaces mágicos, passkeys y autenticación telefónica con verificación de correo configurable...
official