better-auth-setup
Interactive setup wizard for better-auth authentication. Guides through database, framework, OAuth providers, and plugin configuration.
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.
/better-auth-add-pluginContext 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.
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>"
This command adds a plugin to an existing better-auth configuration.
/better-auth-add-plugin <plugin-name>
| 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 |
Find the existing auth configuration:
Find the client configuration:
Based on the plugin, add the appropriate import and configuration:
import { twoFactor } from "better-auth/plugins";
plugins: [
twoFactor({
issuer: "Your App Name",
}),
],import { passkey } from "@better-auth/passkey"; // extracted package (v1.5+)
plugins: [
passkey({
rpID: "your-domain.com",
rpName: "Your App",
origin: "https://your-domain.com",
}),
],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>` });
},
}),
],import { organization } from "better-auth/plugins";
plugins: [
organization({
allowUserToCreateOrganization: true,
}),
],import { apiKey } from "@better-auth/api-key"; // extracted package (v1.5+)
plugins: [
apiKey({
prefix: "sk_",
}),
],import { admin } from "better-auth/plugins";
plugins: [
admin({
adminUsers: ["admin@your-company.com"],
}),
],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!,
}),
],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(),
],
});Some plugins require additional tables:
// 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(),
});// 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(),
});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
# For Drizzle bunx drizzle-kit generate bunx drizzle-kit push # For Prisma bunx prisma generate bunx prisma migrate dev
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
/better-auth-add-plugin organizations /better-auth-add-plugin sso /better-auth-add-plugin scim /better-auth-add-plugin admin
/better-auth-add-plugin 2fa /better-auth-add-plugin passkeys
/better-auth-add-plugin api-key /better-auth-add-plugin jwt
/better-auth-add-plugin stripe
145 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
Interactive setup wizard for better-auth authentication. Guides through database, framework, OAuth providers, and plugin configuration.
Explain Better Auth error codes and provide solutions with code examples
Display Better Auth available authentication providers and their configuration