Agent Skillstrycompai/crm › better-auth-best-practices

better-auth-best-practices

GitHub

提供 Better Auth 的全栈集成指南,涵盖服务端与客户端配置、数据库适配器选择、会话管理及环境变量设置,适用于 TypeScript 认证系统搭建。

.agents/skills/better-auth-best-practices/SKILL.md trycompai/crm

Trigger Scenarios

Better Auth 集成配置 数据库适配器设置 会话管理策略 环境变量的处理

Install

npx skills add trycompai/crm --skill better-auth-best-practices -g -y
More Options

Non-standard path

npx skills add https://github.com/trycompai/crm/tree/main/.agents/skills/better-auth-best-practices -g -y

Use without installing

npx skills use trycompai/crm@better-auth-best-practices

指定 Agent (Claude Code)

npx skills add trycompai/crm --skill better-auth-best-practices -a claude-code -g -y

安装 repo 全部 skill

npx skills add trycompai/crm --all -g -y

预览 repo 内 skill

npx skills add trycompai/crm --list

SKILL.md

Frontmatter
{
    "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."
}

Better Auth Integration Guide

Always consult 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 migrations:
    • Built-in adapter: npx @better-auth/cli@latest migrate
    • Drizzle: npx @better-auth/cli@latest generate --output src/db/auth-schema.ts then npx drizzle-kit push (dev) or npx drizzle-kit generate && npx drizzle-kit migrate (prod)
    • Prisma: npx @better-auth/cli@latest generate --output prisma/schema.prisma then npx prisma migrate dev
  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 32
  • BETTER_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/Drizzle
  • npx @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. For Postgres, also supports postgres (postgres.js) and @neondatabase/serverless.

ORM adapters: Import from better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.

Drizzle provider values: "pg" (PostgreSQL), "mysql" (MySQL), "sqlite" (SQLite). Must match the driver used.

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 work
  • emailVerification.sendOnSignUp / sendOnSignIn - Auto-send triggers
  • emailAndPassword.sendResetPassword - Password reset email handler

Security

In advanced:

  • useSecureCookies - Force HTTPS cookies
  • disableCSRFCheck - ⚠️ Security risk
  • disableOriginCheck - ⚠️ Security risk
  • crossSubDomainCookies.enabled - Share cookies across subdomains
  • ipAddress.ipAddressHeaders - Custom IP headers for proxies
  • database.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
  7. Drizzle: db not initialized - drizzleAdapter(db, ...) requires a db instance from drizzle(). See create-auth skill for setup examples (node-postgres, postgres.js, Neon).
  8. Drizzle: missing drizzle.config.ts - drizzle-kit commands require a drizzle.config.ts pointing to the generated schema file and DB credentials.

Resources

Version History

  • d42a04e Current 2026-08-04 18:45

Same Skill Collection

.agents/skills/ai-elements/SKILL.md
.agents/skills/eve/SKILL.md
.agents/skills/nestjs-best-practices/SKILL.md
.agents/skills/no-use-effect/SKILL.md
.agents/skills/nuqs/SKILL.md
.agents/skills/prisma-database-setup/SKILL.md
.agents/skills/shadcn/SKILL.md
.agents/skills/skill-creator/SKILL.md
.agents/skills/turborepo/SKILL.md
.agents/skills/typescript-advanced-types/SKILL.md
.agents/skills/vercel-composition-patterns/SKILL.md
.agents/skills/vercel-react-best-practices/SKILL.md
.agents/skills/web-design-guidelines/SKILL.md
.agents/skills/nestjs-trpc/SKILL.md

Metadata

Files
0
Version
d42a04e
Hash
6d41db16
Indexed
2026-08-04 18:45

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-05 08:51
浙ICP备14020137号-1 $방문자$