better-auth
npx machina-cli add skill zircote/agents/better-auth --openclawBetter Auth Skill
Better Auth is comprehensive, framework-agnostic authentication/authorization framework for TypeScript with built-in email/password, social OAuth, and powerful plugin ecosystem for advanced features.
<triggers> <trigger>Implementing auth in TypeScript/JavaScript applications</trigger> <trigger>Adding email/password or social OAuth authentication</trigger> <trigger>Setting up 2FA, passkeys, magic links, advanced auth features</trigger> <trigger>Building multi-tenant apps with organization support</trigger> <trigger>Managing sessions and user lifecycle</trigger> <trigger>Working with any framework (Next.js, Nuxt, SvelteKit, Remix, Astro, Hono, Express, etc.)</trigger> </triggers>Quick Start
Installation
<example type="usage"> <code language="bash"> npm install better-auth # or pnpm/yarn/bun add better-auth </code> </example>Environment Setup
Create .env:
BETTER_AUTH_SECRET=<generated-secret-32-chars-min>
BETTER_AUTH_URL=http://localhost:3000
Basic Server Setup
Create auth.ts (root, lib/, utils/, or under src/app/server/):
export const auth = betterAuth({ database: { // See references/database-integration.md }, emailAndPassword: { enabled: true, autoSignIn: true }, socialProviders: { github: { clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, } } }); </code> </example>
Database Schema
<example type="usage"> <code language="bash"> npx @better-auth/cli generate # Generate schema/migrations npx @better-auth/cli migrate # Apply migrations (Kysely only) </code> </example>Mount API Handler
Next.js App Router:
<example type="usage"> <code language="typescript"> // app/api/auth/[...all]/route.ts import { auth } from "@/lib/auth"; import { toNextJsHandler } from "better-auth/next-js";export const { POST, GET } = toNextJsHandler(auth); </code> </example>
Other frameworks: See references/email-password-auth.md#framework-setup
Client Setup
Create auth-client.ts:
export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL || "http://localhost:3000" }); </code> </example>
Basic Usage
<example type="usage"> <code language="typescript"> // Sign up await authClient.signUp.email({ email: "user@example.com", password: "secure123", name: "John Doe" });// Sign in await authClient.signIn.email({ email: "user@example.com", password: "secure123" });
// OAuth await authClient.signIn.social({ provider: "github" });
// Session const { data: session } = authClient.useSession(); // React/Vue/Svelte const { data: session } = await authClient.getSession(); // Vanilla JS </code> </example>
Feature Selection Matrix
| Feature | Plugin Required | Use Case | Reference |
|---|---|---|---|
| Email/Password | No (built-in) | Basic auth | email-password-auth.md |
| OAuth (GitHub, Google, etc.) | No (built-in) | Social login | oauth-providers.md |
| Email Verification | No (built-in) | Verify email addresses | email-password-auth.md |
| Password Reset | No (built-in) | Forgot password flow | email-password-auth.md |
| Two-Factor Auth (2FA/TOTP) | Yes (twoFactor) | Enhanced security | advanced-features.md |
| Passkeys/WebAuthn | Yes (passkey) | Passwordless auth | advanced-features.md |
| Magic Link | Yes (magicLink) | Email-based login | advanced-features.md |
| Username Auth | Yes (username) | Username login | email-password-auth.md |
| Organizations/Multi-tenant | Yes (organization) | Team/org features | advanced-features.md |
| Rate Limiting | No (built-in) | Prevent abuse | advanced-features.md |
| Session Management | No (built-in) | User sessions | advanced-features.md |
Auth Method Selection Guide
Choose Email/Password when:
- Building standard web app with traditional auth
- Need full control over user credentials
- Targeting users who prefer email-based accounts
Choose OAuth when:
- Want quick signup with minimal friction
- Users already have social accounts
- Need access to social profile data
Choose Passkeys when:
- Want passwordless experience
- Targeting modern browsers/devices
- Security is top priority
Choose Magic Link when:
- Want passwordless without WebAuthn complexity
- Targeting email-first users
- Need temporary access links
Combine Multiple Methods when:
- Want flexibility for different user preferences
- Building enterprise apps with various auth requirements
- Need progressive enhancement (start simple, add more options)
Core Architecture
Better Auth uses client-server architecture:
- Server (
better-auth): Handles auth logic, database ops, API routes - Client (
better-auth/client): Provides hooks/methods for frontend - Plugins: Extend both server/client functionality
Implementation Checklist
- Install
better-authpackage - Set environment variables (SECRET, URL)
- Create auth server instance with database config
- Run schema migration (
npx @better-auth/cli generate) - Mount API handler in framework
- Create client instance
- Implement sign-up/sign-in UI
- Add session management to components
- Set up protected routes/middleware
- Add plugins as needed (regenerate schema after)
- Test complete auth flow
- Configure email sending (verification/reset)
- Enable rate limiting for production
- Set up error handling
Reference Documentation
Core Authentication
- Email/Password Authentication - Email/password setup, verification, password reset, username auth
- OAuth Providers - Social login setup, provider configuration, token management
- Database Integration - Database adapters, schema setup, migrations
Advanced Features
- Advanced Features - 2FA/MFA, passkeys, magic links, organizations, rate limiting, session management
Scripts
scripts/better_auth_init.py- Initialize Better Auth configuration with interactive setup
Resources
Source
git clone https://github.com/zircote/agents/blob/main/skills/better-auth/SKILL.mdView on GitHub Overview
Better Auth is a framework-agnostic TypeScript authentication and authorization framework. It includes built-in email/password with verification, OAuth providers, 2FA, passkeys/WebAuthn, session management, and RBAC, plus database adapters to fit any stack. Use it to add robust, scalable authentication to web apps.
How This Skill Works
Initialize Better Auth with a config object that wires your database adapter and enables features like email/password, social providers, and 2FA. It exposes framework-agnostic handlers you mount into your app (e.g., route handlers for sign-in/out, OAuth redirects, and session state). It also handles RBAC, rate limiting, and migrations via its CLI and adapters.
When to Use It
- When adding authentication to a TypeScript/JavaScript application
- When implementing OAuth login flows with providers (Google, GitHub, Discord, etc.)
- When setting up 2FA/MFA (TOTP, SMS) and passkeys/WebAuthn
- When managing user sessions and lifecycle across frameworks
- When configuring authorization rules with RBAC or multi-tenant organization support
Quick Start
- Step 1: npm install better-auth
- Step 2: Create .env with BETTER_AUTH_SECRET and BETTER_AUTH_URL and add a basic server setup using betterAuth({ ... })
- Step 3: Generate the database schema and run migrations, then mount the API handler in your framework
Best Practices
- Plan and map your RBAC roles and permissions before implementing
- Use email verification for new accounts and consider autoSignIn when appropriate
- Securely manage secrets (env vars) and rotate keys regularly
- Enable rate limiting on authentication endpoints to deter abuse
- Use the CLI to generate and migrate your database schema consistently
Example Use Cases
- Sign-up and sign-in with email/password including verification in a Next.js app
- GitHub or Google OAuth sign-in for a SaaS dashboard
- Enforce TOTP-based 2FA for sensitive actions
- Passwordless login using passkeys/WebAuthn
- RBAC-enabled admin area in a multi-tenant org-based app