Ramiz RajaBook a call
← Writing
Working With AI Agents

CLAUDE.md File: What to Put In It and What to Leave Out

What a CLAUDE.md file costs, what the docs say belongs in it, and the size history of mine: 3,639 words, then 512, then 9,555.

Ramiz RajaOctober 26, 20265 min read
CLAUDE.md File: What to Put In It and What to Leave Out

If Claude Code ignores half of your CLAUDE.md file, one possible cause is its length. The file is loaded at the start of every conversation, so each line takes up context every time, and the docs warn that longer files "consume more context and reduce adherence". My answer is to keep only what must hold in every session and link to everything else. I got that wrong in both directions: my file went from 3,639 words to 512, then back to 9,555.

What the docs say a CLAUDE.md file is

Per the official memory documentation, a CLAUDE.md file holds instructions you write to give Claude persistent context, and it is loaded at the start of every session. Claude treats it "as context, not enforced configuration". The docs' size guidance is to target under 200 lines per file, and to move instructions that matter for only part of the codebase into path-scoped rules.

Files stack by scope: managed policy, then your user file at ~/.claude/CLAUDE.md, then the project file, then CLAUDE.local.md, concatenated rather than overriding each other, per the docs. /init generates a starting file from your codebase.

What belongs in it, and what doesn't

A line earns its place if forgetting it would be wrong in every session: build and test commands, conventions the agent cannot infer, standing rules about who authors commits. Everything else has a better home, per the docs:

InstructionWhere it goesWhy
Must hold every sessionCLAUDE.mdLoaded every time
Applies to certain files onlyPath-scoped rule in .claude/rules/Loads when matching files are opened
Task-specific procedureA skillLoads when invoked
Must never happenA PreToolUse hookCLAUDE.md is context, not enforcement

I wrote about the last two in Claude Code Skills: How to Write Ones Your Agent Actually Uses and Claude Code Hooks: Three I Run Every Day.

The pointer index, with real numbers

The backups of my shared CLAUDE.md are in git, so these are measured with git show <commit>:claude-shared/CLAUDE.md | wc -lw, not remembered. At the first backup it was 185 lines and 3,639 words, with full guides for several tools written inline. Two weeks later it was 28 lines and 512 words: a handful of standing rules plus a pointer index of 8 rows. Each row is one line: a trigger and the file to read when it applies. The intent is that the guide is read only when the task matches. Here is the same move for one topic, with the path anonymised. The heading is from the first backup; the row is from my current index, trigger shortened:

Before (inline, the whole guide under this heading):
# Maestro CLI — multi-agent/parallel usage (ALL Android/iOS projects on this machine)

After (one row in the pointer index):
| A Maestro test run failed or hung | `<shared-dir>/maestro-multi-agent.md` |

Here is the generic shape of a short file with a pointer index (all names are placeholders):

# Standing rules
- Run `npm test` before saying a change is done.
- Never commit secrets; use the `.env.example` pattern.

# Pointer index: read the file only when the trigger applies
| Trigger | Read |
|---|---|
| Changing the database schema | `docs/db-migrations.md` |
| A release build fails | `docs/release-troubleshooting.md` |
| Writing or editing UI copy | `docs/style-guide.md` |

This differs from the docs' @path imports, which are "expanded and loaded into context alongside" the file that references them, up to four hops deep. A pointer is not loaded until the agent decides it needs it. The trade-off is that the agent has to notice the trigger and open the file; an import is loaded without that decision.

Where I broke my own rule

Then I stopped cutting. Three months after the cut, the same file was 723 lines and 9,555 words, with 35 top-level sections. The pointer index itself grew to 29 rows and 977 words. Most of the growth was policy that I added inline each time something went wrong, instead of adding a pointer and a file.

That is far past the docs' under-200-lines target, and I have not measured whether adherence got worse, so I will not claim it did. What I can say is that I stopped following the short-file-plus-pointers pattern I had set up, and the file's growth is a curve I only saw by running wc on old commits.

What I would do differently

Measure the file on a schedule, not when it feels long. Treat a new section as a cost: if it only applies to one kind of task, it should be a pointer and a file, a skill or a rule. And if something must never happen, write the hook. A sentence in CLAUDE.md is a request, and a request is not a check; Don't Trust an Agent That Says the Tests Passed shows what that costs.

A shorter file also costs fewer tokens each session; Claude Code pricing lists the other levers.