Appearance
Text size
Typeface
Line spacing
2
Chapter 2 · 4 min

What belongs in CLAUDE.md

CLAUDE.md is context that Claude reads, not configuration that Claude obeys. Write only what the code cannot tell it, keep it short, and move hard rules to hooks.


Context, not configuration

A CLAUDE.md file is plain markdown that Claude reads at the start of every session. It is treated as context. It is not enforced. If a line there says "never touch the migrations folder", Claude will usually follow it, and nothing will stop it on the day it does not.

The official guide draws the line clearly. Some things are Claude's judgment: prompts, CLAUDE.md. Some things are enforced by the harness: hooks, deny rules, the sandbox. Use the second kind for rules that have no exceptions.

That one distinction decides most of what you should and should not write.

What goes in

The test the guide gives before you add any line: could Claude find this by reading the code, and would it actually go look? If both answers are yes, leave the line out.

What is left is a short list:

  • The exact test, typecheck and lint commands.
  • Code areas that mislead, where the obvious reading is wrong.
  • Decisions made outside the repo that the code cannot show.
  • Anything you have corrected twice.
## Commands
- Test one file: `pnpm vitest run path/to/file.test.ts`
- Typecheck: `pnpm tsc --noEmit`

## Careful
- `src/billing/legacy/` looks unused but the invoice export depends on it.
- Use 2-space indentation.

Notice that "use 2-space indentation" can be checked, and "format nicely" cannot. Verifiable lines work better than vague ones.

Check yourself

Which line earns a place in CLAUDE.md?

Where files load from

The order runs from broad to specific, so the text read last is the most specific:

Managed policy CLAUDE.md
~/.claude/CLAUDE.md
Project ./CLAUDE.md or ./.claude/CLAUDE.md
./CLAUDE.local.md

Files are concatenated. A later file does not override an earlier one, it is simply added after it. Claude also walks up from the launch directory and loads every CLAUDE.md above it. Files in subdirectories below the launch directory load lazily, when Claude reads or edits a file there.

CLAUDE.local.md is for your personal notes on a project, and should be gitignored. /init writes a starting file for you.

Length is a cost

Keep each file under about 200 lines. This is not tidiness. The whole file is loaded into every session, so every line is paid for on every turn, as the first lesson showed.

There is also an effect on obedience. The guide says that when a line keeps being ignored, adding emphasis rarely helps. Either the file is too long, so the line is lost in it, or the rule has no exceptions and belongs in a hook.

Small things worth knowing

  • A path wrapped in backticks, like @README, is not imported. Import parsing skips code spans and fenced blocks.
  • Editing CLAUDE.md in the middle of a session does not change that session. The new text loads after /clear, /compact or a restart.
  • If a repo has only an AGENTS.md, Claude Code reads it. If both exist, only CLAUDE.md is read unless CLAUDE.md imports AGENTS.md.
  • /doctor prompt-audit checks instruction files for stale or contradicting content.
Check yourself

A rule in CLAUDE.md is ignored again and again, and it has no exceptions. What is the better fix?

Read further