Skip to content

AI CODING ASSISTANTS

How to Set Up CLAUDE.md: A Complete Configuration Guide

A working CLAUDE.md setup cuts wasted context every session. Here's where the file goes, the structure we run in production, and the ceiling where it starts working against you.

A CLAUDE.md setup is one markdown file at your project root, committed to git, holding the facts Claude Code cannot infer from your code: build commands, conventions, and the traps specific to your repo. Run /init to generate a starting file, then cut it down — Anthropic's documented target is under 200 lines, because longer files consume more context and reduce adherence.

This guide covers where the file goes, how it loads, the structure we run on this site's repository, and what to do when it outgrows the ceiling. Every example is from the CLAUDE.md in production here — 135 lines, ten sections — including the two instructions in it that went stale and had to be pulled.

Key takeaways

  • CLAUDE.md is delivered as a user message after the system prompt, not as part of it. It is context, not enforced configuration, which is why adherence is probabilistic rather than absolute.
  • Anthropic's documented size target is under 200 lines per file. There is no hard cap, but longer files reduce adherence.
  • @path imports organize a large instruction set but do not reduce context cost — imported files still load in full at launch.
  • .claude/rules/ with a paths: frontmatter field is the only mechanism that keeps instructions out of context until they are relevant.
  • An instruction that must run every time belongs in a hook, not in CLAUDE.md.

What CLAUDE.md actually does

Claude Code reads CLAUDE.md at the start of every session and loads its contents into the context window. The detail that explains almost every complaint about the file comes from Anthropic's memory documentation: that content is delivered as a user message after the system prompt, not as part of the system prompt itself.

That single fact reframes the whole file. Claude reads your instructions and tries to follow them, but there is no guarantee of strict compliance — the docs say so directly. Vague instructions get interpreted loosely. Contradictory instructions get resolved arbitrarily. A rule buried on line 340 of a bloated file competes with everything above it.

System prompt first, then CLAUDE.md injected as a user message, then your first prompt
Delivery order at session start. The placement is what makes adherence probabilistic rather than absolute.

So the question to ask about every line is not "is this rule correct?" but "is this rule specific enough to act on, and is it worth the context it costs?"

Where the file goes

CLAUDE.md files load from several locations, ordered from broadest scope to most specific, so a project instruction lands in context after a user instruction.

ScopeLocationCommit it?
Managed policyOS-specific system pathDeployed by IT, not by you
User~/.claude/CLAUDE.mdNo — personal, all projects
Project./CLAUDE.md or ./.claude/CLAUDE.mdYes — shared with the team
Local./CLAUDE.local.mdNo — add it to .gitignore

Both project locations are read, so pick one and be consistent. Claude Code walks up the directory tree from your working directory and concatenates everything it finds, ordered from the filesystem root down — instructions closer to where you launched are read last. Files in subdirectories below you load on demand, when Claude reads a file in that directory.

That upward walk is what surprises people in monorepos: another team's CLAUDE.md three levels up is in your context. The claudeMdExcludes setting skips specific files by path or glob, and belongs in .claude/settings.local.json so the exclusion stays on your machine.

CLAUDE.md files found on the walk up a monorepo tree, and the context order they produce
The upward walk in a monorepo: an ancestor file nobody on your team wrote still lands in your context.

A CLAUDE.md setup that survives real work

Start with /init, which reads your codebase and generates a file with the build commands, test setup, and conventions it can detect. Then delete most of it. The generated file describes things Claude can rediscover by reading the code; what you keep should be what it cannot.

Here is the section list of the CLAUDE.md running this site, in order:

CLAUDE.md — section outline (135 lines total)
## Commands                                    ← build, typecheck, lint, dev
## Never build while the dev server is running ← the most expensive trap first
## MDX authoring traps                         ← six silent-failure rules
## Database                                    ← the one module allowed to talk to D1
## Admin panel                                 ← where the security boundary actually is
## Public site is not to be modified casually  ← what's frozen and why
## Styling                                     ← design tokens, no UI libraries
## Content workflow                            ← the editorial pipeline
## Environment                                 ← Windows, two shells, secrets
## Verifying, not assuming                     ← the code outranks the docs

The ordering is deliberate: the two sections most likely to cost an hour sit at the top, where they compete with the least. Every heading is a category of mistake we actually made, not a category of information that exists.

What earns a place, and what does not:

