Skip to content

How to Write a CLAUDE.md That Claude Actually Follows

Core Concept LearningOctober 18, 202613 min read

A CLAUDE.md file is where you write down what you would otherwise re-explain to Claude Code every session: the build command it cannot guess, the directory where handlers live, the convention that differs from the language default. Claude reads it at the start of every conversation.

The catch is in how it is read. CLAUDE.md is context, not enforced configuration: it arrives as a message after the system prompt, and Claude tries to follow it, with no guarantee. So the quality of the file decides how much it helps. Long, vague, or contradictory files get followed less, and the documentation is direct about it: target under 200 lines per file.

This guide covers what to put in a CLAUDE.md and what to leave out, how to phrase instructions so they can be checked, how files load and combine, when to move content to path-scoped rules, skills, or hooks, how AGENTS.md fits in, and how to debug an instruction Claude ignores. It is based on the Claude Code memory and best-practices documentation. For where every Claude Code configuration file lives, see Claude Code Directory Structure.

Where an instruction belongs: CLAUDE.md for facts needed every session, path-scoped rules for one area, skills for procedures, hooks for what must always happen
Where an instruction belongs: CLAUDE.md for facts needed every session, path-scoped rules for one area, skills for procedures, hooks for what must always happen

What belongs in CLAUDE.md, and what doesn't

The documentation gives a simple trigger for adding a line: Claude makes the same mistake a second time, a code review catches something Claude should have known, you type the same correction you typed last session, or a new teammate would need the same context.

And a simple test for keeping one: for each line, ask "Would removing this cause Claude to make mistakes?" If not, cut it. Directory layouts, dependency lists, and architecture overviews usually fail that test, because Claude can read them from the code; the /doctor checkup proposes exactly those cuts for a checked-in CLAUDE.md, while keeping pitfalls, rationale, and conventions that differ from tool defaults.

A starting file can be generated: /init analyses the codebase and writes build commands, test instructions, and conventions it finds, or suggests improvements if a CLAUDE.md already exists. Treat its output as a draft and delete what Claude would have discovered anyway.

Include and exclude, from the Claude Code best-practices guide
IncludeExclude
Bash commands Claude can't guessAnything Claude can figure out by reading code
Code style rules that differ from defaultsStandard language conventions Claude already knows
Testing instructions and preferred test runnersDetailed API documentation (link to it instead)
Repository etiquette: branch naming, PR conventionsInformation that changes frequently
Architectural decisions specific to your projectLong explanations or tutorials
Developer environment quirks, such as required env varsFile-by-file descriptions of the codebase
Common gotchas that aren't self-evidentSelf-evident practices like "write clean code"

Quick reference

  • Multi-step procedures (how to cut a release, how to add a migration) belong in a skill, which loads only when relevant.
  • Instructions for one part of the codebase belong in a path-scoped rule, so they cost nothing elsewhere.
  • Put personal preferences in ~/.claude/CLAUDE.md or a gitignored CLAUDE.local.md, not in the shared project file.

Remember this

Keep only facts Claude needs every session and cannot derive from the code; cut every line whose removal wouldn't cause a mistake.

Write instructions Claude can check

Because CLAUDE.md is advisory, phrasing matters. The documentation's guidance is to write instructions concrete enough to verify: "Use 2-space indentation" rather than "Format code properly", "Run npm test before committing" rather than "Test your changes", "API handlers live in src/api/handlers/" rather than "Keep files organized".

Here is a typical first draft and a rewrite:

1# Before2- Write clean, well-tested code3- Follow our coding standards4- Be careful with the database5- The project uses React and TypeScript
1# Commands2- Typecheck: `npm run typecheck`; run it after a series of edits3- Single test file: `npm test -- path/to/file.test.ts` (the full suite takes minutes)4 5# Conventions6- Named exports only; no default exports in `src/`7- Dates are stored as UTC ISO strings; convert only in the UI layer8 9# Gotchas10- Never edit files in `migrations/` by hand; generate them with `npm run db:migration`11- `.env.example` must list every new environment variable

Each line in the rewrite is one action Claude can take or a fact it can check, and the vague lines are gone: "write clean code" adds nothing, and "uses React and TypeScript" is visible from package.json.

Structure helps too: group related instructions under headers and bullets rather than paragraphs. If one rule keeps being skipped, the documentation suggests emphasis such as "IMPORTANT" on that line alone; emphasise many lines and none stands out.

Rewriting vague instructions as checkable ones
Rewriting vague instructions as checkable ones

Quick reference

  • If Claude asks questions your CLAUDE.md already answers, the phrasing is ambiguous; rewrite the line rather than adding another.
  • State the command, not the intent: npm run lint -- --fix beats "fix lint errors".
  • Say why for non-obvious rules in a few words; it helps Claude apply the rule to cases you didn't list.

Remember this

Write one verifiable action or fact per line, grouped under headers, and reserve emphasis for the single rule that keeps being missed.

