If you have used Claude Code for more than a week, you have a CLAUDE.md. If you have used it for six months, your CLAUDE.md is probably 600 lines, and nobody on your team is reading it -- the agent included.

This is a practical guide to writing one that earns its place. It covers what the file is, where it lives, how the global file layers with the project file, the augment-vs-fresh distinction that controls what gets loaded, and the four traps that quietly turn a useful file into noise. It is excerpted shape from Claude Code in Production -- Chapter 2 is the long version, with the rule-layering pattern and the worked examples.

What CLAUDE.md actually is

CLAUDE.md is a markdown file Claude Code reads on startup and pins into the system prompt for every turn. There are two of them, and they layer:

Both get concatenated into the system prompt every turn. Both count against your context window every turn. The cost is paid before the user types anything.

What to put in it

The good test is: would the agent get this wrong without it? If yes, write it down. If no, the file is just paying tokens for nothing.

Things worth writing:

What to leave out

The most common mistake is treating CLAUDE.md as documentation. It is not. It is the agent's permanent priming -- every line in it is paid every turn. Anything the agent can discover by reading the code, looking at the directory structure, or running one cheap tool call does not belong here.

Things to leave out:

The four traps

1. The 600-line CLAUDE.md trap

Every rule you add makes the existing rules less load-bearing. At line 200 the agent is still tracking each rule individually. At line 600 the rules blur into a vibe -- "the user cares about quality and discipline" -- which is approximately what you'd get without the file at all. Worse, the rules near the end of the file get measurably less attention than the rules at the top.

The fix is layering: keep CLAUDE.md as an index of pointers, and put the actual rule bodies in separate files the agent loads via @./rules/<name>.md references. The index stays scannable; the bodies stay editable; the agent loads each rule with its own context boundary. Chapter 2 of Claude Code in Production has the worked pattern.

2. The stale-rule trap

You write "the auth module is at src/auth/" in CLAUDE.md. Six weeks later someone moves it to src/lib/auth/. The agent now confidently looks in the wrong place, and the wrongness has a stale rule backing it up.

The fix is to write rules that point at concepts, not paths. "Authentication code is centralized; grep for authenticate( to find it" survives a refactor. "Auth is at src/auth/" does not.

3. The contradiction trap

Global says "always run tests before pushing." Project says "tests are slow; skip them and let CI catch failures." The agent now has to pick a side, and which side it picks depends on which rule appears later in the concatenated prompt -- which depends on platform, on Claude Code version, on whether you are in augment or fresh mode.

The fix is to detect contradictions on purpose. When a project rule overrides a global rule, say so out loud: "Project override: tests are run in CI, not locally. The global 'run tests before pushing' rule does not apply in this repo." The agent can follow that. The silent contradiction it cannot.

4. The augment-vs-fresh trap

Yaw Mode and similar overlays distinguish between augment mode (your ~/.claude/CLAUDE.md layers under the overlay's rules) and fresh mode (only the overlay's rules apply; your personal CLAUDE.md is ignored). If you have a critical safety rule in your personal CLAUDE.md and run in fresh mode, that rule is not loaded. Same agent, same prompt, different rule set, different behavior. The agent will not warn you.

The fix is to know which mode you are in (check $YAW_MODE or the equivalent in your overlay) and to put load-bearing safety rules in a place that survives a mode switch -- typically the project CLAUDE.md or an overlay rule, not your personal global file.

A minimal CLAUDE.md that earns its place

For a typical project, a good CLAUDE.md is around 30-80 lines. Something like:

# <project name> ## Commands - Test: `pnpm vitest` - Lint: `pnpm lint:fix` (run before every commit -- Biome diffs break CI) - Build: `pnpm build` - Deploy: `./deploy.sh` (never `netlify deploy` directly -- see deploy.sh:1) ## Constraints - Never push to main; PRs only. - Forward-only migrations. No `DROP COLUMN` without a deprecation cycle. - Secrets live in 1Password, never in env files in git. ## Decisions worth knowing - CloudFormation over Terraform (see `docs/iac-choice.md` for why). - Tests live next to their source as `*.test.ts`, not in `__tests__/`. - Auth is centralized; grep for `authenticate(` to find it.

That file pays its tokens. It is scannable in 20 seconds. Each rule prevents something specific the agent would otherwise get wrong. It does not pretend to be documentation.

Want the rest?

This is the surface. Claude Code in Production covers the rule-layering pattern in depth, the hook system that mechanically enforces what CLAUDE.md only suggests, the per-project settings.json contract that pins model and effort, the seven failure modes the discipline catches before they ship, and the eleven other chapters on subagents, memory, capacity, scope, and what survives the move from solo to a team.

Claude Code in Production

The Claude Code book and practitioner's guide. Twelve chapters. PDF + EPUB. Free updates as the surface area moves. $39 one-time, secure checkout.

Read more & buy $39

Published by Yaw Labs.

Related