/better-auth-add-plugin
Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports.
$ npx -y skills add secondsky/claude-skills --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/better-auth-add-plugin
Context preview
What this command does when you run it.
Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports.
Command definition
better-auth-add-plugin.mdname: better-auth:add-plugin
description: Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports.
argument-hint: "<plugin-name>"
Add better-auth Plugin
This command adds a plugin to an existing better-auth configuration.
Usage
/better-auth-add-plugin <plugin-name>
Supported Plugins
| Plugin | Description | |--------|-------------| | `2fa` / `two-factor` | Two-factor authentication (TOTP) | | `passkeys` | WebAuthn/Passkeys | | `magic-link` | Passwordless magic links | | `email-otp` | Email-based OTP codes | | `anonymous` | Anonymous/guest users | | `organizations` | Multi-tenancy support | | `sso` / `saml` | SSO/SAML integration | | `scim` | SCIM user provisioning | | `admin` | Admin dashboard | | `api-key` | API key authentication | | `bearer` | Bearer token support | | `jwt` | JWT token plugin | | `oidc` | OIDC provider | | `stripe` | Stripe payments | | `polar` | Polar payments |
Process
Step 1: Locate Configuration
Find the existing auth configuration:
- `src/auth.ts`
- `lib/auth.ts`
- `server/auth.ts`
Find the client configuration:
- `src/lib/auth-client.ts`
- `lib/auth-client.ts`
Step 2: Add Server Plugin
Based on the plugin, add the appropriate import and configuration:
Two-Factor Authentication
import { twoFactor } from "better-auth/plugins";
plugins: [
twoFactor({
issuer: "Your App Name",
}),
],Passkeys
import { passkey } from "@better-auth/passkey"; // extracted package (v1.5+)
plugins: [
passkey({
rpID: "your-domain.com",
rpName: "Your App",
origin: "https://your-domain.com",
}),
],Magic Links
import { magicLink } from "better-auth/plugins";
plugins: [
magicLink({
sendMagicLink: async ({ email, token, url }) => {
// TODO: Implement email sending
await sendEmail({ to: email, subject: "Sign in", html: `<a href="${url}">Click to sign in</a>` });
},
}),
],Organizations
import { organization } from "better-auth/plugins";
plugins: [
organization({
allowUserToCreateOrganization: true,
}),
],API Keys
import { apiKey } from "@better-auth/api-key"; // extracted package (v1.5+)
plugins: [
apiKey({
prefix: "sk_",
}),
],Admin
import { admin } from "better-auth/plugins";
plugins: [
admin({
adminUsers: ["admin@your-company.com"],
}),
],Stripe
import { stripe } from "better-auth/plugins";
import Stripe from "stripe";
const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY!);
plugins: [
stripe({
stripeClient,
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
}),
],Step 3: Add Client Plugin
Add matching client plugin:
// In auth-client.ts
import {
twoFactorClient,
passkeyClient,
magicLinkClient,
organizationClient,
apiKeyClient,
adminClient,
stripeClient,
} from "better-auth/client/plugins";
export const authClient = createAuthClient({
plugins: [
// Add matching client plugin
twoFactorClient(),
],
});Step 4: Update Database Schema (if needed)
Some plugins require additional tables:
Organizations
// Add to schema.ts
export const organization = pgTable("organization", {
id: text("id").primaryKey(),
name: text("name").notNull(),
slug: text("slug").notNull().unique(),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});
export const member = pgTable("member", {
id: text("id").primaryKey(),
organizationId: text("organizationId").notNull(),
userId: text("userId").notNull(),
role: text("role").notNull().default("member"),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});API Keys
// v1.5+: `userId` renamed to `referenceId`; new `configId` field (defaults to "default")
export const apiKeyTable = pgTable("api_key", {
id: text("id").primaryKey(),
referenceId: text("referenceId").notNull(), // was `userId` pre-v1.5
configId: text("configId").notNull().default("default"), // v1.5+ new field
name: text("name").notNull(),
keyHash: text("keyHash").notNull(),
expiresAt: timestamp("expiresAt"),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});Step 5: Environment Variables
Add required environment variables:
# Two-Factor - no additional vars needed
# Passkeys
# RP_ID and RP_ORIGIN configured in code
# Magic Links
# Email provider credentials
# Stripe
STRIPE_SECRET_KEY=sk_...
STRIPE_WEBHOOK_SECRET=whsec_...
# SSO/SAML
# IdP-specific configuration
Step 6: Generate Migrations
# For Drizzle
bunx drizzle-kit generate
bunx drizzle-kit push
# For Prisma
bunx prisma generate
bunx prisma migrate dev
Output
After adding a plugin, report:
✓ Added two-factor plugin to src/auth.ts
✓ Added twoFactorClient to src/lib/auth-client.ts
✓ No schema changes required
Next steps:
1. Run migrations if schema was updated
2. Configure plugin options as needed
3. Implement UI components for 2FA setup
Documentation:
- Plugin docs: https://better-auth.com/docs/plugins/two-factor
- Reference: references/plugins/authentication.md
Common Combinations
Enterprise Setup
/better-auth-add-plugin organizations
/better-auth-add-plugin sso
/better-auth-add-plugin scim
/better-auth-add-plugin admin
Enhanced Security
/better-auth-add-plugin 2fa
/better-auth-add-plugin passkeys
API Access
/better-auth-add-plugin api-key
/better-auth-add-plugin jwt
Monetization
/better-auth-add-plugin stripe
Read more
name: better-auth:add-plugin description: Add a better-auth plugin to an existing project. Configures server and client plugins with proper imports. argument-hint: "<plugin-name>"
Add better-auth Plugin
This command adds a plugin to an existing better-auth configuration.
Usage
/better-auth-add-plugin <plugin-name>
Supported Plugins
| Plugin | Description | |--------|-------------| | `2fa` / `two-factor` | Two-factor authentication (TOTP) | | `passkeys` | WebAuthn/Passkeys | | `magic-link` | Passwordless magic links | | `email-otp` | Email-based OTP codes | | `anonymous` | Anonymous/guest users | | `organizations` | Multi-tenancy support | | `sso` / `saml` | SSO/SAML integration | | `scim` | SCIM user provisioning | | `admin` | Admin dashboard | | `api-key` | API key authentication | | `bearer` | Bearer token support | | `jwt` | JWT token plugin | | `oidc` | OIDC provider | | `stripe` | Stripe payments | | `polar` | Polar payments |
Process
Step 1: Locate Configuration
Find the existing auth configuration:
- `src/auth.ts`
- `lib/auth.ts`
- `server/auth.ts`
Find the client configuration:
- `src/lib/auth-client.ts`
- `lib/auth-client.ts`
Step 2: Add Server Plugin
Based on the plugin, add the appropriate import and configuration:
Two-Factor Authentication
import { twoFactor } from "better-auth/plugins";
plugins: [
twoFactor({
issuer: "Your App Name",
}),
],Passkeys
import { passkey } from "@better-auth/passkey"; // extracted package (v1.5+)
plugins: [
passkey({
rpID: "your-domain.com",
rpName: "Your App",
origin: "https://your-domain.com",
}),
],Magic Links
import { magicLink } from "better-auth/plugins";
plugins: [
magicLink({
sendMagicLink: async ({ email, token, url }) => {
// TODO: Implement email sending
await sendEmail({ to: email, subject: "Sign in", html: `<a href="${url}">Click to sign in</a>` });
},
}),
],Organizations
import { organization } from "better-auth/plugins";
plugins: [
organization({
allowUserToCreateOrganization: true,
}),
],API Keys
import { apiKey } from "@better-auth/api-key"; // extracted package (v1.5+)
plugins: [
apiKey({
prefix: "sk_",
}),
],Admin
import { admin } from "better-auth/plugins";
plugins: [
admin({
adminUsers: ["admin@your-company.com"],
}),
],Stripe
import { stripe } from "better-auth/plugins";
import Stripe from "stripe";
const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY!);
plugins: [
stripe({
stripeClient,
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
}),
],Step 3: Add Client Plugin
Add matching client plugin:
// In auth-client.ts
import {
twoFactorClient,
passkeyClient,
magicLinkClient,
organizationClient,
apiKeyClient,
adminClient,
stripeClient,
} from "better-auth/client/plugins";
export const authClient = createAuthClient({
plugins: [
// Add matching client plugin
twoFactorClient(),
],
});Step 4: Update Database Schema (if needed)
Some plugins require additional tables:
Organizations
// Add to schema.ts
export const organization = pgTable("organization", {
id: text("id").primaryKey(),
name: text("name").notNull(),
slug: text("slug").notNull().unique(),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});
export const member = pgTable("member", {
id: text("id").primaryKey(),
organizationId: text("organizationId").notNull(),
userId: text("userId").notNull(),
role: text("role").notNull().default("member"),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});API Keys
// v1.5+: `userId` renamed to `referenceId`; new `configId` field (defaults to "default")
export const apiKeyTable = pgTable("api_key", {
id: text("id").primaryKey(),
referenceId: text("referenceId").notNull(), // was `userId` pre-v1.5
configId: text("configId").notNull().default("default"), // v1.5+ new field
name: text("name").notNull(),
keyHash: text("keyHash").notNull(),
expiresAt: timestamp("expiresAt"),
createdAt: timestamp("createdAt").notNull().defaultNow(),
});Step 5: Environment Variables
Add required environment variables:
# Two-Factor - no additional vars needed # Passkeys # RP_ID and RP_ORIGIN configured in code # Magic Links # Email provider credentials # Stripe STRIPE_SECRET_KEY=sk_... STRIPE_WEBHOOK_SECRET=whsec_... # SSO/SAML # IdP-specific configuration
Step 6: Generate Migrations
# For Drizzle bunx drizzle-kit generate bunx drizzle-kit push # For Prisma bunx prisma generate bunx prisma migrate dev
Output
After adding a plugin, report:
✓ Added two-factor plugin to src/auth.ts ✓ Added twoFactorClient to src/lib/auth-client.ts ✓ No schema changes required Next steps: 1. Run migrations if schema was updated 2. Configure plugin options as needed 3. Implement UI components for 2FA setup Documentation: - Plugin docs: https://better-auth.com/docs/plugins/two-factor - Reference: references/plugins/authentication.md
Common Combinations
Enterprise Setup
/better-auth-add-plugin organizations /better-auth-add-plugin sso /better-auth-add-plugin scim /better-auth-add-plugin admin
Enhanced Security
/better-auth-add-plugin 2fa /better-auth-add-plugin passkeys
API Access
/better-auth-add-plugin api-key /better-auth-add-plugin jwt
Monetization
/better-auth-add-plugin stripe
142 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).
Repo: secondsky/claude-skills
Other commands on secondsky-claude-skills.
- /better-auth-setup
Interactive setup wizard for better-auth authentication. Guides through database, framework, OAuth providers, and plugin configuration.
Open command - /explain-error
Explain Better Auth error codes and provide solutions with code examples
Open command - /providers
Display Better Auth available authentication providers and their configuration
Open command - /bun-debug
Type of issue to debug (runtime, test, build, memory, performance)
Open command - /bun-deploy
Target platform (docker, cloudflare, vercel, fly, railway)
Open command - /bun-init
Template to use (hono, next, nuxt, sveltekit, tanstack, basic)
Open command