How CLAUDE.md files load and combine

CLAUDE.md files can live at four scopes, loaded from broadest to most specific:

  • Managed policy: an organisation-wide file installed by IT (for example /etc/claude-code/CLAUDE.md on Linux).
  • User: ~/.claude/CLAUDE.md, your preferences across all projects.
  • Project: ./CLAUDE.md or ./.claude/CLAUDE.md, shared through version control.
  • Local: ./CLAUDE.local.md, your personal notes for this project; add it to .gitignore.

Claude Code loads CLAUDE.md and CLAUDE.local.md from the working directory and every directory above it at launch. The files are concatenated, not overridden: content runs from the filesystem root down to your working directory, and within each directory the local file comes after CLAUDE.md. Files in subdirectories load on demand, when Claude reads, writes, or edits a file in that subdirectory.

Two consequences matter in practice. First, a contradiction between files is not resolved by precedence: the documentation warns that Claude may pick one arbitrarily, so remove conflicts rather than relying on the more specific file to win. Second, the project-root CLAUDE.md survives /compact, because Claude re-reads it from disk; instructions given only in conversation do not, so anything you want to persist belongs in the file.

Block-level HTML comments (<!-- note for maintainers -->) are stripped before the content reaches Claude, so you can leave notes for humans at no context cost.

CLAUDE.md load order: managed, user, then project files from the root down to the working directory, each local file after its CLAUDE.md; subdirectory files load on demand
CLAUDE.md load order: managed, user, then project files from the root down to the working directory, each local file after its CLAUDE.md; subdirectory files load on demand

Quick reference

  • Run /context and check Memory files to see exactly which files loaded at launch; use /memory to open and edit them.
  • In large monorepos, claudeMdExcludes skips other teams' CLAUDE.md files that would otherwise load from parent or sibling paths.
  • A gitignored CLAUDE.local.md exists only in the worktree where you created it; import a file from your home directory to share personal notes across worktrees.

Remember this

All applicable files are concatenated from root to working directory, subdirectory files load on demand, and conflicts are not resolved for you.

Imports, path-scoped rules, and when to move content out

Imports pull other files into a CLAUDE.md with @path syntax. Relative paths resolve from the file that contains the import, imports can nest up to four hops, and the first time a project imports a file from outside the working directory Claude Code asks you to approve it. Imports help organise a long file but do not reduce its context cost: imported files load at launch too.

1See @README.md for the project overview and @package.json for npm scripts.2 3# Git workflow4- @docs/git-instructions.md

Wrap a path in backticks to mention it without importing it.

Path-scoped rules are the tool that does reduce cost. Put a markdown file in .claude/rules/ with paths frontmatter, and it loads only when Claude works with a matching file:

1---2paths:3  - "src/api/**/*.ts"4---5 6# API rules7- Validate every request body with the shared Zod schemas in `src/api/schemas/`8- Return errors in the `{ error: { code, message } }` shape

Rules without paths load at launch like the project CLAUDE.md. paths is the only frontmatter field rules read.

Move content out of CLAUDE.md when it matches one of these patterns: it applies to one area of the code (path-scoped rule), it is a procedure or domain knowledge needed only sometimes (a skill, which loads when relevant), or it must happen every time without exception (a hook).

Quick reference

  • If a rule's YAML frontmatter fails to parse, Claude Code loads the rule without paths, so it applies everywhere; claude --debug shows the error.
  • User-level rules in ~/.claude/rules/ apply to all your projects.
  • Splitting a 600-line file into imports changes nothing for Claude; splitting it into path-scoped rules and skills does.

Remember this

Imports organise but still load at launch; path-scoped rules and skills are how you cut what Claude reads every session.

CLAUDE.md and AGENTS.md

Many repositories already have an AGENTS.md for other coding agents. Recent Claude Code versions read it directly, with a simple default:

  • An AGENTS.md and no CLAUDE.md or CLAUDE.local.md in your working directory or above: Claude reads the AGENTS.md.
  • An AGENTS.md and a project CLAUDE.md or CLAUDE.local.md: Claude reads only the CLAUDE.md files.
  • A CLAUDE.md that imports AGENTS.md: Claude reads both, through the import.

Your ~/.claude/CLAUDE.md, the managed file, and .claude/rules/ don't count for that check and load alongside AGENTS.md. The Project instructions setting in /config changes the default, for example to read both.

The trap is CLAUDE.local.md: creating one for personal notes in an AGENTS.md-based repository stops Claude from reading the AGENTS.md. The portable pattern for teams that use several tools is one shared file plus a thin CLAUDE.md:

1@AGENTS.md2 3# Claude Code only4- Use plan mode for changes under `infra/`

Quick reference

  • Reading AGENTS.md directly needs a recent Claude Code version; in sessions where it isn't supported, the import pattern still works.
  • AGENTS.local.md, AGENTS.override.md, and .agents/ directories are not read.
  • Run /memory to confirm which instruction files Claude actually read.

