The tell that you need one
You correct the same thing twice. You explain the folder layout again. You say “we use pnpm, not npm” for the third session running.
Every Claude Code session begins with a fresh context window. Nothing carries over on its own. CLAUDE.md is the file it reads at the start of every session, so anything in there is something you never have to type again.
Write it down the second time, not the fifth.
Good triggers: Claude makes the same mistake twice, a code review catches something it should have known, or a new teammate would have needed the same explanation.
01 · Let it write the first draft
Do not start from a blank file. Inside your project, run:
/init
It reads the codebase and writes a starting CLAUDE.md with the build commands, test commands and conventions it can find. If one already exists, /init suggests improvements instead of overwriting it.
Then refine by hand. The useful half is what it could not discover on its own: why things are the way they are, and the rules that differ from the tool defaults.
02 · Where the file goes
There are four places, and they all load — broadest first, so the most specific instruction is the last thing read.
| Scope | Location | For |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS)/etc/claude-code/CLAUDE.md (Linux, WSL) | org-wide rules pushed by IT |
| User | ~/.claude/CLAUDE.md | your preferences, every project |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | the team's rules, committed to git |
| Local | ./CLAUDE.local.md | your own notes for this project — gitignore it |
Files in directories above your working directory load at launch too, root-down. Files in subdirectories load on demand, when Claude reads something in that folder. To see what actually loaded in this session, run /context and look under Memory files.
03 · What to write in it
Facts that should hold in every session: build and test commands, project layout, naming conventions, the “always do X” rules.
Specific beats tidy. Instructions you can verify get followed; vague ones get ignored.
“Use 2-space indentation”
“Run npm test before committing”
“API handlers live in src/api/handlers/”
“Format code properly”
“Test your changes”
“Keep files organised”
- Keep it under about 200 lines. It loads into context every session, so a long file costs tokens and, counter-intuitively, gets followed less closely.
- Use headers and bullets. Claude scans structure the way you do.
- Remove contradictions. If two rules disagree, it may pick either one.
- Multi-step procedures do not belong here — those are skills.
04 · Splitting it up
Two mechanisms, for two different problems.
Imports pull another file in with @path. Good for organisation; it does not save context, because imported files load at launch as well.
See @README for the project overview and @package.json for the npm scripts.
# Additional instructions
- git workflow @docs/git-instructions.md
To mention a path without importing it, wrap it in backticks. @README imports; `@README` stays literal.
Path-scoped rules in .claude/rules/ only enter context when Claude touches a matching file, so they genuinely reduce noise:
---
paths:
- "src/api/**/*.ts"
---
# API rules
- Every endpoint validates its input
- Use the standard error response shape
A rule with no paths field loads every session, same as .claude/CLAUDE.md. Personal rules that apply everywhere go in ~/.claude/rules/.
05 · The memory you don't write
Alongside the file you maintain, Claude keeps notes of its own. Auto memory is on by default, stored per repository on your machine.
your role, expertise, how you like to work
who you arecorrections you gave, approaches you confirmed
what you told itdecisions and ongoing work it cannot read from the code
what's going onwhere things live outside the repo — tracker, dashboard
where to lookIt deliberately skips anything it could work out from the codebase, and anything your CLAUDE.md already says. Run /memory to browse, edit or delete what it saved — it is all plain markdown — and to toggle the feature off.
{
"autoMemoryEnabled": false
}
06 · When CLAUDE.md is the wrong tool
This is the part people learn the hard way. CLAUDE.md is context, not configuration. Claude reads it and tries to follow it. Nothing enforces it.
If it absolutely must happen, it is not an instruction — it is a hook.
“Never edit .env” in CLAUDE.md is a request. The same rule as a PreToolUse hook is enforced by your machine, whatever the model decides.
Same for anything that must run at a fixed moment — before every commit, after every edit. That is a lifecycle event, not a note.
Troubleshooting
- It is ignoring the file. Run
/contextfirst — if it is not listed under Memory files, it never loaded, and the problem is the location, not the wording. - It is too big. Over ~200 lines adherence drops. Move sections into path-scoped rules so they load only when relevant.
- Instructions vanished after
/compact. The project-root CLAUDE.md is re-read from disk after compaction. Anything you only said in conversation is not — which is the argument for writing it down. - Rules contradict each other. Review the whole chain: user, project, nested, and
.claude/rules/.
Verified against the official Claude Code documentation, September 2026. Claude Code moves quickly, so check the official documentation before relying on a detail here.