nextjs-setup-better-auth
Setup Better Auth with Email OTP authentication and shadcn/ui components in a Next.js project
- License 许可
- MIT
- 所属仓库
- zuzu59/z-skills
- 最近更新
- 2026-09-30
- Stars
- ★ 0
- Forks
- 1
01 前言 Front Matter
- name
- nextjs-setup-better-auth
- description
- Setup Better Auth with Email OTP authentication and shadcn/ui components in a Next.js project
03 SKILL.md 正文
<objective> Setup Better Auth in the current Next.js project with Email OTP authentication flow.
This creates a production-ready authentication system with Resend email delivery, a beautiful sign-in page using shadcn/ui, and an account management page. Uses Prisma adapter for database integration. </objective>
<context>
Project structure: !ls -la
Prisma schema: !cat prisma/schema.prisma 2>/dev/null | head -40 || echo "No Prisma schema"
Existing auth: !ls src/lib/auth* 2>/dev/null || ls lib/auth* 2>/dev/null || echo "No auth files"
Path aliases: !cat tsconfig.json | grep -A5 '"paths"'
</context>
<process>
Phase 1: Prerequisites
-
Ask for Resend API Key - Prompt user:
"I need your Resend API key to send OTP emails. Get it from https://resend.com/api-keys"
-
Verify Prisma is configured:
- Check
prisma/schema.prismaexists - Identify Prisma client import path (custom output or default)
- Confirm
lib/prisma.tssingleton exists
- Check
Phase 2: Installation
-
Install dependencies:
pnpm add better-auth resend -
Install shadcn/ui components:
pnpm dlx shadcn@latest add input label card button tabs input-otp -
Get reference components (study then delete):
pnpm dlx shadcn@latest add https://coss.com/origin/r/comp-326.json pnpm dlx shadcn@latest add https://coss.com/origin/r/comp-324.json
Phase 3: Configuration
-
Configure environment variables - Add to
.env:BETTER_AUTH_SECRET="[generate with: openssl rand -base64 32]" BETTER_AUTH_URL="http://localhost:3000" RESEND_API_KEY="[user-provided]" RESEND_FROM_EMAIL="onboarding@resend.dev" -
Create Better Auth instance -
src/lib/auth.ts:import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { emailOTP } from "better-auth/plugins"; import { prisma } from "./prisma"; import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY); export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "postgresql" }), emailAndPassword: { enabled: false }, plugins: [ emailOTP({ async sendVerificationOTP({ email, otp, type }) { await resend.emails.send({ from: process.env.RESEND_FROM_EMAIL!, to: email, subject: type === "sign-in" ? "Sign in to your account" : "Verify your email", html: `<p>Your verification code is: <strong>${otp}</strong></p><p>This code will expire in 5 minutes.</p>`, }); }, otpLength: 6, expiresIn: 300, }), ], secret: process.env.BETTER_AUTH_SECRET!, baseURL: process.env.BETTER_AUTH_URL!, }); -
Generate Prisma schema using Better Auth CLI:
npx @better-auth/cli generate --config src/lib/auth.ts npx prisma migrate dev --name add_better_auth npx prisma generate -
Create API route handler -
app/api/auth/[...all]/route.ts:import { auth } from "@/lib/auth"; import { toNextJsHandler } from "better-auth/next-js"; export const { GET, POST } = toNextJsHandler(auth.handler); -
Create auth client -
src/lib/auth-client.ts:import { createAuthClient } from "better-auth/react"; import { emailOTPClient } from "better-auth/client/plugins"; export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL || "http://localhost:3000", plugins: [emailOTPClient()], }); export const { signIn, signOut, useSession } = authClient;
Phase 4: UI Implementation
-
Study reference components - Read comp-326 and comp-324 patterns:
- Note form layouts, validation patterns, UX flows
- Understand OTP input behavior
-
Create sign-in page -
app/sign-in/page.tsx:- Two-step flow: email input → OTP verification
- Use
InputOTPcomponent with 6 slots - Auto-submit on complete with
onCompletehandler - Loading states and error handling with
text-destructive - Redirect to
/accounton success
-
Create account page -
app/account/page.tsx:- Protected route (redirect if no session)
- Tabs for Profile and Security
- Profile form with name update
- Sign out button
- Session info display
-
Delete reference components - Remove comp-326 and comp-324 files
Phase 5: Integration & Testing
-
Update layout - Add TanStack Query provider if needed for session management
-
Update home page - Add auth status display with sign-in/account links
-
Test complete flow:
- Navigate to
/sign-in - Enter email, receive OTP
- Verify OTP, redirect to
/account - Update name, sign out </process>
- Navigate to
<constraints> UI RULES:
- ONLY use shadcn/ui components and theme colors
- NEVER use custom colors - only background, foreground, primary, secondary, muted, accent, destructive
- All styling via Tailwind with theme-aware classes
- NO hardcoded colors like #000, blue-500, etc.
FLEXIBILITY:
- Check Prisma client location before importing
- Adapt all paths to project structure
- Match existing path alias conventions </constraints>
<success_criteria>
- Sign-in page renders with email input
- OTP email is sent via Resend
- OTP verification signs user in
- Account page shows session data
- Name update persists to database
- Sign out clears session and redirects
- No TypeScript or linting errors </success_criteria>
04 同仓库更多 Skills
writing-great-skills
Reference for writing and editing skills well — the vocabulary and principles that make a skill predictable.
use-style
Apply named visual style guides to landing pages, app shells, and UI. Use for $use-style, /useskill, list styles, or styles like ios-app, grid, vercel, black-grid, stripe, linear, raycast, gumroad, dusk, or luma.
use-goal
Use when the user asks to create, draft, set, start, or refine a Codex or Claude Code `/goal` objective for persistent multi-turn work.
use-fable
Orchestrator mode for Fable: Fable thinks, plans, and reviews while Codex CLI and subagents execute all heavy work. Use when the user invokes /use-fable, says 'use fable', 'fable mode', 'orchestrator mode', or wants to save Fable tokens/rate limits.
use-delegate
Delegation mode: the host agent (Claude or Codex) plans and reviews while heavy work runs on cheap executors: OpenCode Kimi K3, Codex GPT-5.6 terra/sol. Use when the user invokes /use-delegate, says 'use delegate', 'delegate mode', 'orchestrator mode', or wants to save tokens/rate limits.
use-artifacts
Create Claude-style local HTML artifacts under ~/.agents/artifacts. Use for plans, prototypes, visualizations, dashboards, diagrams, options, or substantial reusable content, with a portable local runtime and no Anthropic API.