Next.js + Tailwind + Prisma Stack
Full-stack Next.js with Prisma ORM, Tailwind CSS, and Postgres.
# CLAUDE.md — Next.js + Tailwind + Prisma
## Project layout
- `app/` — routes
- `components/` — shared components (server-first)
- `lib/db.ts` — singleton Prisma client (see below)
- `lib/actions/<feature>.ts` — Server Actions
- `prisma/schema.prisma` — single source of truth for the data model
## Prisma client
- Export a singleton from `lib/db.ts` to avoid exhausting connection pools in dev:
```ts
import { PrismaClient } from '@prisma/client'
const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient }
export const db = globalForPrisma.prisma ?? new PrismaClient()
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db
```
- Never instantiate `new PrismaClient()` outside this file.
- Run `prisma generate` on every schema change. Add it to `postinstall`.
## Data access
- Query Prisma in Server Components and Server Actions only. Don't pass the Prisma client to the client.
- Use `select` to project only the fields you need. Don't return entire rows by default.
- Wrap multi-step writes in `prisma.$transaction`. If a write fails halfway, the rollback must be automatic.
- For pagination, use cursor-based pagination (`cursor`, `take`) — not `skip` + `take`.
## Migrations
- `prisma migrate dev --name <change>` for local schema changes; `prisma migrate deploy` in CI.
- Never edit a migration file after merging. Generate a new migration to fix forward.
- Seed data lives in `prisma/seed.ts`, runnable via `prisma db seed`.
## Tailwind
- Use semantic spacing scale (`p-4`, `gap-3`) — no magic pixel values via `[12px]` unless absolutely required.
- Component variants: use `cva` from `class-variance-authority`, not nested ternaries inside `className`.
- Mobile-first: write base styles, then `sm:`, `md:`, `lg:`. Don't write `lg:` styles before base.
## Environment
- `DATABASE_URL` and `DIRECT_URL` (for migrations) live in `.env`. Never commit `.env`.
- For pooled connections (Vercel, etc.), set `DATABASE_URL` to the pooled URL and `DIRECT_URL` to the direct one in `prisma/schema.prisma`.
## Don't
- Don't query Prisma from a Client Component or `useEffect`. Move it to the server.
- Don't use `findFirst` when `findUnique` would do — uniqueness is a hint to the planner.
- Don't disable type generation to ship.
- Don't leak full DB error messages to the client.
Other Next.js templates
Next.js App Router + TypeScript Rules
Server Components, Server Actions, and TypeScript discipline for the Next.js App Router.
Next.js + Server Actions + Shadcn UI
Forms with Server Actions, Zod validation, and Shadcn UI primitives.
Next.js + Supabase Auth
Auth flows with Supabase SSR, cookies, and Row Level Security policies.
Next.js SEO + Metadata Rules
Metadata API, sitemap, robots, OG images, and structured data done right.