headroom.walls.sh · nextjs
Next.js projects have patterns Claude Code handles particularly well: App Router file conventions, API routes with Zod validation, Server vs Client Component decisions, and Playwright test generation. This page covers the workflows that save the most time.
Give Claude Code the project conventions once, and it applies them every session:
## Stack - Next.js 14+ (App Router) - TypeScript strict mode - Tailwind CSS - Prisma + PostgreSQL ## Commands - Dev: npm run dev - Type check: npx tsc --noEmit - Build: npm run build - Test: npx playwright test - Lint: npm run lint ## Conventions - Server Components by default — add "use client" only when needed - API routes use Zod for request validation - All database access goes through src/lib/db.ts - No inline styles — Tailwind classes only
Claude Code reads this at session start and respects these rules. It won't add "use client" unnecessarily or bypass Prisma for raw SQL unless you ask it to.
Claude Code understands the App Router file convention (app/route/page.tsx, layout.tsx, loading.tsx, error.tsx):
claude "add a /dashboard/settings page to the App Router — read the existing /dashboard/page.tsx first to match the layout and data-fetching style"
claude "add a loading.tsx and error.tsx to app/dashboard/ — follow the patterns from app/profile/ which already has them"
The "read the existing page first" instruction helps Claude Code match your specific patterns — whether you use async/await directly in Server Components, a data layer abstraction, or React Query for client-side fetching.
The most common Next.js question Claude Code handles well: what should be a Server Component vs a Client Component.
claude "read app/products/page.tsx. The product list needs to be filterable client-side. Extract the filterable part into a Client Component and keep the data fetching in the Server Component."
claude "find all components in app/components/ that use useState or useEffect but don't need to — convert them to Server Components if their data can be fetched server-side"
Claude Code reads the component, checks what it uses (hooks, event handlers, browser APIs), and makes the correct Server/Client decision based on those dependencies.
claude "add a POST /api/users route in app/api/users/route.ts — validate the request body with Zod (name: string, email: string, role: enum), write to the database via Prisma, return proper error responses"
claude "read all API routes in app/api/ — add Zod validation to any that currently parse request bodies without validation. Use a consistent error response format."
Claude Code will write the Zod schema, parse the request body, handle validation errors with a 400 response, and return typed data on success — all in one pass.
claude "the /products page fetches data directly in the component. Extract the data fetching into src/lib/products.ts with proper TypeScript return types, and update the page to call it"
claude "add revalidation to the /blog page — it should revalidate every 60 seconds using Next.js cache tags. Follow the pattern from /news which already uses this."
claude "the dashboard makes 3 sequential data fetches. Convert them to parallel fetches using Promise.all and measure the improvement in the dev server logs"
claude "add Next.js middleware to protect all /dashboard routes — redirect to /login if the session cookie is missing or invalid. Read the existing auth utilities in src/lib/auth.ts first."
claude "add rate limiting to the API routes in app/api/ using a simple in-memory counter. Log rate limit events and return 429 with a Retry-After header."
claude "write Playwright tests for the login flow — test: valid credentials succeed, invalid credentials show error message, remember-me checkbox persists the session"
claude "the checkout flow has no tests. Write Playwright e2e tests for: add to cart, view cart, enter shipping, enter payment, confirm order. Use page object pattern."
Claude Code generates complete Playwright tests that run against the dev server. Ask it to use page objects for flows with multiple steps — it keeps the tests readable as the UI changes.
claude "migrate pages/about.tsx to the App Router — create app/about/page.tsx with the equivalent Server Component. Remove the getStaticProps and convert it to async data fetching directly in the component."
claude "audit pages/ for routes that can be migrated to App Router. For each, assess: does it use getServerSideProps (→ Server Component), getStaticProps (→ static generation), or client-only (→ Client Component with 'use client')."
Migration benefits from the audit first — knowing what each page uses helps Claude Code choose the right App Router equivalent rather than doing a mechanical rename.
Next.js migrations and test generation sessions can run long. Headroom shows your Claude Code session (5h) and weekly (7d) utilization live in the macOS menu bar — no token, no API key, reads the file Claude Code writes to ~/.claude/.
Install in one line:
Color-coded from calm to amber to red. Know your headroom before you start a full Pages Router → App Router migration.
→ Claude Code for TypeScript
→ Writing tests with Claude Code
→ Multi-file editing with Claude Code
→ Refactoring with Claude Code