Installation
npx skills add oakoss/agent-skills --skill better-auth 39
Installs
better-auth
Package: better-auth@1.4.15 (ESM-only since v1.4.0)
Docs: https://better-auth.com/docs | GitHub: https://github.com/better-auth/better-auth
Environment Setup
| Variable | Purpose |
|---|---|
BETTER_AUTH_SECRET |
Encryption secret (min 32 chars). Generate: openssl rand -base64 32 |
BETTER_AUTH_URL |
Base URL (e.g., https://example.com) |
Only define baseURL/secret in config if env vars are NOT set. CLI looks for auth.ts in: ./, ./lib, ./utils, or ./src.
Core Config Options
| Option | Notes |
|---|---|
appName |
Optional display name |
baseURL |
Only if BETTER_AUTH_URL not set |
basePath |
Default /api/auth. Set / for root. |
secret |
Only if BETTER_AUTH_SECRET not set |
database |
Required unless using stateless mode (v1.4+) |
secondaryStorage |
Redis/KV for sessions and rate limits |
emailAndPassword |
{ enabled: true } to activate |
socialProviders |
{ google: { clientId, clientSecret }, ... } |
plugins |
Array of plugins |
trustedOrigins |
CSRF whitelist |
Plugin Reference
| 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 @better-auth/oauth-provider package) |
| sso | Enterprise SSO with OIDC, OAuth2, SAML 2.0 (separate @better-auth/sso package) |
| scim | Enterprise user provisioning (separate @better-auth/scim package) |
| 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 /api/auth/reference |
Session Strategies
| Strategy | Format | Use Case |
|---|---|---|
| Compact (default) | Base64url + HMAC-SHA256 | Smallest, fastest |
| JWT | Standard JWT | Interoperable |
| JWE | A256CBC-HS512 encrypted | Most secure |
Getting Started
For new projects or first-time Better Auth setup, use the official interactive setup skill:
npx skills add better-auth/skills -s create-auth-skillThis walks through framework detection, database selection, auth method choices, plugin setup, and generates the initial configuration.
Anti-Patterns
| Anti-Pattern | Correct Approach |
|---|---|
Using d1Adapter |
Use Drizzle or Kysely adapter with provider: "sqlite" |
| Using table name in config | Use ORM model name, not DB table name |
| Forgetting CLI after plugin changes | Re-run npx @better-auth/cli@latest generate |
tanstackStartCookies() not last plugin |
Must be the last plugin in array (TanStack Start) |
Checking session for login state |
Check session?.user — session object is always truthy |
Missing nodejs_compat flag |
Required in wrangler.toml for Cloudflare Workers |
| Kysely CamelCasePlugin with auth | Use separate Kysely instance without the plugin |
Using old reactStartCookies import |
Renamed to tanstackStartCookies from better-auth/tanstack-start in v1.4.14 |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
Setting baseURL and secret in config when env vars are already set |
Only define these in config if BETTER_AUTH_URL and BETTER_AUTH_SECRET env vars are NOT set |
| Using CommonJS require syntax with better-auth v1.4+ | better-auth is ESM-only since v1.4.0; use import syntax exclusively |
| Not re-running CLI generate after adding or changing plugins | Always run npx @better-auth/cli@latest generate after plugin changes to update DB schema |
Checking session object truthy state for login detection |
Check session?.user instead; the session object itself is always truthy |
Using d1Adapter directly for Cloudflare D1 |
Use Drizzle or Kysely adapter with provider: "sqlite" for D1 compatibility |
Breaking Changes
| Version | Change |
|---|---|
| v1.4.14 | reactStartCookies renamed to tanstackStartCookies (import from better-auth/tanstack-start) |
| v1.4.6 | allowImpersonatingAdmins defaults to false |
| v1.4.0 | ESM-only (no CommonJS); SSO, SCIM, OAuth Provider moved to separate packages |
| v1.3.0 | Multi-team table structure: new teamMembers table needed |
Delegation
When working on auth, delegate to:
application-security— Security architecture and threat modelingdatabase— Drizzle ORM schema and migrationstanstack-start— TanStack Start integration patterns
Resources
- Docs: https://better-auth.com/docs
- Options Reference: https://better-auth.com/docs/reference/options
- LLMs.txt: https://better-auth.com/llms.txt
- Changelog: https://www.better-auth.com/changelogs
- TanStack Start: https://www.better-auth.com/docs/integrations/tanstack
- Expo: https://www.better-auth.com/docs/integrations/expo
References
- Database Adapters — Drizzle, Kysely, Prisma adapters, Cloudflare Workers factory pattern
- Session Management — Cookie cache, stateless sessions, storage priority, freshAge constraints
- Plugins and Social Auth — Plugin setup, OAuth 2.1 provider, admin RBAC, social provider scopes
- Email and Password — Verification, password reset, timing attack prevention, hashing (scrypt, argon2), token security
- Two-Factor Authentication — TOTP, email/SMS OTP, backup codes, trusted devices, 2FA session flow
- Organizations — Multi-tenant orgs, teams, invitations, RBAC, dynamic access control, lifecycle hooks
- Configuration — User/account config, rate limiting, hooks, CSRF, trusted origins, cookie/OAuth security, production checklist
- Framework Integration — TanStack Start setup, Expo/React Native, client imports, type safety
- Migration Guides — Migrate from NextAuth/Auth.js, Clerk, or Supabase Auth with schema mappings and session strategies
- Troubleshooting — D1 consistency, CORS, OAuth redirect, admin 403, nanostore refresh, known bugs
Installs
Security Audit
View Source
oakoss/agent-skills
More from this source
Power your AI Agents with
the best open-source models.
Drop-in OpenAI-compatible API. No data leaves Europe.
Explore Inference APIGLM
GLM 5
$1.00 / $3.20
per M tokens
Kimi
Kimi K2.5
$0.60 / $2.80
per M tokens
MiniMax
MiniMax M2.5
$0.30 / $1.20
per M tokens
Qwen
Qwen3.5 122B
$0.40 / $3.00
per M tokens
How to use this skill
Install better-auth by running npx skills add oakoss/agent-skills --skill better-auth in your project directory. Run the install command above in your project directory. The skill file will be downloaded from GitHub and placed in your project.
No configuration needed. Your AI agent (Claude Code, Cursor, Windsurf, etc.) automatically detects installed skills and uses them as context when generating code.
The skill enhances your agent's understanding of better-auth, helping it follow established patterns, avoid common mistakes, and produce production-ready output.
What you get
Skills are plain-text instruction files — not executable code. They encode expert knowledge about frameworks, languages, or tools that your AI agent reads to improve its output. This means zero runtime overhead, no dependency conflicts, and full transparency: you can read and review every instruction before installing.
Compatibility
This skill works with any AI coding agent that supports the skills.sh format, including Claude Code (Anthropic), Cursor, Windsurf, Cline, Aider, and other tools that read project-level context files. Skills are framework-agnostic at the transport level — the content inside determines which language or framework it applies to.
Chat with 100+ AI Models in one App.
Use Claude, ChatGPT, Gemini alongside with EU-Hosted Models like Deepseek, GLM-5, Kimi K2.5 and many more.