/api-auth-better-auth-drizzle-hono
Better Auth patterns, sessions, OAuth
$ npx -y skills add agents-inc/skills --skill api-auth-better-auth-drizzle-hono --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/api-auth-better-auth-drizzle-hono
Context preview
The summary Claude sees to decide when to auto-load this skill.
Better Auth patterns, sessions, OAuth
SKILL.md
api-auth-better-auth-drizzle-hono.SKILL.mdname: api-auth-better-auth-drizzle-hono
description: Better Auth patterns, sessions, OAuth
Authentication with Better Auth
> **Quick Guide:** Use Better Auth (v1.5+) for type-safe, self-hosted authentication in TypeScript apps. It provides email/password, OAuth, 2FA, sessions, stateless auth, and organization multi-tenancy. Plugin architecture enables progressive complexity. Mount auth handler before session-dependent middleware, configure CORS first for cross-origin deployments, and always run schema generation after adding plugins.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST mount Better Auth handler on the auth route BEFORE any other middleware that depends on session)**
**(You MUST configure CORS middleware BEFORE auth routes when client and server are on different origins)**
**(You MUST use environment variables for ALL secrets (clientId, clientSecret, BETTER_AUTH_SECRET) - NEVER hardcode)**
**(You MUST run `npx auth@latest generate` then your ORM migration tool after adding plugins)**
**(You MUST use `auth.$Infer.Session` types for type-safe session access in middleware)**
</critical_requirements>
---
**Auto-detection:** Better Auth, betterAuth, createAuthClient, auth.handler, auth.api.getSession, socialProviders, twoFactor plugin, organization plugin, drizzleAdapter, session management, OAuth providers, stateless sessions, cookieCache, genericOAuth, oAuthProvider, passkey, SCIM
**When to use:**
- Building self-hosted authentication (no vendor lock-in)
- Need email/password + OAuth + 2FA in one solution
- Multi-tenant SaaS with organization/team management
- Type-safe session management
- Projects requiring database-stored or stateless sessions
**When NOT to use:**
- Need managed authentication with zero maintenance (consider hosted auth solutions)
- Simple static sites without user accounts
- Projects where serverless cold starts are critical (though stateless mode helps)
**Key patterns covered:**
- Server configuration (auth.ts) with plugins
- Session middleware and type-safe route protection
- Email/password authentication flows
- OAuth providers (GitHub, Google, Generic OAuth)
- Two-factor authentication (TOTP)
- Organization and multi-tenancy
- Session strategies: database, cookie cache, stateless
- Database adapter integration
- Client-side useSession hook
- Performance: experimental joins, cookie caching, stateless sessions
**Detailed Resources:**
- [examples/core.md](examples/core.md) - Sign up, sign in, client setup, database adapter
- [examples/oauth.md](examples/oauth.md) - GitHub, Google, Generic OAuth providers
- [examples/two-factor.md](examples/two-factor.md) - TOTP setup, enable, verify
- [examples/organizations.md](examples/organizations.md) - Multi-tenancy, invitations
- [examples/sessions.md](examples/sessions.md) - Session config, cookie caching, stateless
- [reference.md](reference.md) - Decision frameworks, anti-patterns, version notes
---
<philosophy>
Philosophy
Better Auth follows a **TypeScript-first, self-hosted** approach to authentication. Your user data stays in your database, with no vendor lock-in. The plugin architecture enables progressive complexity - start simple and add features as needed.
**Core principles:**
1. **Type safety throughout** - Session types flow from server to client via `auth.$Infer.Session` 2. **Database as source of truth** - Sessions stored in your DB (with optional stateless mode) 3. **Plugin-based extensibility** - Add 2FA, organizations, passkeys, SCIM, OAuth provider when needed 4. **Framework-agnostic** - Works with any TypeScript web framework 5. **Performance-focused** - Experimental joins (2-3x faster), cookie caching, stateless sessions
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Server Configuration (auth.ts)
Create the auth instance with database adapter. Single source of truth for all authentication config.
// lib/auth.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/db";
const SESSION_EXPIRES_IN_SECONDS = 60 * 60 * 24 * 7; // 7 days
const SESSION_UPDATE_AGE_SECONDS = 60 * 60 * 24; // Refresh daily
export const auth = betterAuth({
database: drizzleAdapter(db, { provider: "pg" }),
emailAndPassword: {
enabled: true,
minPasswordLength: 8,
maxPasswordLength: 128,
},
session: {
expiresIn: SESSION_EXPIRES_IN_SECONDS,
updateAge: SESSION_UPDATE_AGE_SECONDS,
},
trustedOrigins: [process.env.APP_URL || "http://localhost:3000"],
});**Why good:** Named constants make session policy auditable, env vars for URLs, single exported instance
// BAD: Magic numbers, hardcoded secrets, default export
const auth = betterAuth({
database: { url: "postgres://user:pass@localhost/db" },
session: { expiresIn: 604800 },
});
export default auth;**Why bad:** Hardcoded credentials leak in source control, magic numbers obscure policy, default export
See [examples/core.md](examples/core.md) for full setup with email verification and Drizzle adapter configuration.
---
Pattern 2: Session Middleware with Type Safety
Mount auth handler and create typed middleware for session access in routes.
// CRITICAL: CORS must be configured BEFORE auth routes
app.use("/auth/*", cors({ origin: APP_URL, credentials: true }));
app.on(["POST", "GET"], "/auth/*", (c) => auth.handler(c.req.raw));// middleware/auth-middleware.ts - Type-safe session access
type AuthVariables = {
user: typeof auth.$Infer.Session.user | null;
session: typeof auth.$Infer.Session.session | null;
};
export const authMiddleware = createMiddleware<{ Variables: AuthVariables }>(
async (c, next) => {
const session = await auth.api.getSession({ headers: c.Read more
name: api-auth-better-auth-drizzle-hono description: Better Auth patterns, sessions, OAuth
Authentication with Better Auth
> **Quick Guide:** Use Better Auth (v1.5+) for type-safe, self-hosted authentication in TypeScript apps. It provides email/password, OAuth, 2FA, sessions, stateless auth, and organization multi-tenancy. Plugin architecture enables progressive complexity. Mount auth handler before session-dependent middleware, configure CORS first for cross-origin deployments, and always run schema generation after adding plugins.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST mount Better Auth handler on the auth route BEFORE any other middleware that depends on session)**
**(You MUST configure CORS middleware BEFORE auth routes when client and server are on different origins)**
**(You MUST use environment variables for ALL secrets (clientId, clientSecret, BETTER_AUTH_SECRET) - NEVER hardcode)**
**(You MUST run `npx auth@latest generate` then your ORM migration tool after adding plugins)**
**(You MUST use `auth.$Infer.Session` types for type-safe session access in middleware)**
</critical_requirements>
---
**Auto-detection:** Better Auth, betterAuth, createAuthClient, auth.handler, auth.api.getSession, socialProviders, twoFactor plugin, organization plugin, drizzleAdapter, session management, OAuth providers, stateless sessions, cookieCache, genericOAuth, oAuthProvider, passkey, SCIM
**When to use:**
- Building self-hosted authentication (no vendor lock-in)
- Need email/password + OAuth + 2FA in one solution
- Multi-tenant SaaS with organization/team management
- Type-safe session management
- Projects requiring database-stored or stateless sessions
**When NOT to use:**
- Need managed authentication with zero maintenance (consider hosted auth solutions)
- Simple static sites without user accounts
- Projects where serverless cold starts are critical (though stateless mode helps)
**Key patterns covered:**
- Server configuration (auth.ts) with plugins
- Session middleware and type-safe route protection
- Email/password authentication flows
- OAuth providers (GitHub, Google, Generic OAuth)
- Two-factor authentication (TOTP)
- Organization and multi-tenancy
- Session strategies: database, cookie cache, stateless
- Database adapter integration
- Client-side useSession hook
- Performance: experimental joins, cookie caching, stateless sessions
**Detailed Resources:**
- [examples/core.md](examples/core.md) - Sign up, sign in, client setup, database adapter
- [examples/oauth.md](examples/oauth.md) - GitHub, Google, Generic OAuth providers
- [examples/two-factor.md](examples/two-factor.md) - TOTP setup, enable, verify
- [examples/organizations.md](examples/organizations.md) - Multi-tenancy, invitations
- [examples/sessions.md](examples/sessions.md) - Session config, cookie caching, stateless
- [reference.md](reference.md) - Decision frameworks, anti-patterns, version notes
---
<philosophy>
Philosophy
Better Auth follows a **TypeScript-first, self-hosted** approach to authentication. Your user data stays in your database, with no vendor lock-in. The plugin architecture enables progressive complexity - start simple and add features as needed.
**Core principles:**
1. **Type safety throughout** - Session types flow from server to client via `auth.$Infer.Session` 2. **Database as source of truth** - Sessions stored in your DB (with optional stateless mode) 3. **Plugin-based extensibility** - Add 2FA, organizations, passkeys, SCIM, OAuth provider when needed 4. **Framework-agnostic** - Works with any TypeScript web framework 5. **Performance-focused** - Experimental joins (2-3x faster), cookie caching, stateless sessions
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Server Configuration (auth.ts)
Create the auth instance with database adapter. Single source of truth for all authentication config.
// lib/auth.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/db";
const SESSION_EXPIRES_IN_SECONDS = 60 * 60 * 24 * 7; // 7 days
const SESSION_UPDATE_AGE_SECONDS = 60 * 60 * 24; // Refresh daily
export const auth = betterAuth({
database: drizzleAdapter(db, { provider: "pg" }),
emailAndPassword: {
enabled: true,
minPasswordLength: 8,
maxPasswordLength: 128,
},
session: {
expiresIn: SESSION_EXPIRES_IN_SECONDS,
updateAge: SESSION_UPDATE_AGE_SECONDS,
},
trustedOrigins: [process.env.APP_URL || "http://localhost:3000"],
});**Why good:** Named constants make session policy auditable, env vars for URLs, single exported instance
// BAD: Magic numbers, hardcoded secrets, default export
const auth = betterAuth({
database: { url: "postgres://user:pass@localhost/db" },
session: { expiresIn: 604800 },
});
export default auth;**Why bad:** Hardcoded credentials leak in source control, magic numbers obscure policy, default export
See [examples/core.md](examples/core.md) for full setup with email verification and Drizzle adapter configuration.
---
Pattern 2: Session Middleware with Type Safety
Mount auth handler and create typed middleware for session access in routes.
// CRITICAL: CORS must be configured BEFORE auth routes
app.use("/auth/*", cors({ origin: APP_URL, credentials: true }));
app.on(["POST", "GET"], "/auth/*", (c) => auth.handler(c.req.raw));// middleware/auth-middleware.ts - Type-safe session access
type AuthVariables = {
user: typeof auth.$Infer.Session.user | null;
session: typeof auth.$Infer.Session.session | null;
};
export const authMiddleware = createMiddleware<{ Variables: AuthVariables }>(
async (c, next) => {
const session = await auth.api.getSession({ headers: c.Showing the first part of this file.
The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Other skills on agents-inc-skills.
- /ai-infrastructure-huggingface-inference
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints
Open skill - /ai-infrastructure-litellm
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment
Open skill - /ai-infrastructure-modal
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Open skill - /ai-infrastructure-ollama
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint
Open skill - /ai-infrastructure-replicate
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Open skill - /ai-infrastructure-together-ai
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints
Open skill

