CLAUDE.md Best Practices: What to Put In, What to Leave Out
CLAUDE.md is the file Claude Code reads at the start of every session, and it is the highest-leverage two hundred lines in your repo. It is also the file people most reliably get wrong, usually by treating it as a dumping ground for everything they ever wanted Claude to know. This article covers where the files live, what actually belongs in them, and the habits that keep them working. Facts verified against the Claude Code docs as of August 2026.
The one-sentence rule
CLAUDE.md is for facts Claude should hold in every session. Everything else goes somewhere that loads on demand.
Build commands, project layout, naming conventions, "always do X" rules: those are every-session facts. A twelve-step release procedure is not; it belongs in a skill that loads when you release. This single distinction fixes most bloated CLAUDE.md files we see.
Where the files live and how they load
Claude Code reads instruction files from four scopes, loaded from broadest to most specific, so project instructions land in context after user instructions:
| Scope | Path | Who it affects |
|---|---|---|
| Managed policy | e.g. /Library/Application Support/ClaudeCode/CLAUDE.md (macOS), /etc/claude-code/CLAUDE.md (Linux) | Everyone in the org, deployed by IT |
| User | ~/.claude/CLAUDE.md | You, in every project |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | Everyone who clones the repo |
| Local | ./CLAUDE.local.md | You, in this project only |
Two details worth knowing:
CLAUDE.local.mdis current, not deprecated. It loads right after the projectCLAUDE.mdand is meant for personal, per-project preferences. Add it to.gitignore.- Subdirectory CLAUDE.md files load lazily. Files in directories above where you launched load at startup. A
CLAUDE.mddeeper in the tree loads only when Claude actually reads files in that directory. This makes per-package instructions in a monorepo nearly free.
Run /context in a session to see exactly which memory files loaded. When an instruction seems to be ignored, this is the first thing to check: half the time the file never loaded at all.
Keep it under 200 lines
The official guidance is to target under 200 lines per CLAUDE.md file. This is not just about token cost. Adherence drops as instruction files grow, because every marginal rule dilutes attention on the rules that matter. A short file where every line earns its place beats a complete one.
The practical test we use: if you cannot say what would break when a given line is deleted, delete it.
Be specific or don't bother
Vague instructions produce vague compliance. The docs' own example of the difference is the right one:
| Weak | Strong |
|---|---|
| Format code nicely | Use 2-space indentation |
| Write good tests | New code needs a failing test first; run npm test -- --watch=false |
| Be careful with the database | Never write migrations by hand; use npm run db:migration |
An instruction is specific enough when a new teammate could follow it without asking a clarifying question. That is the standard, because CLAUDE.md is onboarding documentation that happens to be read by a model.
A skeleton that works
Most of our project files follow this shape:
# Project name
One paragraph: what this is and the one architectural fact
that prevents the most wrong assumptions.
## Commands
- Build: `npm run build`
- Test: `npm test` (single file: `npm test -- path/to/file`)
- Lint: `npm run lint:fix`
## Layout
- `src/api/` - route handlers, one file per resource
- `src/lib/` - shared logic, no framework imports allowed here
- `migrations/` - generated only, never hand-edited
## Rules
- TypeScript strict mode; no `any` without a comment explaining why
- Never commit directly to main
- UI copy lives in `src/strings.ts`, never inline
Commands, layout, rules. Facts, not procedures.
Imports: split without losing the thread
CLAUDE.md supports an import syntax: @path/to/file anywhere in the file pulls that file's contents in, up to four hops deep. Relative paths resolve relative to the file containing the import, and home-directory paths like @~/.claude/my-preferences.md work too.
See @README.md for the project overview.
- Git workflow: @docs/git-instructions.md
Imports inside backticks or fenced code blocks are ignored, so you can mention @README literally by wrapping it in backticks. Imports that resolve outside the working directory trigger an approval dialog the first time, which is the right paranoia.
Use imports sparingly. They are great for pulling in a genuinely shared document (a style guide used by humans and Claude alike). They are a smell when used to hide length: four imported files of 150 lines are still 600 lines in context.
Generate the first draft, then edit hard
The /init command generates a starting CLAUDE.md by analyzing your codebase, and if one already exists it suggests improvements instead of overwriting. It even reads existing agent configs like .cursorrules and .github/copilot-instructions.md and folds in what is relevant. There is also an interactive multi-phase mode behind the CLAUDE_CODE_NEW_INIT=1 environment variable that proposes CLAUDE.md files, skills, and hooks for review before writing anything.
Treat the generated file as a draft. /init is good at inventorying commands and layout; it cannot know your team's actual rules. The editing pass where you delete generic advice and add the three rules that genuinely bite is where the value is.
/memory lists all your memory files across scopes and opens any of them in your editor, creating it first if needed. It is the fastest path to "add this rule right now" mid-session.
What to move out of CLAUDE.md
The most common failure mode is procedures living where facts should be. If you find any of these in a CLAUDE.md, move them:
- Multi-step task instructions (release process, PR checklist, scaffold steps): move to a skill, which loads only when the task comes up.
- Instructions that only apply to some files (e.g. rules for the legacy package): move to a subdirectory CLAUDE.md or path-scoped rules so they load when relevant.
- Delegation-worthy roles ("when reviewing security, act as..."): move to a subagent with its own system prompt and tool limits.
After the move, the main file gets shorter and both halves work better: the standing facts get more attention, and the procedure arrives with full detail exactly when needed.
Maintenance
Instruction files rot. Two habits keep them honest:
- When Claude does the wrong thing twice, write the rule. Once is noise; twice is a missing instruction. Add it while the failure is fresh.
- Review on rule collisions. Contradictory instructions across user, project, and local files produce confusing behavior, and you will not notice without occasionally reading the files together.
/memorymakes the full set easy to audit.
FAQ
Should CLAUDE.md be committed to version control?
The project CLAUDE.md: yes, it is team documentation. CLAUDE.local.md: no, that is the file's entire purpose; add it to .gitignore and keep personal preferences there.
How is CLAUDE.md different from a skill?
CLAUDE.md loads every session and should carry standing facts. Skills load on demand and should carry procedures. If your CLAUDE.md is over 200 lines, the overflow is usually procedures wearing a facts costume.
Does a subdirectory CLAUDE.md override the root one?
They stack rather than override: broader scopes load first, more specific ones after. Subdirectory files below your working directory load on demand when Claude works with files there, which is exactly what you want in a monorepo.
What if an instruction keeps being ignored?
Check /context to confirm the file loaded, then make the instruction more specific and more prominent. Vague rules buried at line 180 of a long file lose; concrete rules near the top of a short file win.