Skip to content

The Claude Code setup for a Next.js app

The best Claude Code setup for a Next.js repo: a short CLAUDE.md, path-scoped rules, skills, subagents, guard hooks and MCP. What goes where, with real files.

Updated · 10 min read

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

LayerWhereWhen it loadsUse it forGuide
CLAUDE.mdRepo rootEvery session, in fullStack, commands, layout, pointersCLAUDE.md template
Rules.claude/rules/*.mdEvery session, or when Claude touches a matching fileConventions per folderThis page
Skills.claude/skills/<name>/SKILL.mdDescription always, body when usedRepeated proceduresSkills
Subagents.claude/agents/*.mdWhen spawned, in their own contextReviewers, auditors, read-only rolesSubagents
Hooks.claude/settings.json + scriptsOn the event. No context costThings that must never happenHooks
MCP servers.mcp.jsonTool names at startTalking to Stripe, Neon, SentryThis page
Solution docsdocs/solutions/When readKnown mistakes, written down onceThis 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:

  • paths is 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 .md files under .claude/rules/ are found, so rules/frontend/ and rules/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.ts
  • auth-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.tsx
  • code-style: always loaded
  • deployment: next.config.ts, vercel.json, package.json, src/proxy.ts, src/app/**/route.ts, .env.example
  • drizzle-migrations: src/db/**, drizzle/**, drizzle.config.ts
  • drizzle-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 loaded
  • identify-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 loaded
  • sentry-capture: src/**, sentry.server.config.ts, sentry.edge.config.ts
  • sentry-no-pii: always loaded
  • server-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.ts
  • testing: tests/**, src/**/*.test.ts, src/**/*.test.tsx
  • tokens-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, not backend.md.
  • Short. The generated system-manager agent 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.ts
  • block-destructive.ts
  • enforce-doc-meta.ts
  • enforce-typecheck.ts
  • env-leak-detector-write.ts
  • env-leak-detector.ts
  • guard-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

DoWhy
Keep CLAUDE.md under 200 linesIt loads on every request
Scope every folder-specific rule with pathsIt loads only when it applies
Name your Next.js, React and TypeScript majors in a ruleModels trained on older code write older APIs
Write rules for route.ts, proxy.ts and next.config.tsThat is where builds and deploys break
Turn a procedure you explained twice into a skillIt costs one line until used
Gate side-effect skills with disable-model-invocation: trueNo surprise deploys
Give every subagent an explicit tools listLeaving it out grants every tool
Put "never do X" in a PreToolUse hookInstructions are requests, hooks are not
Use "$CLAUDE_PROJECT_DIR" in hook commandsGuards keep firing after cd
Test hooks after every change to .claude/Guards die without telling you
Commit .claude/ and .mcp.jsonThe whole team gets the same agent
Turn a correction you made twice into a ruleTwo 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" in CLAUDE.md is 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.md and .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.