Where it goes, and what actually loads
Claude Code loads CLAUDE.md and CLAUDE.local.md from your current working directory and every directory above it. Launch in foo/bar/ and it loads foo/bar/CLAUDE.md, foo/CLAUDE.md, and any CLAUDE.local.md alongside them.
They are concatenated, not overridden — which surprises people who expect the nearest file to win. Content is ordered from the filesystem root down to your working directory, so foo/CLAUDE.md appears before foo/bar/CLAUDE.md, and within a directory CLAUDE.local.md is appended after CLAUDE.md. Your personal notes are the last thing Claude reads at that level.
Files in subdirectories below your working directory behave differently: they are not loaded at launch, only when Claude reads a file in that subdirectory. That is what makes per-package instructions in a monorepo affordable — you are not paying for every package's rules on every session.
your-project/ ├── .claude/ │ ├── CLAUDE.md main project instructions │ └── rules/ │ ├── testing.md loaded every session │ ├── api-design.md loaded every session │ └── frontend.md path-scoped: only when touched ├── CLAUDE.local.md yours, gitignored └── AGENTS.md the portable baseline
Keep it short — and the comment trick
Everything in a CLAUDE.md is in context for the whole session, competing with your actual code for the model's attention. A page that is entirely load-bearing beats ten pages where the agent has to work out which parts still apply.
The test: if you have explained something to the agent more than twice, write it down. If you have never needed to explain it, leave it out. "Write clean, readable code" costs tokens and changes nothing.
Split it with .claude/rules/
Once a CLAUDE.md is long enough to scroll, move topics into .claude/rules/ as separate Markdown files — one topic per file, with descriptive names like testing.md or security.md. All .md files are discovered recursively, so subdirectories like frontend/ and backend/ work.
Rules without frontmatter load at launch with the same priority as .claude/CLAUDE.md. The gain is organisational, not yet a context saving.
The context saving comes from path scoping. A rule with a paths field in its YAML frontmatter only loads when Claude is working with matching files:
--- paths: - "src/api/**/*.ts" --- Every route returns AppError with a machine code, never a bare string. Validate at the boundary with the shared zod schemas, not inline.
That rule costs nothing on a session spent in the frontend. On a large codebase this is the difference between instructions that stay sharp and a preamble so long the model skims it.
Imports, and their limits
A CLAUDE.md can pull in other files with @path syntax. Imported files are expanded and loaded at launch alongside the file that references them. Relative paths resolve against the file containing the import, not your working directory — the usual cause of an import that works from the repo root and breaks from a subdirectory.
See @README for the project overview and @package.json for the available npm commands. @AGENTS.md # Claude-specific notes Only guidance that is meaningless in another tool belongs below here.
Two limits worth knowing before you build a structure on this. Imports recurse to a maximum depth of four hops, so a chain of files each importing the next stops being loaded at the fifth. And import parsing skips Markdown code spans and fenced blocks — so to mention a path without importing it, wrap it in backticks. Outside backticks, @README imports the file.
Monorepos and extra directories
In a large monorepo, other teams' CLAUDE.md files on the path above you get picked up along with your own. claudeMdExcludes takes paths or globs and skips them, which is the difference between useful shared context and four teams' conventions arguing in one window.
Worth knowing about --add-dir: by default, CLAUDE.md files in additional directories are NOT loaded. If you want them, set CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1, which pulls in that directory's CLAUDE.md, .claude/CLAUDE.md, .claude/rules/*.md and CLAUDE.local.md.
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared-config
The limit nobody mentions
Anthropic's documentation is unusually direct about this, and it is the most important sentence on the subject: Claude treats these files as context, not enforced configuration. The agent weighs your instructions against everything else in the session and can decide otherwise.
So a CLAUDE.md is the right place for conventions, architecture, reasoning and preferences — things where judgement is wanted. It is the wrong place for anything that must hold every time.
For those, use something mechanical. A PreToolUse hook blocks an action regardless of what the model decides. A test fails. A lint rule fails. CI refuses the merge. "Never edit the generated schema file" in prose is a strong hint; the same rule as a hook is a guarantee.
Run that in a fresh session after any change to the setup. If the paths are not what you expected, or a rule you care about is missing, you have found the problem in one message rather than after an afternoon of odd behaviour.
Common questions
Does a nested CLAUDE.md override the one above it?
No. All discovered files are concatenated rather than overriding each other, ordered from the filesystem root down to your working directory. The nearer file is read last, which gives it recency but not authority — if two files genuinely contradict, the agent may pick either. Remove the contradiction rather than relying on position.
CLAUDE.md or .claude/rules/ — which should I use?
Start with CLAUDE.md. Move to .claude/rules/ when it is long enough that you scroll to find things, or when a set of conventions only matters for part of the codebase. Rules without paths frontmatter load every session at the same priority as .claude/CLAUDE.md; rules with it load only when Claude touches matching files, which is where the context saving actually comes from.
Should CLAUDE.md be committed?
Yes — it is project documentation and the value is that everyone's agent follows the same conventions. Keep personal preferences in CLAUDE.local.md, which is meant to be gitignored. One caution: CLAUDE.local.md suppresses a shared AGENTS.md for you alone, so if your project relies on one, set Project instructions to claude-md-and-agents-md.
How long should it be?
Shorter than feels right. Every line competes for attention with your code, and stale lines actively mislead. Put rationale and maintainer notes in HTML comments, which are stripped before the file reaches the model and therefore cost nothing.