A good Claude Code setup is mostly about where each instruction lives. Facts Claude needs on every task go in CLAUDE.md. Conventions for one folder go in a path-scoped rule. Procedures go in skills. Narrow jobs go to subagents. Anything that must never happen goes in a hook.
Get the placement right and your agent forgets less. Get it wrong and you get a 600-line CLAUDE.md it half-reads.
This page is the whole setup on one page, with real files from a generated Next.js repo. Each section links to a deeper guide.
The setup at a glance
| Layer | Where | When it loads | Use it for | Guide |
|---|---|---|---|---|
CLAUDE.md | Repo root | Every session, in full | Stack, commands, layout, pointers | CLAUDE.md template |
| Rules | .claude/rules/*.md | Every session, or when Claude touches a matching file | Conventions per folder | This page |
| Skills | .claude/skills/<name>/SKILL.md | Description always, body when used | Repeated procedures | Skills |
| Subagents | .claude/agents/*.md | When spawned, in their own context | Reviewers, auditors, read-only roles | Subagents |
| Hooks | .claude/settings.json + scripts | On the event. No context cost | Things that must never happen | Hooks |
| MCP servers | .mcp.json | Tool names at start | Talking to Stripe, Neon, Sentry | This page |
| Solution docs | docs/solutions/ | When read | Known mistakes, written down once | This page |
The last row is not a Claude Code feature. It is a folder of markdown files and a line in CLAUDE.md that says "read the relevant one first". It works anyway.
The file tree
This is the shape of a repo the generator writes:
my-app/
CLAUDE.md # the index Claude reads every session
AGENTS.md # the same rules for Codex
.claude/
settings.json # hooks and plugins
rules/ # path-scoped conventions
skills/ # /slash-command procedures
agents/ # subagents
hooks/ # guard scripts
.cursor/rules/ # the rules again, for Cursor
.mcp.json # MCP servers for your batteries
docs/
onboard.md # every env var and where to get it
solutions/ # known problems, solved
plans/ # one plan per piece of work
src/
Commit .claude/, except settings.local.json. Personal tweaks go there and in CLAUDE.local.md.
1. Keep CLAUDE.md short
CLAUDE.md loads in full on every request. Anthropic's docs say to target under 200 lines. Longer files cost more context and get followed less.
What belongs in it:
- The stack and the package manager.
- The four commands to get running.
- Where things live.
- Pointers to everything else: rules, skills, subagents,
docs/onboard.md.
What does not:
- Conventions for one folder. Those are rules.
- Multi-step procedures. Those are skills.
- "Never run X." That is a hook.
@path imports help you organize, but imported files still load at launch. They don't save context.
The generated CLAUDE.md is an index, not a manual. It lists the stack, four setup commands and the counts, then every rule, skill and subagent with a one-line summary. The full walkthrough is in the CLAUDE.md template guide.
If you also run Codex, keep an AGENTS.md. When a repo has both files, Claude Code reads CLAUDE.md by default. The generator writes both. See CLAUDE.md vs AGENTS.md.
2. Path-scoped rules
A rule is a markdown file in .claude/rules/. Without frontmatter it loads at session start, like CLAUDE.md. Add a paths list and it loads only when Claude reads, writes or edits a matching file.
That is the trick that keeps a big setup cheap. A rule on src/lib/billing/** costs nothing while Claude edits a marketing page.
Copy this: a path-scoped rule
A generic example. Save as .claude/rules/route-handlers.md:
---
paths:
- "src/app/api/**/route.ts"
---
# Route handlers
- Parse the request body with a Zod schema before you use it.
- Check the session inside the handler. Never rely on proxy.ts alone.
- Return Response.json(...) with an explicit status code.
- A new handler gets a test for the happy path and the unauthorized path.
How rules behave:
pathsis the only field Claude Code reads. Anything else in the frontmatter is ignored.- Globs work as you expect.
src/**/*.tsx,src/components/**,*.{ts,tsx}. - Quote globs that start with
*or{. YAML reads a bare*as an alias. If the frontmatter fails to parse, Claude Code ignores it and loads the rule everywhere. - Subfolders work. All
.mdfiles under.claude/rules/are found, sorules/frontend/andrules/backend/are fine. - Personal rules go in
~/.claude/rules/and apply to every project.
A real rule, scoped to the files it governs
This is the deployment rule from a generated Next.js repo. It loads when Claude touches next.config.ts, src/proxy.ts, a route handler or .env.example:
---
paths:
- next.config.ts
- vercel.json
- package.json
- src/proxy.ts
- src/app/**/route.ts
- .env.example
---
# Deployment rules
Target is Vercel. These constraints are what actually breaks builds and
runtimes, in the order they usually break them.
## Before any deploy
Run all four locally and get them green:
```bash
bun run typecheck
bun run lint
bun run test
bun run build
```
A green dev server is not evidence. `next build` type-checks and prerenders
paths that `next dev` never touches.
First 28 of 72 lines of .claude/rules/deployment.md.
The full repo ships 30 rules. Each line shows the paths that load it:
admin-access:src/app/(admin)/**,src/components/admin/**,src/lib/admin/actions.ts,src/app/api/admin/**admin-mutations:src/lib/admin/**,src/components/admin/**,scripts/admin/**app-shell:src/app/(app)/**,src/components/app/**,src/components/ui/sidebar.tsx,src/lib/app-shell.ts,src/lib/nav.tsauth-server-boundary:src/lib/auth/**,src/app/api/auth/**,src/app/(better-auth)/**,src/components/auth/**billing-core:src/lib/pricing.ts,src/lib/billing/**,src/app/pricing/**,src/app/(app)/billing/**,src/components/billing/**blog-content:content/**blog-rendering:src/app/blog/**,src/app/sitemap.ts,src/lib/blog/**,src/components/blog/**,src/mdx-components.tsxcode-style: always loadeddeployment:next.config.ts,vercel.json,package.json,src/proxy.ts,src/app/**/route.ts,.env.exampledrizzle-migrations:src/db/**,drizzle/**,drizzle.config.tsdrizzle-schema:src/db/**email-sending-discipline:src/lib/email/**,src/app/api/webhooks/resend/**,src/lib/auth/**,src/lib/billing/**event-naming:src/lib/analytics/**,src/app/**,src/components/**git: always loadedidentify-timing:src/lib/analytics/**,src/app/**,src/components/**landing-and-legal:src/lib/site.ts,src/lib/llms.ts,src/app/page.tsx,src/app/(legal)/**,src/app/llms.txt/**,src/components/marketing/**,src/components/site/**neon-connections:src/db/**,src/app/api/**neon-migrations:src/db/**roles-are-server-side:src/app/**,src/components/**,src/lib/auth/**security: always loadedsentry-capture:src/**,sentry.server.config.ts,sentry.edge.config.tssentry-no-pii: always loadedserver-truth-and-pii:src/lib/analytics/**,src/app/**,src/components/**stripe-billing-store:src/lib/billing/**,scripts/billing/**stripe-pricing-source-of-truth:src/lib/pricing.ts,src/lib/billing/**,scripts/billing/**stripe-server-boundary:src/lib/billing/**,src/app/api/webhooks/stripe/**,src/app/**stripe-webhook-integrity:src/app/api/webhooks/stripe/**,src/lib/billing/provider.ts,src/lib/billing/webhook.tstesting:tests/**,src/**/*.test.ts,src/**/*.test.tsxtokens-only:src/components/**,src/app/**ui-kit:src/components/**,src/app/**
Seven come from the Next.js stack: code-style, git and security load every session, and testing, deployment, ui-kit and landing-and-legal load for the files they cover. app-shell, billing-core and tokens-only come with auth, payments and the design. The rest come from the batteries. Stripe alone adds four.
The same rules compile to 58 Cursor files (rules plus one per skill). Each keeps the scope as globs:
---
alwaysApply: false
description: Deployment rules
globs: next.config.ts,vercel.json,package.json,src/proxy.ts,src/app/**/route.ts,.env.example
---
First 5 of 66 lines of .cursor/rules/deployment.mdc.
More on that in Cursor rules for Next.js.
Write rules Claude can check
- Checkable, not vibes. "Re-read the files you touched before you finish" works. "Write clean code" doesn't.
- Do, don't, exception. In that order.
- One topic per file.
stripe-webhook-integrity.md, notbackend.md. - Short. The generated
system-manageragent caps rules at roughly 40 lines. Longer than that, it's a solution doc. - Scoped by default. An unscoped rule costs context on every task. Make it earn that.
3. Skills for repeated work
A skill is a SKILL.md that becomes a slash command. Claude sees only its description until it runs, so 30 skills cost 30 descriptions, not 30 files.
The generated repo ships 28: /verify, /write-spec, /qa-feature, /deploy-to-vercel and /security-audit from the stack, plus battery ones like /add-plan, /test-webhook, /db-branch and /add-table.
Write one the third time you explain the same procedure. Full guide, with the /verify skill quoted in full: Claude Code skills.
4. Subagents for narrow jobs
A subagent is a separate Claude with its own prompt, tools and context window. It hands back a summary.
The generated repo ships 7. pr-reviewer reviews a diff against .claude/rules/. security-auditor hunts leaked keys and missing auth checks. db-inspector runs SELECT and EXPLAIN only. system-manager owns .claude/ and turns repeated corrections into rules.
The rule of thumb: give each one the smallest tool list that does the job. Full guide: Claude Code subagents.
5. Hooks for what must never happen
Rules, skills and CLAUDE.md are all instructions. Claude reads them and decides. A hook is a script Claude Code runs on every matching tool call, whatever Claude decides.
A PreToolUse hook that exits 2 blocks the call. Hooks run before permission checks, so a block holds even with --dangerously-skip-permissions. The generated repo wires 7:
auto-lint.tsblock-destructive.tsenforce-doc-meta.tsenforce-typecheck.tsenv-leak-detector-write.tsenv-leak-detector.tsguard-neon-sql.ts
Together they block rm -rf, force pushes, DROP TABLE and .env reads, and redact live secrets from output. A self-test, bun run verify:hooks, proves each one still fires. Full guide with the wiring: Claude Code hooks.
6. MCP servers, only the real ones
MCP servers give Claude tools for outside services. Project servers live in .mcp.json at the repo root, committed so the team gets the same ones. In an interactive session, Claude Code asks for approval before it uses a project server.
The generated repo only lists servers that its batteries actually have:
{
"mcpServers": {
"better-auth": {
"type": "http",
"url": "https://mcp.better-auth.com/mcp"
},
"neon": {
"type": "http",
"url": "https://mcp.neon.tech/mcp?readonly=true"
},
"posthog": {
"type": "http",
"url": "https://mcp.posthog.com/mcp?readonly=true"
},
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
},
"stripe": {
"type": "http",
"url": "https://mcp.stripe.com"
}
}
}
.mcp.json, as generated.
Neon and PostHog connect read-only (?readonly=true). Sign in to each with /mcp. Don't add a server you won't use. Every one is another login and another set of tools in the list.
7. Solution docs: mistakes written down once
docs/solutions/ holds one problem per file: symptom, cause, fix, how to verify. The example repo is seeded with 74, like idempotent Stripe webhooks, Neon pooled vs direct URLs, and the PostHog identify race.
CLAUDE.md tells Claude to read the relevant one before re-solving anything. When you fix something new, write it down. Every seeded doc is public in the cookbook. Start with idempotent Stripe webhooks.
Claude Code best practices for a Next.js repo
| Do | Why |
|---|---|
Keep CLAUDE.md under 200 lines | It loads on every request |
Scope every folder-specific rule with paths | It loads only when it applies |
| Name your Next.js, React and TypeScript majors in a rule | Models trained on older code write older APIs |
Write rules for route.ts, proxy.ts and next.config.ts | That is where builds and deploys break |
| Turn a procedure you explained twice into a skill | It costs one line until used |
Gate side-effect skills with disable-model-invocation: true | No surprise deploys |
Give every subagent an explicit tools list | Leaving it out grants every tool |
Put "never do X" in a PreToolUse hook | Instructions are requests, hooks are not |
Use "$CLAUDE_PROJECT_DIR" in hook commands | Guards keep firing after cd |
Test hooks after every change to .claude/ | Guards die without telling you |
Commit .claude/ and .mcp.json | The whole team gets the same agent |
| Turn a correction you made twice into a rule | Two is a pattern, one is an accident |
The generated code-style rule has a section for this: "Examples online often target older majors. These are the ones installed here." Copy the idea even if you copy nothing else.
Common mistakes
- The 600-line
CLAUDE.md. Everything in one file, all of it loaded on every task, half of it ignored. - Unscoped rules for everything. Billing rules loading while Claude edits a button.
- Advice instead of rules. "Be careful with webhooks" gives Claude nothing to check.
- Guardrails as prose. "Never run
git reset --hard" inCLAUDE.mdis a wish. - Subagents with every tool. The read-only reviewer that can edit.
- Hooks nobody tested. Wired once, broken since the last refactor.
- Rules that contradict. Claude picks one at random. Audit
CLAUDE.mdand.claude/rules/together. - A setup that never changes. If corrections don't turn into rules, the same bug gets fixed twice.
Get the whole setup in one command
That is a lot of files to write by hand. The generator writes them for your stack:
npm create agentic-boilerplate@latest my-app
Or click through the builder. Pick from 26 batteries (auth, database, payments, email, analytics, admin, AI) and 31 designs. The Indie SaaS preset gives you 30 rules, 28 skills, 7 subagents, 7 hooks and 74 solution docs. Rules and skills compile for Claude Code, Codex and Cursor. Free during launch, then $99 once.
Battery pages show what each one adds: Stripe, Neon. How the layers fit together: the agentic layer. The Codex side: AGENTS.md examples.
FAQ
What is the best Claude Code setup for a Next.js project?
A short CLAUDE.md as an index, path-scoped rules in .claude/rules/ for each part of the app, skills for repeated procedures, a few subagents with narrow tool lists, and PreToolUse hooks for anything destructive. Commit all of it.
What are path-scoped rules in Claude Code?
Markdown files in .claude/rules/ with a paths list of globs in their frontmatter. They load only when Claude reads, writes or edits a matching file, so they cost no context the rest of the time.
Where do Claude Code rules go?
Project rules go in .claude/rules/ and get committed. Personal rules go in ~/.claude/rules/ and apply to every project on your machine.
How long should CLAUDE.md be?
Anthropic's docs say to target under 200 lines. Move folder-specific conventions into path-scoped rules and procedures into skills.
Does Claude Code read AGENTS.md?
Recent versions read AGENTS.md when there is no CLAUDE.md. When both exist, Claude Code reads CLAUDE.md by default, and a CLAUDE.md can pull in AGENTS.md with an @AGENTS.md import.
Should I commit the .claude folder?
Yes. Commit .claude/settings.json, rules, skills, agents and hooks so the team gets the same setup. Keep personal settings in .claude/settings.local.json.
Sources
Tool behavior is from the official docs, checked on October 4, 2026. Tools change. The docs win.
Keep reading
- CLAUDE.md template for Next.js, from a real repoA CLAUDE.md template for Next.js you can copy, a real one from a generated repo, where the file goes, what belongs in it, and the mistakes that get it ignored.
- AGENTS.md examples, from a real Next.js repoWhat AGENTS.md is, a template to copy, real root and nested AGENTS.md files from a generated Next.js repo, and how Codex, Cursor and Claude Code load them.
- CLAUDE.md vs AGENTS.md: which one you needCLAUDE.md is for Claude Code. AGENTS.md is the shared file Codex, Cursor and others read. Which tool reads what, and how to run both without them drifting.
- Cursor rules for Next.js, with real .mdc examplesHow Cursor rules work: the .mdc format, globs, alwaysApply and the four rule types, plus real Next.js rules from a generated repo that you can copy.