IncludeExclude
Commands that can't be guessedAnything readable from the code
Style rules that differ from defaultsStandard language conventions
Non-obvious behaviour and gotchasFile-by-file descriptions
Architectural decisions and their whyLong tutorials or API docs
Environment quirks and required varsFacts that change frequently
The two phases of a CLAUDE.md: build it once, then correct and prune forever
A line earns its place on the second correction, and loses it when the code moves on.

Writing instructions Claude follows

Write instructions concrete enough to verify. The difference is not stylistic — a verifiable instruction gives Claude a check it can run against its own output, and a vague one gives it nothing.

VagueVerifiable
"Format code properly""Use 2-space indentation"
"Test your changes""Run npm test before committing"
"Keep files organized""API handlers live in src/api/handlers/"

Three more rules earn their keep:

  • Structure it. Markdown headers and bullets group related instructions. Claude scans structure the way a reader does — organized sections beat dense paragraphs.
  • Remove contradictions. If two rules conflict, Claude may pick one arbitrarily. Review nested CLAUDE.md files and .claude/rules/ periodically for guidance that has drifted apart.
  • Apply the deletion test. For every line ask: would removing this cause Claude to make a mistake? If not, cut it. Bloat is not neutral — it is what makes your real rules get lost.

The 200-line ceiling

Target under 200 lines per file. CLAUDE.md files load in full at any length, so nothing breaks when you cross it — the certain cost is tokens, because every line loads every session. Anthropic also states that longer files reduce adherence; a 2026 factorial study looked for that effect directly and did not detect it, which is covered alongside the mistakes that actually slow Claude Code down.

The instinct at that point is to split the file into @path imports. That organizes the content, but it does not help — imported files are expanded and loaded into context at launch alongside the file that references them, up to a maximum depth of four hops. The context cost is identical.

Four imported files loading 400 lines every session versus path-scoped rules loading 200
The same 400-line instruction set under both mechanisms. Only the paths: field changes what loads.

What actually reduces the cost is .claude/rules/. A rule file with a paths field in its frontmatter loads only when Claude reads a matching file:

.claude/rules/api.md
---
paths:
  - "src/api/**/*.ts"
---

# API rules

- Every endpoint validates its input before touching the database.
- Errors use the standard response shape in `src/api/errors.ts`.

Rules without a paths field load unconditionally, at the same priority as .claude/CLAUDE.md. Two more levers: /doctor proposes trims for a checked-in CLAUDE.md, cutting content Claude can derive from the codebase while keeping pitfalls and rationale (v2.1.206 or later), and claudeMdExcludes drops ancestor files you don't want.

We haven't needed .claude/rules/ on this repo yet — at 135 lines the whole file is cheaper than the machinery to split it. That calculus changes around the ceiling.

A CLAUDE.md example you can copy

Most CLAUDE.md examples are templates with placeholder headings. This is a real entry from ours, reproduced exactly, and it is shaped the way it is for a reason:

CLAUDE.md — excerpt
## Never build while the dev server is running

`next dev` and `next build` share `.next`. Running a build against a live dev
server rewrites its chunk manifest and **every route starts returning 500 —
public pages included**. It looks exactly like an application bug and wastes an
hour of debugging the wrong thing.

Before `npm run build`: confirm no dev server is running, or ask. If a build
already corrupted one, the fix is stop the server, `rm -rf .next`, restart.

Four things are doing work there. It names the symptom an agent will actually observe (500s on every route), not the cause. It states the mechanism in one sentence, so the rule is understood rather than memorized. It gives an action before the risky command. And it supplies the recovery, because the failure is discovered after the fact more often than before it.

That entry exists because we lost an hour to it. Every section in the file has a story like that behind it, which is the honest test of whether a line belongs: nothing goes in speculatively.

Common mistakes

  • Documenting what the code already says. Directory layouts, dependency lists, and architecture overviews are the first things /init writes and the first things to cut. Claude can read those. Spend the context on what it can't infer.
  • Writing rules you can't check. "Follow best practices" cannot fail a review, so it cannot change behaviour. If you can't describe what violating the rule looks like, rewrite it.
  • Trusting the file after the code changes. This is the one we got wrong. Our CLAUDE.md carried a warning that a build error in components/article/MdxContent.tsx told authors to use the wrong attribute syntax, and to trust the file over the message. The component was fixed weeks earlier; the warning stayed, teaching contributors to distrust a message that had become correct. A second entry pointed at a documentation example that had since been fixed. Both were removed on 2026-07-24. A stale instruction is worse than a missing one — it is confidently wrong, and it survives exactly as long as nobody re-reads the file.
  • Reaching for imports to fix size. Covered above: imports reorganize, they don't reduce. Reach for .claude/rules/ instead.
  • Encoding must-happen rules as prose. Anything that has to run at a fixed point — before every commit, after every edit — is a hook. CLAUDE.md is advisory by design.

