What should a CLAUDE.md for Next.js include?
A CLAUDE.md for Next.js should tell Claude Code the commands it cannot guess, where routes and data access live, your Server and Client Component rules, how secrets are handled, and the gotchas specific to your app. Keep it under 200 lines and start it with @AGENTS.md, so the AGENTS.md that Next.js generates keeps loading.
That last point is what most templates online miss. The default create-next-app setup includes an AGENTS.md, and in Next.js 16.3 and later next dev keeps a managed block in it that tells agents to read the docs bundled with your installed version. Claude Code reads AGENTS.md only when there is no CLAUDE.md, so the moment you add one, the Next.js block silently drops out unless you import it.
The template below is built for a Next.js 16 App Router project with TypeScript and Tailwind CSS, the defaults create-next-app picks. The commands and framework rules in it come from the Next.js docs; project conventions such as lib/db.ts, named exports and Vitest are common choices you can swap for your own. The memory behavior comes from Anthropic's CLAUDE.md documentation. For the general file format, see what a CLAUDE.md file is.
The Next.js CLAUDE.md template
Copy this into CLAUDE.md at your repo root, replace the angle-bracket placeholders, and delete any line that does not match your project.
@AGENTS.md
# <App name>
<One sentence: what this app does and who uses it.>
Stack: Next.js 16 (App Router), TypeScript strict, Tailwind CSS, npm. Node 20.9 or newer.
Docs for the installed Next.js version: node_modules/next/dist/docs/
## Commands
- Install: `npm install`
- Dev server: `npm run dev` (Turbopack, http://localhost:3000)
- Build: `npm run build` (does not run the linter)
- Production server: `npm run start`
- Lint: `npm run lint` (ESLint CLI; do not use `next lint`)
- Lint and fix: `npm run lint -- --fix`
- Typecheck: `npx tsc --noEmit`
- Unit tests (your runner's script): `npm test`; one file: `npm test -- path/to/file.test.tsx`
- E2E tests: `npm run build && npm run start`, then `npx playwright test`
- Done means: lint, typecheck and the tests for touched files all pass
## Project structure
- `app/`: routes only. `page.tsx` makes a route public; `layout.tsx`, `loading.tsx`,
`error.tsx`, `not-found.tsx` wrap it; `route.ts` is an API endpoint
- `app/(marketing)/`, `app/(dashboard)/`: route groups, not part of the URL
- `app/**/_components/`: private folders, never routable
- `components/ui/`: shared UI. `lib/`: data access and utilities
- `lib/db.ts`: the only module that talks to the database
- `proxy.ts`: request proxy (Next.js 16 renamed middleware to proxy)
- `public/`: static files served from `/`
## Server and Client Components
- Pages and layouts are Server Components. Fetch data there, not in effects
- Add `'use client'` only to the leaf component that needs state, effects,
event handlers or browser APIs. Never to a page or layout
- Everything a `'use client'` file imports ships to the browser
- Props passed to Client Components must be serializable by React
- Pass server-rendered UI into client wrappers as `children`
- Context providers live in a client component that wraps `{children}`, placed as deep as possible
## Data, env and security
- Secrets live in `.env.local` (git-ignored). Never print, log or commit them
- Only `NEXT_PUBLIC_` variables reach the browser, inlined at build time. No secrets there
- Modules that read secrets or the database start with `import 'server-only'`
- Every Server Function (`'use server'`) checks auth and validates input itself.
Do not rely on `proxy.ts` for auth
- `params` and `searchParams` are Promises: `const { id } = await params`
## Code style
- No `any`. No `@ts-ignore` without a comment saying why
- Named exports, except files where Next.js needs a default export (page, layout, etc.)
- Import with the `@/` alias, not long relative paths
- Use `next/image`, `next/link` and `next/font` instead of raw tags
- Style with Tailwind classes; no new global CSS without asking
## Testing
- Vitest and Testing Library for units and components, as `*.test.tsx` next to the file
- Async Server Components get Playwright E2E tests, not unit tests
- Every bug fix comes with a test that failed before the fix
## Do not
- Do not create `middleware.ts` or a `pages/` directory
- Do not edit the managed `nextjs-agent-rules` block in AGENTS.md; `next dev` rewrites it
- Do not add a dependency without asking first
- Do not change `next.config.ts` unless the task is about config
## Gotchas
- If a dev server is already running, `next dev` prints its URL and PID. Reuse it
- Browser console errors show up in the dev server terminal
- `.env*` files stay in the project root, even with a `src/` folder
- Changing a `NEXT_PUBLIC_` value needs a rebuild
- <Your app's own surprises: flaky services, seed data, feature flags>
How does this template work with the AGENTS.md Next.js creates?
New Next.js apps ship with an AGENTS.md. According to the Next.js guide to AI coding agents, create-next-app writes it for new projects and next dev creates or updates it in existing ones when it detects a coding agent. The managed block sits between nextjs-agent-rules markers and tells agents to read the guide that matches your installed version in node_modules/next/dist/docs/ before writing code. Next.js only touches the content between those markers, so anything you add above or below it is preserved.
Claude Code's AGENTS.md rules decide what happens next. By default, Claude reads AGENTS.md only when your working directory and the folders above it contain no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md. Reading AGENTS.md directly needs Claude Code v2.1.277 or later. So:
| Your repo has | Claude Code reads |
|---|---|
| Only the generated AGENTS.md | AGENTS.md, including the Next.js block |
| AGENTS.md and a CLAUDE.md without an import | CLAUDE.md only; the Next.js block is skipped |
AGENTS.md and a CLAUDE.md that starts with @AGENTS.md |
Both, with AGENTS.md expanded first |
That is why the template's first line is @AGENTS.md. Imports are expanded into context alongside the file that references them, and keeping the import never makes Claude read AGENTS.md twice. One more trap from the docs: a CLAUDE.local.md also counts as a CLAUDE.md, so creating one for personal notes stops Claude from reading AGENTS.md unless your CLAUDE.md imports it.
If you do not want the managed block at all, set agentRules: false in next.config.ts, as the agentRules reference explains, or create the app with --no-agents-md. Then delete the import line from the template.
What does each part of the template do?
Header and stack line. One sentence of purpose plus the stack saves Claude from inferring it. The docs path points Claude at version-matched documentation, which matters because Next.js 16 changed things models may have learned differently, such as the rename of middleware.ts to proxy.ts and the Promise-based params prop.
Commands. The dev, build, start and lint lines match the scripts create-next-app generates, described in the Next.js installation guide. create-next-app adds no test script, so the npm test lines assume you added one for your runner. next dev runs on Turbopack by default, and since Next.js 16 next build no longer runs the linter, so lint is its own step. The E2E line follows the Next.js Playwright guide, which runs tests against a production build. The "Done means" line is the single most useful rule in any CLAUDE.md: it gives Claude a concrete check instead of "test your changes."
Project structure. The routing files, route groups and _private folders follow the project structure page. Next.js is unopinionated about where components/ and lib/ go, so this is where your own layout goes. Naming one module as the only database access point stops Claude from opening connections in random components.
Server and Client Components. These rules come from the Server and Client Components guide: layouts and pages are Server Components by default, 'use client' marks a boundary that pulls every import into the client bundle, and props crossing it must be serializable. Writing them down stops the most common agent mistake in App Router code, which is marking a whole page as a client component to make one button work.
Data, env and security. Only NEXT_PUBLIC_ variables are bundled for the browser, and their values are frozen at build time, per the environment variables guide. The server-only import turns an accidental client import into a build error. The Server Function rule comes from the proxy docs, which warn that a matcher change can silently remove proxy coverage, so auth must be checked inside each function.
Testing. The Next.js testing guide recommends end-to-end tests over unit tests for async Server Components, because some unit tools do not fully support them yet. Vitest and Testing Library are one option; the same guide also covers Jest, Playwright and Cypress, so swap in whatever your project uses.
Do not and Gotchas. Short negative rules prevent repeat mistakes. The gotchas come from the docs: next dev reuses an existing server, forwards browser console errors to the terminal, and loads .env files only from the project root.
How do you adapt it to your project?
- pnpm, Yarn or Bun: swap
npm runfor your package manager. Wrong commands are worse than none. - Biome instead of ESLint: Next.js supports both. Replace the lint lines with
biome checkandbiome format --writescripts. src/folder: prefix the structure paths withsrc/but leave the.envline, because env files stay at the root.- Pages Router: remove the Server Component section and describe
pages/instead. Do not mix routers in one template. - Rules for one area: move them into
.claude/rules/. A file withpaths: ["app/**/route.ts"]in its frontmatter loads only when Claude touches a route handler. - Monorepo: put this file in the Next.js app's folder. Claude Code loads CLAUDE.md files in subdirectories on demand, when it reads or edits files there.
After you save the file, run /context in a Claude Code session and check that it appears under Memory files. If you have no CLAUDE.md yet and want a starting point from your actual code, /init generates one, and you can merge in the sections above.
Should you write an AGENTS.md version too?
If your team also uses Codex, Cursor or Copilot, put the shared content in AGENTS.md instead, below the Next.js managed block, and keep CLAUDE.md tiny. The AGENTS.md guide covers which tools read it.
@AGENTS.md
## Claude Code only
- Use plan mode before changing anything under `app/(billing)/`
- Run `/doctor prompt-audit` after editing AGENTS.md or this file
In that setup, AGENTS.md holds the commands, structure, rules and gotchas from the template, and CLAUDE.md adds only what is specific to Claude Code. The CLAUDE.md vs AGENTS.md comparison goes deeper on the trade-offs, and Claude Code memory explains load order.
How do you keep the file useful over time?
Anthropic's docs suggest adding a line when Claude makes the same mistake twice or a review catches something it should have known, and pruning anything Claude already does right. /doctor prompt-audit (Claude Code v2.1.283 or later) checks your instruction files for outdated or conflicting content and proposes edits. Remember that CLAUDE.md is context, not enforcement: to block an action outright, use a hook.
If you start many Next.js projects, it helps to keep the template somewhere you can reuse it. Kipt stores prompts and Agent Skills as Markdown in a private GitHub repo you own, so you could save this template as a prompt with blanks like {{package_manager:npm}} and fill them per project. For other stacks, see the FastAPI, Django and Rails templates.