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 test before 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:

  1. Run /context and check Memory files. If a file is missing there, Claude can’t see it. Run /memory to list and open memory files.
  2. A CLAUDE.md in a subdirectory is not listed at launch; a Loaded line 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.
  3. Check the file sits in a location that loads for your session.
  4. Make vague instructions specific, and look for contradictions across files.
  5. Log what loads and why with the InstructionsLoaded hook.

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

  1. Run /context and confirm the CLAUDE.md files you expect appear under Memory files.
  2. Cut every line that fails the test “would removing this cause mistakes?”; aim for under 200 lines per file.
  3. Rewrite vague rules as checkable ones (commands, paths, exact values).
  4. Move multi-step procedures to a skill and part-of-codebase rules to .claude/rules/ with paths.
  5. Turn “must happen every time” rules into hooks, and “must never happen” rules into permission denies.
  6. Remove contradictions between user, project, local and nested files.
  7. 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.