Best practices

  • Commit it. A project CLAUDE.md belongs in version control so the team shares one set of conventions and improves them by pull request.
  • Add on the second correction. When you type the same clarification into chat twice, that's the signal the fact belongs in the file.
  • Prune on a schedule. Treat it like code: review it when things go wrong, and delete aggressively. The file compounds in value only if it stays accurate.
  • Verify it loaded. Run /context and check the Memory files list. If your file isn't there, nothing else in this guide matters. /memory opens the files for editing.
  • Escalate deliberately. Advisory guidance goes in CLAUDE.md; guaranteed execution goes in a hook; system-prompt-level instruction goes in --append-system-prompt. And when you want Claude to commit to an approach before it touches anything, that is plan mode, not a file.
Decision tree routing an instruction to a hook, a rule file, a CLI flag, or CLAUDE.md
CLAUDE.md is the default. Escalate only when the instruction needs a guarantee or a path scope.

Laid out side by side, the five mechanisms differ on two things that matter — when they enter the context window, and whether they can be ignored:

MechanismWhere it livesWhen it loadsEnforcement
CLAUDE.md./CLAUDE.md, committedEvery session, in fullAdvisory
Rule file.claude/rules/*.md with paths:Only when Claude reads a matching fileAdvisory
Auto memoryMEMORY.md index, per repositoryEvery sessionAdvisory
Hook.claude/settings.jsonFires at a lifecycle event, not at launchGuaranteed
--append-system-promptCLI flag, not committedThat invocation onlyStrongest framing available

Four of the five are advisory, which is the point worth internalising: only a hook actually runs.

Conclusion

Write the file for the mistakes you have actually made, keep it under 200 lines, and make every line specific enough that you could tell whether it was violated. If it grows past the ceiling, move path-specific guidance into .claude/rules/ rather than splitting it into imports that cost the same context.

Then re-read it a month later. Ours was 135 lines and two of them were actively wrong — which is the strongest argument for keeping it short enough that re-reading is cheap. Both stale rules, and the measured cost of getting a CLAUDE.md wrong, are in the follow-up on what slows Claude Code down. If you're still deciding whether a terminal-first agent like Claude Code fits your workflow better than an editor like Cursor, that comparison is worth reading before you invest in a config file either way. And if your project is a Next.js app specifically, this workflow applies everything here plus the framework-specific traps a generic CLAUDE.md guide can't cover. More guides on working with agents are in AI Coding Assistants.

Frequently asked questions

Where does CLAUDE.md go?
Project root, at ./CLAUDE.md or ./.claude/CLAUDE.md — both are read, and both should be committed so your team shares them. Personal notes that shouldn't be committed go in ./CLAUDE.local.md, added to .gitignore. Machine-wide preferences live in ~/.claude/CLAUDE.md. Files in parent directories are also loaded, which is what makes monorepo setups pick up instructions you didn't expect.
How long should a CLAUDE.md file be?
Anthropic's documented target is under 200 lines per file. There is no hard cap — CLAUDE.md files load in full at any length — but longer files consume more context, and Anthropic reports that they reduce adherence. The CLAUDE.md running this site is 135 lines across ten sections. If yours is growing past 200, move path-specific guidance into .claude/rules/ rather than trimming detail you actually need.
Why is Claude Code ignoring my CLAUDE.md?
Usually one of three things. The file didn't load — run /context and check the Memory files list. The instruction is too vague to act on, like "write clean code." Or two files give conflicting guidance, in which case Claude may pick one arbitrarily. If the instruction must run every time without exception, it belongs in a hook, which executes as a shell command regardless of what Claude decides.
Do @path imports reduce context usage?
No. Imports help you organize a large instruction set across files, but imported content is expanded and loaded into context at launch alongside the CLAUDE.md that references it. The context cost is identical. The only mechanism that keeps instructions out of context until they're relevant is a path-scoped rule in .claude/rules/ with a paths field in its frontmatter.
What's the difference between CLAUDE.md and auto memory?
You write CLAUDE.md; Claude writes auto memory. CLAUDE.md holds instructions and rules you want applied every session. Auto memory holds learnings Claude accumulates from your corrections, stored per repository and loaded from a MEMORY.md index. Both load at the start of every session, and both are context rather than enforced configuration.

Muhammad Kashif

Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.