Loading...
Loading...
Self-hosted TypeScript auth framework with social auth, 2FA, passkeys, organizations, RBAC, and 15+ plugins. Supports Drizzle/Prisma/Kysely adapters. Self-hosted alternative to Clerk/Auth.js. Use when: configuring auth, adding plugins, social OAuth, multi-tenant SaaS, organizations with teams and RBAC, two-factor authentication (TOTP/OTP/backup codes), email verification, password reset flows, session management, rate limiting, CSRF and cookie security, Expo/mobile, D1 adapter errors, TanStack Start integration, additionalFields bugs, admin plugin, migrating from NextAuth, migrating from Clerk, migrating from Supabase Auth, or troubleshooting auth issues.
npx skill4agent add oakoss/agent-skills better-auth| Variable | Purpose |
|---|---|
| Encryption secret (min 32 chars). Generate: |
| Base URL (e.g., |
baseURLsecretauth.ts././lib./utils./src| Option | Notes |
|---|---|
| Optional display name |
| Only if |
| Default |
| Only if |
| Required unless using stateless mode (v1.4+) |
| Redis/KV for sessions and rate limits |
| |
| |
| Array of plugins |
| CSRF whitelist |
| Plugin | Description |
|---|---|
| twoFactor | TOTP, email OTP, backup codes |
| organization | Multi-tenant orgs, teams, invitations, RBAC |
| admin | User management, impersonation, banning |
| passkey | WebAuthn passwordless login |
| magicLink | Email-based passwordless login |
| jwt | JWT tokens with key rotation, JWKS |
| oauthProvider | Build your own OAuth 2.1 provider (separate |
| sso | Enterprise SSO with OIDC, OAuth2, SAML 2.0 (separate |
| scim | Enterprise user provisioning (separate |
| stripe | Payment and subscription management |
| bearer | API token auth for mobile/CLI |
| apiKey | Token-based auth with rate limits |
| oneTap | Google One Tap frictionless sign-in |
| anonymous | Guest user access without PII |
| genericOAuth | Custom OAuth providers with PKCE |
| emailOTP | Email-based one-time password auth |
| phoneNumber | Phone/SMS-based OTP sign-in |
| username | Username-based sign-in (alternative to email) |
| multiSession | Multiple accounts in same browser |
| openAPI | Interactive API docs at |
| Strategy | Format | Use Case |
|---|---|---|
| Compact (default) | Base64url + HMAC-SHA256 | Smallest, fastest |
| JWT | Standard JWT | Interoperable |
| JWE | A256CBC-HS512 encrypted | Most secure |
npx skills add better-auth/skills -s create-auth-skill| Anti-Pattern | Correct Approach |
|---|---|
Using | Use Drizzle or Kysely adapter with |
| Using table name in config | Use ORM model name, not DB table name |
| Forgetting CLI after plugin changes | Re-run |
| Must be the last plugin in array (TanStack Start) |
Checking | Check |
Missing | Required in |
| Kysely CamelCasePlugin with auth | Use separate Kysely instance without the plugin |
Using old | Renamed to |
| Mistake | Correct Pattern |
|---|---|
Setting | Only define these in config if |
| Using CommonJS require syntax with better-auth v1.4+ | better-auth is ESM-only since v1.4.0; use |
| Not re-running CLI generate after adding or changing plugins | Always run |
Checking | Check |
Using | Use Drizzle or Kysely adapter with |
| Version | Change |
|---|---|
| v1.4.14 | |
| v1.4.6 | |
| v1.4.0 | ESM-only (no CommonJS); SSO, SCIM, OAuth Provider moved to separate packages |
| v1.3.0 | Multi-team table structure: new |
application-securitydatabasetanstack-start