
Better Auth Best Practices
- 1 installs
- 404 repo stars
- Updated August 5, 2026
- aiskillstore/marketplace
This is a copy of better-auth-best-practices by pedronauck - installs and ranking accrue to the original listing.
better-auth-best-practices is a Claude Code skill that configures the Better Auth TypeScript authentication library, including adapters, sessions and plugins.
About
better-auth-best-practices guides configuring the Better Auth TypeScript authentication library. It covers server and client setup, database adapters, session management, plugins, email flows, security options and environment variables, plus common gotchas. A developer uses it when adding email/password or OAuth authentication to a TypeScript app.
- Configures the Better Auth TypeScript authentication library
- Covers server/client setup, database adapters, sessions and plugins
- Documents env vars, security options and common gotchas
Better Auth Best Practices by the numbers
- 1 all-time installs (skills.sh)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
better-auth-best-practices capabilities & compatibility
- Capabilities
- authentication setup · oauth config · session management · auth plugins
- Works with
- postgres · mysql · mongodb · redis
- Use cases
- api development · security audit
What better-auth-best-practices says it does
Configure Better Auth server and client, set up database adapters, manage sessions, add plugins, and handle environment variables.
`BETTER_AUTH_SECRET` - Encryption secret (min 32 chars). Generate: `openssl rand -base64 32`
npx skills add https://github.com/aiskillstore/marketplace --skill better-auth-best-practicesAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 404 |
| Last updated | August 5, 2026 |
| Repository | aiskillstore/marketplace ↗ |
What it does
Set up and configure Better Auth in a TypeScript app, including database adapters, sessions, OAuth and plugins.
Who is it for?
Configuring Better Auth server and client, database adapters, sessions and plugins in TypeScript.
Skip if: Non-Better-Auth authentication libraries or non-TypeScript stacks.
When should I use this skill?
A developer mentions Better Auth, auth.ts, or needs TypeScript email/password or OAuth authentication.
What you get
A correctly configured Better Auth setup with the right adapter, session strategy and plugins.
- configured auth.ts
- database adapter and session configuration
By the numbers
- 6-step setup workflow
- min 32-character BETTER_AUTH_SECRET
- 3 cookie cache strategies (compact, jwt, jwe)
Files
Better Auth Integration Guide
Always consult [better-auth.com/docs](https://better-auth.com/docs) for code examples and latest API.
---
Setup Workflow
1. Install: npm install better-auth 2. Set env vars: BETTER_AUTH_SECRET and BETTER_AUTH_URL 3. Create auth.ts with database + config 4. Create route handler for your framework 5. Run npx @better-auth/cli@latest migrate 6. Verify: call GET /api/auth/ok — should return { status: "ok" }
---
Quick Reference
Environment Variables
BETTER_AUTH_SECRET- Encryption secret (min 32 chars). Generate:openssl rand -base64 32BETTER_AUTH_URL- Base URL (e.g.,https://example.com)
Only define baseURL/secret in config if env vars are NOT set.
File Location
CLI looks for auth.ts in: ./, ./lib, ./utils, or under ./src. Use --config for custom path.
CLI Commands
npx @better-auth/cli@latest migrate- Apply schema (built-in adapter)npx @better-auth/cli@latest generate- Generate schema for Prisma/Drizzlenpx @better-auth/cli mcp --cursor- Add MCP to AI tools
Re-run after adding/changing plugins.
---
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 for most features. See adapters docs. |
secondaryStorage | Redis/KV for sessions & rate limits |
emailAndPassword | { enabled: true } to activate |
socialProviders | { google: { clientId, clientSecret }, ... } |
plugins | Array of plugins |
trustedOrigins | CSRF whitelist |
---
Database
Direct connections: Pass pg.Pool, mysql2 pool, better-sqlite3, or bun:sqlite instance.
ORM adapters: Import from better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.
Critical: Better Auth uses adapter model names, NOT underlying table names. If Prisma model is User mapping to table users, use modelName: "user" (Prisma reference), not "users".
---
Session Management
Storage priority: 1. If secondaryStorage defined → sessions go there (not DB) 2. Set session.storeSessionInDatabase: true to also persist to DB 3. No database + cookieCache → fully stateless mode
Cookie cache strategies:
compact(default) - Base64url + HMAC. Smallest.jwt- Standard JWT. Readable but signed.jwe- Encrypted. Maximum security.
Key options: session.expiresIn (default 7 days), session.updateAge (refresh interval), session.cookieCache.maxAge, session.cookieCache.version (change to invalidate all sessions).
---
User & Account Config
User: user.modelName, user.fields (column mapping), user.additionalFields, user.changeEmail.enabled (disabled by default), user.deleteUser.enabled (disabled by default).
Account: account.modelName, account.accountLinking.enabled, account.storeAccountCookie (for stateless OAuth).
Required for registration: email and name fields.
---
Email Flows
emailVerification.sendVerificationEmail- Must be defined for verification to workemailVerification.sendOnSignUp/sendOnSignIn- Auto-send triggersemailAndPassword.sendResetPassword- Password reset email handler
---
Security
In `advanced`:
useSecureCookies- Force HTTPS cookiesdisableCSRFCheck- ⚠️ Security riskdisableOriginCheck- ⚠️ Security riskcrossSubDomainCookies.enabled- Share cookies across subdomainsipAddress.ipAddressHeaders- Custom IP headers for proxiesdatabase.generateId- Custom ID generation or"serial"/"uuid"/false
Rate limiting: rateLimit.enabled, rateLimit.window, rateLimit.max, rateLimit.storage ("memory" | "database" | "secondary-storage").
---
Hooks
Endpoint hooks: hooks.before / hooks.after - Array of { matcher, handler }. Use createAuthMiddleware. Access ctx.path, ctx.context.returned (after), ctx.context.session.
Database hooks: databaseHooks.user.create.before/after, same for session, account. Useful for adding default values or post-creation actions.
Hook context (`ctx.context`): session, secret, authCookies, password.hash()/verify(), adapter, internalAdapter, generateId(), tables, baseURL.
---
Plugins
Import from dedicated paths for tree-shaking:
import { twoFactor } from "better-auth/plugins/two-factor"NOT from "better-auth/plugins".
Popular plugins: twoFactor, organization, passkey, magicLink, emailOtp, username, phoneNumber, admin, apiKey, bearer, jwt, multiSession, sso, oauthProvider, oidcProvider, openAPI, genericOAuth.
Client plugins go in createAuthClient({ plugins: [...] }).
---
Client
Import from: better-auth/client (vanilla), better-auth/react, better-auth/vue, better-auth/svelte, better-auth/solid.
Key methods: signUp.email(), signIn.email(), signIn.social(), signOut(), useSession(), getSession(), revokeSession(), revokeSessions().
---
Type Safety
Infer types: typeof auth.$Infer.Session, typeof auth.$Infer.Session.user.
For separate client/server projects: createAuthClient<typeof auth>().
---
Common Gotchas
1. Model vs table name - Config uses ORM model name, not DB table name 2. Plugin schema - Re-run CLI after adding plugins 3. Secondary storage - Sessions go there by default, not DB 4. Cookie cache - Custom session fields NOT cached, always re-fetched 5. Stateless mode - No DB = session in cookie only, logout on cache expiry 6. Change email flow - Sends to current email first, then new email
---
Resources
{
"schema_version": "2.0",
"meta": {
"generated_at": "2026-03-19T08:21:26.063Z",
"slug": "better-auth-better-auth-best-practices",
"source_url": "https://github.com/better-auth/skills/tree/main/better-auth/best-practices/",
"source_ref": "main",
"model": "claude",
"analysis_version": "3.0.0",
"source_type": "community",
"content_hash": "c62acc0464f80bf8be72e0b55046a06c7762fa1ffaac1e78f61159b50072c9cf",
"tree_hash": "0d59bc23f61ba03b850aa3b81392044c5c7fa3662a5f61b98490b20b0f14a56a"
},
"skill": {
"name": "better-auth-best-practices",
"description": "Configure Better Auth server and client, set up database adapters, manage sessions, add plugins, and handle environment variables. Use when users mention Better Auth, betterauth, auth.ts, or need to set up TypeScript authentication with email/password, OAuth, or plugin configuration.",
"summary": "Complete guide for Better Auth setup, configuration, sessions, plugins, and security best practices.",
"icon": "📦",
"version": "1.0.0",
"author": "better-auth",
"license": "MIT",
"category": "security",
"tags": [
"authentication",
"better-auth",
"typescript",
"security",
"oauth"
],
"supported_tools": [
"claude",
"codex",
"claude-code"
],
"risk_factors": []
},
"security_audit": {
"risk_level": "safe",
"is_blocked": false,
"safe_to_publish": true,
"summary": "This skill contains documentation-only content (SKILL.md) with no executable code. Static analyzer flagged 144 external command patterns and 7 network URLs, but all are false positives: command examples are CLI instructions for users to run manually, and URLs are documentation links. No security risks detected.",
"risk_factor_evidence": [
{
"factor": "external_commands",
"evidence": [],
"verdict": "FALSE_POSITIVE",
"reasoning": "All detected patterns are documentation examples showing CLI commands (npm install, npx migrate) for users to execute manually, not actual code execution within the skill."
},
{
"factor": "network",
"evidence": [],
"verdict": "FALSE_POSITIVE",
"reasoning": "All detected URLs are documentation reference links (better-auth.com/docs, GitHub URLs), not actual network requests made by the skill."
}
],
"critical_findings": [],
"high_findings": [],
"medium_findings": [],
"low_findings": [],
"dangerous_patterns": [],
"files_scanned": 1,
"total_lines": 175,
"audit_model": "claude",
"audited_at": "2026-03-19T08:21:26.063Z"
},
"content": {
"user_title": "Configure Better Auth authentication securely",
"value_statement": "Setting up authentication can be complex with many security considerations. This skill provides proven patterns for Better Auth configuration, session management, and plugin integration.",
"seo_keywords": [
"Better Auth",
"Claude",
"Codex",
"Claude Code",
"authentication",
"TypeScript auth",
"OAuth setup",
"session management",
"auth best practices",
"secure authentication"
],
"actual_capabilities": [
"Guide Better Auth server and client setup with correct configuration options",
"Configure database adapters for Prisma, Drizzle, MongoDB, and direct connections",
"Set up session management with cookie cache strategies and secondary storage",
"Integrate plugins like twoFactor, organization, passkey, and OAuth providers",
"Configure security settings including rate limiting, CSRF protection, and HTTPS cookies",
"Set up email flows for verification, password reset, and OTP functionality"
],
"limitations": [
"Provides documentation guidance only - does not execute code or make network requests",
"Requires users to manually run CLI commands for migration and schema generation",
"Does not replace official Better Auth documentation for latest API changes",
"Framework-specific route handler setup requires additional framework knowledge"
],
"use_cases": [
{
"title": "New Project Authentication Setup",
"description": "Set up Better Auth from scratch with proper database adapters, environment variables, and basic configuration for a new TypeScript project.",
"target_user": "Full-stack developer starting a new project"
},
{
"title": "Enterprise Security Configuration",
"description": "Configure advanced security features including two-factor authentication, rate limiting, organization management, and secure session storage for production applications.",
"target_user": "Security-focused backend engineer"
},
{
"title": "OAuth and Social Login Integration",
"description": "Set up social providers (Google, GitHub, etc.) with proper callback configuration and account linking for seamless user authentication.",
"target_user": "Developer adding social login to existing app"
}
],
"prompt_templates": [
{
"title": "Basic Setup",
"prompt": "Help me set up Better Auth for a new TypeScript project with email/password authentication and a PostgreSQL database.",
"scenario": "Starting a new project and need basic auth configuration"
},
{
"title": "OAuth Configuration",
"prompt": "Configure Better Auth with Google and GitHub OAuth providers, including the required environment variables and callback setup.",
"scenario": "Adding social login options to existing authentication"
},
{
"title": "Session Management",
"prompt": "Explain how to configure session storage with Redis as secondary storage, including cookie cache options and session expiration settings.",
"scenario": "Scaling authentication with external session storage"
},
{
"title": "Advanced Security",
"prompt": "Set up Better Auth with two-factor authentication, rate limiting, and organization-based access control for a production SaaS application.",
"scenario": "Implementing enterprise-grade security features"
}
],
"output_examples": [
{
"input": "Set up Better Auth with Prisma adapter",
"output": [
"Install: npm install better-auth @prisma/client",
"Generate Prisma schema: npx @better-auth/cli@latest generate",
"Run migration: npx @better-auth/cli@latest migrate",
"Configure auth.ts with Prisma adapter import from better-auth/adapters/prisma",
"Use modelName (not table name) for user, session, account models"
]
},
{
"input": "Enable two-factor authentication",
"output": [
"Import: import { twoFactor } from 'better-auth/plugins/two-factor'",
"Add to plugins array in auth configuration",
"Run CLI migrate command after adding plugin",
"Client receives totp and backup code methods for 2FA flow"
]
}
],
"best_practices": [
"Always use BETTER_AUTH_SECRET and BETTER_AUTH_URL environment variables instead of hardcoding in config",
"Run the Better Auth CLI migrate command after adding or changing plugins to update database schema",
"Use secondary storage (Redis/KV) for sessions in production to enable proper session invalidation and scaling"
],
"anti_patterns": [
"Using database table names instead of ORM model names in configuration (causes adapter errors)",
"Disabling CSRF checks or origin checks in production environments",
"Storing sessions only in cookie cache without database or secondary storage backup (loses logout capability)"
],
"faq": [
{
"question": "How do I generate a secure BETTER_AUTH_SECRET?",
"answer": "Use the command: openssl rand -base64 32. This generates a random 32-character base64 string suitable for encryption."
},
{
"question": "Why are my sessions not being saved to the database?",
"answer": "If secondaryStorage is configured, sessions go there by default. Set session.storeSessionInDatabase: true to also persist to the database."
},
{
"question": "What is the difference between model name and table name?",
"answer": "Better Auth uses your ORM's model name (e.g., 'User' in Prisma), not the actual database table name (e.g., 'users'). Configure using modelName in the adapter."
},
{
"question": "How do I invalidate all user sessions?",
"answer": "Change the session.cookieCache.version value. This invalidates all existing cookie caches, forcing re-authentication."
},
{
"question": "Can I use Better Auth without a database?",
"answer": "Yes, using cookieCache in stateless mode. However, you lose logout functionality and session management since sessions exist only in the cookie."
},
{
"question": "Do I need to re-run migrations after adding plugins?",
"answer": "Yes. Always run 'npx @better-auth/cli@latest migrate' after adding or changing plugins, as they often add new database tables."
}
]
},
"file_structure": [
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"lines": 175
}
]
}
Related skills
FAQ
What environment variables are required?
BETTER_AUTH_SECRET (min 32 chars) and BETTER_AUTH_URL for the base URL.
How are plugins imported?
From dedicated paths for tree-shaking, e.g. better-auth/plugins/two-factor, not the barrel better-auth/plugins.