"use client"; import { motion } from "framer-motion"; import Link from "next/link"; import type { ReactNode } from "react"; import { startTransition, useEffect, useRef, useState } from "react"; import { DynamicCodeBlock } from "@/components/ui/dynamic-code-block"; export const providerIcons: Record ReactNode> = { Google: () => ( ), GitHub: () => ( ), Apple: () => ( ), Microsoft: () => ( ), Discord: () => ( ), Slack: () => ( ), Twitter: () => ( ), Facebook: () => ( ), LinkedIn: () => ( ), GitLab: () => ( ), Twitch: () => ( ), Spotify: () => ( ), Figma: () => ( ), Notion: () => ( ), Atlassian: () => ( ), HuggingFace: () => ( ), Reddit: () => ( ), TikTok: () => ( ), PayPal: () => ( ), Dropbox: () => ( ), Zoom: () => ( ), Vercel: () => ( ), Linear: () => ( ), Kick: () => ( ), Kakao: () => ( ), Line: () => ( ), VK: () => ( ), Naver: () => ( ), Polar: () => ( ), Roblox: () => ( ), Salesforce: () => ( ), }; export const socialProviders = [ "Google", "GitHub", "Apple", "Microsoft", "Discord", "Slack", "Twitter", "Facebook", "LinkedIn", "GitLab", "Twitch", "Spotify", "Figma", "Notion", "Atlassian", "Salesforce", "HuggingFace", "Roblox", "Reddit", "TikTok", "PayPal", "Dropbox", "Zoom", "Vercel", "Linear", "Kick", "Kakao", "Line", "VK", "Naver", ]; export const plugins = [ { name: "Two Factor", category: "auth" }, { name: "Passkey", category: "auth" }, { name: "Magic Link", category: "auth" }, { name: "Email OTP", category: "auth" }, { name: "Username", category: "auth" }, { name: "One Tap", category: "auth" }, { name: "Phone Number", category: "auth" }, { name: "Anonymous", category: "auth" }, { name: "Bearer", category: "auth" }, { name: "Generic OAuth", category: "auth" }, { name: "One Time Token", category: "auth" }, { name: "SIWE", category: "auth" }, { name: "Organization", category: "org" }, { name: "Admin", category: "org" }, { name: "Multi Session", category: "org" }, { name: "API Key", category: "org" }, { name: "SSO", category: "enterprise" }, { name: "OIDC Provider", category: "enterprise" }, { name: "SCIM", category: "enterprise" }, { name: "OAuth Proxy", category: "enterprise" }, { name: "JWT", category: "security" }, { name: "HIBP", category: "security" }, { name: "Captcha", category: "security" }, { name: "Stripe", category: "integration" }, { name: "Polar", category: "integration" }, { name: "Open API", category: "integration" }, { name: "Dub", category: "integration" }, { name: "Autumn", category: "integration" }, { name: "Dodo Payments", category: "integration" }, { name: "Creem", category: "integration" }, { name: "MCP", category: "ai" }, { name: "Device Auth", category: "auth" }, { name: "Last Login", category: "auth" }, ]; export const categoryLabels: Record = { auth: "Authentication", org: "Organization", enterprise: "Enterprise", security: "Security", integration: "Integration", ai: "AI", }; const _categoryColors: Record = { auth: "text-violet-500/50 dark:text-violet-400/40", org: "text-sky-500/50 dark:text-sky-400/40", enterprise: "text-amber-500/50 dark:text-amber-400/40", security: "text-red-500/50 dark:text-red-400/40", integration: "text-emerald-500/50 dark:text-emerald-400/40", ai: "text-pink-500/50 dark:text-pink-400/40", }; const dbDrivers = [ { name: "PostgreSQL", icon: () => ( ), }, { name: "MySQL", icon: () => ( ), }, { name: "SQLite", icon: () => ( ), }, { name: "MongoDB", icon: () => ( ), }, { name: "LibSQL", icon: () => ( ), }, ]; const ormAdapters = [ { name: "Prisma", icon: () => ( ), }, { name: "Drizzle", icon: () => ( ), }, { name: "Mongoose", icon: () => ( ), }, { name: "TypeORM", icon: () => ( ), }, { name: "Kysely", icon: () => ( ), }, { name: "MikroORM", icon: () => ( ), }, ]; const dbCodeExamples: Record = { PostgreSQL: `import { betterAuth } from "better-auth" import { Pool } from "pg" export const auth = betterAuth({ database: new Pool({ connectionString: process.env.DATABASE_URL, }), })`, Prisma: `import { betterAuth } from "better-auth" import { prismaAdapter } from "better-auth/adapters/prisma" import { PrismaClient } from "@prisma/client" const prisma = new PrismaClient() export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "postgresql", }), })`, Drizzle: `import { betterAuth } from "better-auth" import { drizzleAdapter } from "better-auth/adapters/drizzle" import { db } from "./db" export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", }), })`, MongoDB: `import { betterAuth } from "better-auth" import { mongodbAdapter } from "better-auth/adapters/mongodb" import { MongoClient } from "mongodb" const client = new MongoClient(process.env.MONGO_URI!) const db = client.db() export const auth = betterAuth({ database: mongodbAdapter(db), })`, }; export const serverCode = `import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, }, github: { clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, }, }, plugins: [ twoFactor(), passkey(), organization(), ], })`; export const clientCode = `import { createAuthClient } from "better-auth/react" export const authClient = createAuthClient({ plugins: [ twoFactorClient(), passkeyClient(), organizationClient(), ], })`; export function ServerClientTabs() { const [activeTab, setActiveTab] = useState<"server" | "client">("server"); return (
); } const allDbs = [...dbDrivers, ...ormAdapters]; function getDbIcon(name: string) { const found = allDbs.find((d) => d.name === name); return found ? found.icon() : null; } export function DatabaseSection() { const [activeDb, setActiveDb] = useState("PostgreSQL"); const dbOptions = Object.keys(dbCodeExamples); const codeScrollRef = useRef(null); const sidebarRef = useRef(null); const isFirstRender = useRef(true); useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } const el = codeScrollRef.current; if (el) { el.scrollTop = 0; } const sidebar = sidebarRef.current; if (sidebar) { const active = sidebar.querySelector( `[data-db="${activeDb}"]`, ) as HTMLElement | null; if (active) { active.scrollIntoView({ block: "nearest", behavior: "smooth" }); } } }, [activeDb]); return (
Bring Your Own{" "} Database

Use any database you want. Connect directly with a connection string, or use your favorite ORM adapter. Your data stays in your database.

{/* Tabs */}
{dbOptions.map((db) => ( ))}
{/* Code + Sidebar side by side, same fixed height */}
{/* Code snippet */}
{/* Right sidebar — supported DBs & community */}

Direct Drivers

{dbDrivers.map((db) => ( ))}

ORM Adapters

{ormAdapters.map((adapter) => ( ))}

Community

{["Supabase", "Neon", "Turso", "PlanetScale", "D1"].map( (name) => (
{name}
), )}
); } export function SocialProvidersSection() { const containerRef = useRef(null); const [scrollIndex, setScrollIndex] = useState(0); const visibleRows = 2; const perRow = 5; const rowHeight = 34; const totalRows = Math.ceil(socialProviders.length / perRow); const maxScroll = totalRows - visibleRows; useEffect(() => { const interval = setInterval(() => { setScrollIndex((prev) => (prev >= maxScroll ? 0 : prev + 1)); }, 2500); return () => clearInterval(interval); }, [maxScroll]); const allRows = Array.from({ length: totalRows }, (_, rowIdx) => socialProviders.slice(rowIdx * perRow, rowIdx * perRow + perRow), ); return (
35+

social providers

{allRows.map((row, rowIdx) => (
{row.map((provider) => { const Icon = providerIcons[provider]; return ( {Icon && ( {Icon()} )} {provider} ); })}
))}
); } export function PluginEcosystem() { const half = Math.ceil(plugins.length / 2); const row1 = plugins.slice(0, half); const row2 = plugins.slice(half); return (
Plugin Ecosystem {plugins.length} official
browse all →
{/* Row 1 — scrolls left */}
{[...row1, ...row1].map((plugin, i) => ( {plugin.name} {categoryLabels[plugin.category]} ))}
{/* Row 2 — scrolls right */}
{[...row2, ...row2].map((plugin, i) => ( {plugin.name} {categoryLabels[plugin.category]} ))}
{/* Side fades */}
); } const mcpClients = [ { name: "Cursor", cmd: "npx @better-auth/cli mcp --cursor" }, { name: "Claude Code", cmd: "claude mcp add better-auth" }, { name: "Open Code", cmd: "npx @better-auth/cli mcp --open-code" }, ]; export function AiNativeSection() { const steps = [ { label: "mcp", text: "Connected to better-auth docs" }, { label: "skill", text: "better-auth/add-provider → google" }, { label: "skill", text: "better-auth/add-plugin → two-factor" }, { label: "write", text: "lib/auth.ts", lines: 14 }, { label: "done", text: "Google OAuth + 2FA configured" }, ]; return (
AI Native

Your auth lives in{" "} your codebase {" "} — so AI can configure it. Ships with{" "} MCP server ,{" "} Claude Code skills , and{" "} Cursor rules .

{/* Prompt line */}
Add Google login and 2FA to my app
{/* Steps */}
{steps.map((step) => (
{step.label} {step.text} {"lines" in step && typeof step.lines === "number" && ( +{step.lines} )} {step.label === "done" && ( )}
))}
{/* MCP clients */}
{mcpClients.map((mc) => (

{mc.name}

{mc.cmd}
))}
); }