Remember this

By default Claude reads AGENTS.md only when no project CLAUDE.md exists; a CLAUDE.md that imports AGENTS.md works everywhere.

Debugging an instruction Claude ignores

When Claude doesn't follow a line, work through the causes in order:

1. Did the file load? Run /context and look under Memory files. A subdirectory CLAUDE.md won't appear there because it loads on demand; a Loaded line appears in the terminal when it does. The InstructionsLoaded hook can log which files and rules load, and why. 2. Is the line specific? Rewrite it as a single checkable action. 3. Does something contradict it? Check other CLAUDE.md files, .claude/rules/, and Claude Code's own built-in guidance: if your file sets commit or pull request rules, the documentation suggests turning off the built-in ones with includeGitInstructions and setting attribution. 4. Is the file too long? Over about 200 lines, rules get lost; Claude Code warns at startup when a file, or the combined set, is too large. /doctor prompt-audit (in recent versions) reports outdated, missing-file, and contradictory instructions and proposes edits without changing anything until you ask. 5. Must it always happen? Then CLAUDE.md is the wrong tool. Write a hook: hooks run as commands at fixed lifecycle events, regardless of what Claude decides. To block an action outright, use a PreToolUse hook.

Test changes the way you would test code: start a fresh session, give a task that should trigger the instruction, and see whether behaviour changes.

Debugging an ignored instruction: confirm the file loaded, make the line specific, remove conflicts, shorten the file, then decide whether it must always happen
Debugging an ignored instruction: confirm the file loaded, make the line specific, remove conflicts, shorten the file, then decide whether it must always happen

Quick reference

  • If you need an instruction at the system-prompt level for scripts, --append-system-prompt passes it at launch.
  • When testing a new subdirectory CLAUDE.md, create it from your shell rather than asking Claude to write it, then have Claude read a file there.
  • An instruction that vanished after /compact was probably given only in chat, or lives in a nested file or path rule that hasn't reloaded yet.

Remember this

Confirm it loaded, make it specific, remove conflicts, shorten the file, and move must-always rules to hooks.

Hands-on: rewrite your CLAUDE.md

Use a repository you work in daily.

1. Run /context and record which memory files load and how long each is. 2. Apply the removal test to every line of the project CLAUDE.md. Delete what fails; move area-specific lines to a .claude/rules/ file with paths, and procedures to a skill. 3. Rewrite each remaining vague line as one checkable action or fact. 4. Pick two instructions Claude previously ignored. Start a fresh session and give a task that should trigger each. 5. For any instruction that must always hold (a forbidden directory, a required check), write a hook instead and delete the line.

Pass criterion: the project CLAUDE.md is under 200 lines, every line passes the removal test, and both previously ignored instructions are now followed or enforced by a hook.

Quick reference

  • Keep the old file in git history so you can compare behaviour before and after.
  • Ask a teammate to review the new file; they will spot lines only you understand.
  • Schedule a short review whenever Claude repeats a mistake; that is the signal to edit.

Remember this

Measure, prune, rewrite, test in a fresh session, and turn must-always rules into hooks.

Key takeaway

A CLAUDE.md works when it is short, specific, and true: build commands Claude can't guess, conventions that differ from defaults, and gotchas that aren't visible in the code, each written as one checkable line. Every applicable file is concatenated into context, from managed and user files down to the project and your local notes, so conflicts must be removed rather than overridden, and anything that matters only sometimes belongs in path-scoped rules or skills.

Remember the boundary: CLAUDE.md is advice to the model, not enforcement. When something must happen every time, use a hook; see Claude Code Hooks Guide. For packaging procedures that load only when needed, see Top Claude Skills.

Practice (40 min): run the five-step rewrite above on your own repository.

Share:

References

  1. Claude Code docs: How Claude remembers your project (CLAUDE.md, rules, AGENTS.md) — checked Oct 18, 2026
  2. Claude Code docs: Best practices (Write an effective CLAUDE.md) — checked Oct 18, 2026
  3. Claude Code docs: Hooks guide — checked Oct 18, 2026
SH

Shoaib Hossain

Lead Author & Systems Architect

Software engineer and distributed systems architect specializing in backend scalability, cloud-native infrastructure, databases, and AI engineering workflows. Author and maintainer of Core Concept Learning.

Human-Engineered & Fact-CheckedOriginal Visual DiagramsEditorial Standards →Send Feedback

Related Articles

Terminal AI agents are replacing simple code completion extensions, providing developers with autonomous command-line as…

Read

Plan mode is the Claude Code permission mode for thinking before touching code. Claude reads files, runs commands to exp…

Read

A Claude Code skill is a folder with a SKILL.md file: YAML frontmatter that says what the skill is for, and markdown ins…

Read

Explore this topic

Keep learning

Follow a structured path or browse all courses to go deeper.