CLAUDE.md best practices: write a lean file Claude follows
CLAUDE.md best practices checked against the official Claude Code docs: where it lives, what to include, how long it should be, and what to move elsewhere.
A good CLAUDE.md is short, specific and limited to what Claude cannot work out from your code. These CLAUDE.md best practices come from two official pages, How Claude remembers your project and Best practices for Claude Code, both read on 2026-10-10; Anthropic’s overview Using CLAUDE.md files covers the same ground at a higher level. Behaviour and version requirements change between releases, so confirm against the current docs.
What CLAUDE.md is and how Claude Code loads it
Each Claude Code session starts with a fresh context window. CLAUDE.md files are markdown files you write to carry persistent instructions across sessions; auto memory is the separate mechanism where Claude writes its own notes. Both load at the start of every conversation.
The key point from the docs: Claude treats CLAUDE.md as context, not enforced configuration. The content is delivered as a user message after the system prompt, so there is no guarantee of strict compliance, especially for vague or conflicting instructions (troubleshooting section).
Where CLAUDE.md files live (user, project, subdirectory) and which one wins
The memory docs list four scopes, in load order from broadest to most specific:
| Scope | Location | Shared with |
|---|---|---|
| Managed policy | /etc/claude-code/CLAUDE.md (Linux and WSL); other OS paths in the docs |
All users in the organization |
| User | ~/.claude/CLAUDE.md |
Only you, all projects |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md |
Team, via source control |
| Local | ./CLAUDE.local.md |
Only you, current project |
There is no single “winner”. Per How CLAUDE.md files load, all discovered files are concatenated into context rather than overriding each other. Files from the filesystem root down to your working directory are ordered so that instructions closest to where you launched Claude are read last. Within a directory, CLAUDE.local.md is appended after CLAUDE.md. Files in subdirectories load on demand, once Claude reads, writes or edits a file there. If two files contradict each other, Claude may pick one arbitrarily, so keep them consistent.
If your repository uses AGENTS.md, the docs describe separate rules: by default Claude reads it only when there is no CLAUDE.md or CLAUDE.local.md in your working directory or above it, and reading it directly requires Claude Code v2.1.277 or later.
What to put in CLAUDE.md, and what to leave out
The best practices page gives a test for each line: “Would removing this cause Claude to make mistakes?” If not, cut it. Its include/exclude table, condensed:
| Include | Exclude |
|---|---|
| Bash commands Claude can’t guess | Anything Claude can figure out by reading code |
| Code style rules that differ from defaults | Standard language conventions Claude already knows |
| Test instructions and preferred test runners | Detailed API documentation (link to it instead) |
| Branch naming and PR conventions | Information that changes frequently |
| Project-specific architectural decisions | Long explanations or tutorials |
| Required environment variables and quirks | File-by-file descriptions of the codebase |
| Non-obvious gotchas | Self-evident advice like “write clean code” |
A small example in the style the docs use:
# Code style
- Use ES modules (import/export) syntax, not CommonJS (require)
# Workflow
- Typecheck after a series of code changes
- Prefer running single tests, not the whole suite
Run /init to generate a starting file; per the memory docs, Claude analyzes the codebase and proposes build commands and conventions, and if a CLAUDE.md already exists it suggests improvements instead of overwriting it.
Keep it short: size, structure and specific instructions
The memory docs recommend targeting under 200 lines per CLAUDE.md file, grouping related instructions under markdown headers and bullets, and writing instructions concrete enough to verify:
- “Use 2-space indentation” instead of “Format code properly”
- “Run
npm testbefore committing” instead of “Test your changes” - “API handlers live in
src/api/handlers/” instead of “Keep files organized”
The best practices page warns that an over-long file gets rules lost in the noise. If one instruction keeps getting skipped, it suggests adding emphasis such as “IMPORTANT” to that line alone; emphasizing many lines makes none stand out. To audit existing files, the memory docs describe /doctor prompt-audit, which flags outdated instructions, references to files or commands that don’t exist, and contradictions; it requires v2.1.283 or later and changes nothing until you ask Claude to apply the edits.
Imports and splitting a long file
CLAUDE.md can import other files with @path/to/import. Relative paths resolve from the file containing the import, and imports can nest to a maximum depth of four hops:
See @README for project overview and @package.json for npm commands.
# Additional Instructions
- git workflow @docs/git-instructions.md
Imports organize a file but do not save context: imported files load at launch alongside the importing file. To actually reduce load, use path-scoped rules in .claude/rules/, whose paths frontmatter loads them only when Claude works with matching files. The docs also note that block-level HTML comments in CLAUDE.md are stripped before injection, so they are free notes for maintainers.
CLAUDE.md, skills, hooks or permissions: which tool for which job
| Need | Use | Why (per the docs) |
|---|---|---|
| Facts for every session: commands, conventions, layout | CLAUDE.md | Loaded at the start of every session |
| Multi-step procedure or knowledge needed sometimes | A Claude Code skill | Skills load on demand when invoked or judged relevant |
| Something that must run every time (format, check, notify) | Claude Code hooks | Hooks are deterministic; CLAUDE.md instructions are advisory (best practices) |
| Hard block of a tool, command or path | permissions.deny in settings |
The memory docs: settings are enforced by the client, CLAUDE.md is not a hard enforcement layer |
The memory docs say it directly: to block an action regardless of what Claude decides, use a PreToolUse hook rather than a CLAUDE.md instruction.
Check that Claude actually follows it (debugging with /memory)
The troubleshooting steps in the memory docs:
- Run
/contextand check Memory files. If a file is missing there, Claude can’t see it. Run/memoryto list and open memory files. - A CLAUDE.md in a subdirectory is not listed at launch; a
Loadedline with its path appears when it loads. To test one, create it from your shell, then ask Claude to read a file in that subdirectory. - Check the file sits in a location that loads for your session.
- Make vague instructions specific, and look for contradictions across files.
- Log what loads and why with the
InstructionsLoadedhook.
After /compact, the docs say the project-root CLAUDE.md is re-read from disk and re-injected. An instruction you gave only in conversation does not survive, so add it to CLAUDE.md if it should persist.
What to change in your setup
- Run
/contextand confirm the CLAUDE.md files you expect appear under Memory files. - Cut every line that fails the test “would removing this cause mistakes?”; aim for under 200 lines per file.
- Rewrite vague rules as checkable ones (commands, paths, exact values).
- Move multi-step procedures to a skill and part-of-codebase rules to
.claude/rules/withpaths. - Turn “must happen every time” rules into hooks, and “must never happen” rules into permission denies.
- Remove contradictions between user, project, local and nested files.
- Run
/doctor prompt-audit(v2.1.283 or later) and review the proposed edits.
FAQ
- Where should I put CLAUDE.md?
- For a team project, in ./CLAUDE.md or ./.claude/CLAUDE.md, committed to version control. Personal preferences for all projects go in ~/.claude/CLAUDE.md, and personal project-specific notes go in ./CLAUDE.local.md, which you add to .gitignore.
- How long should a CLAUDE.md be?
- The memory docs say to target under 200 lines per CLAUDE.md file, because longer files consume more context and reduce adherence. Imports help organization but do not reduce context cost, since imported files also load at launch.
- Is CLAUDE.md enforced?
- No. Claude treats it as context, not enforced configuration. To block or force an action regardless of what Claude decides, use a hook or a permission rule.
- How do I check that my CLAUDE.md loaded?
- Run /context and look under Memory files. Run /memory to list and open the memory files. A CLAUDE.md in a subdirectory loads on demand, so it does not appear there at launch.