
Better Auth Best Practices
- 13 installs
- Updated February 20, 2026
- jackiexiao/jackie-skills-cn-top50
This is a copy of better-auth-best-practices by pedronauck - installs and ranking accrue to the original listing.
Helps with ai & agent building tasks.
About
better-auth-best-practices is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- better-auth-best-practices
- AI & Agent Building
- AI-coding skill
Better Auth Best Practices by the numbers
- 13 all-time installs (skills.sh)
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jackiexiao/jackie-skills-cn-top50 --skill better-auth-best-practicesAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| Last updated | February 20, 2026 |
| Repository | jackiexiao/jackie-skills-cn-top50 ↗ |
What it does
Helps with ai & agent building tasks.
Files
(中文)Better Auth Integration Guide
Always consult [better-auth.com/docs](https://better-auth.com/docs) for code examples and latest API.
Better Auth is a TypeScript-first, framework-agnostic auth framework supporting email/password, OAuth, magic links, passkeys, and more via plugins.
---
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
---