Practice · The MD series · October 2026

CLAUDE.md: the file Claude Code reads first, and why most of them are too long

Everything in it is read every session, whatever the task. That is the feature, and it is also the reason the best ones are short.

The most common CLAUDE.md we see is four hundred lines long, was generated once, describes the directory layout in loving detail, and ends with always write clean, well-tested code. Claude Code reads every word of it at the start of every session, and then behaves as if it had read none of it. Both halves of that sentence have the same cause. This is a practice note on what the file is for, what the documentation actually says to put in it, and where the rest should go instead.

In one paragraph

A CLAUDE.md is a Markdown file Claude Code reads at the start of every session and treats as persistent instructions: context, not enforced configuration. Keep each file under 200 lines and limited to what the agent cannot derive from the code and would otherwise need re-explaining: commands, conventions that differ from defaults, boundaries, gotchas. Move procedures to skills, part-of-the-codebase rules to path-scoped rules, and anything that must happen every time to a hook. Write instructions concrete enough to verify, remove contradictions, and prune anything the agent already gets right without being told.

The definition

What the file is, and is not

Each Claude Code session starts with an empty context window. Two mechanisms carry knowledge across sessions: CLAUDE.md files, which you write, and auto memory, which Claude writes for itself. Both load at the start of every conversation.[1]

The sentence from the documentation that explains most CLAUDE.md failures is this one: Claude treats these files as context, not enforced configuration. The file is delivered as a user message after the system prompt; Claude reads it and tries to follow it, and there is no guarantee of strict compliance, especially for vague or conflicting instructions.[1] To block an action regardless of what Claude decides, you use a hook or a managed setting, not a sentence in Markdown. The file shapes behavior. It does not enforce it.

That framing decides everything else. A document that is advisory, loaded whole, every session, and competing for attention with the actual task has one optimization: say only what changes behavior, and say it in a form that can be checked.

The mechanics

Where it lives and how it loads

Four locations, each with a different scope, loaded in this order so that the most specific instruction appears last:[1]

ScopeLocationForShared with
Managed policy/Library/Application Support/ClaudeCode/CLAUDE.md on macOS; /etc/claude-code/CLAUDE.md on LinuxOrganization-wide standards, compliance remindersEvery user on the machine; cannot be excluded
User~/.claude/CLAUDE.mdPersonal preferences across all projectsOnly you
Project./CLAUDE.md or ./.claude/CLAUDE.mdTeam-shared project instructionsThe team, via version control
Local./CLAUDE.local.md (gitignored)Your sandbox URLs, preferred test dataOnly you, this project
Figure 1 · Load order and scope

What is in context at launch, and what waits

CLAUDE.md load order in Claude Code At launch Claude Code concatenates, in order: the managed CLAUDE.md, the user CLAUDE.md, then every CLAUDE.md and CLAUDE.local.md from the filesystem root down to the working directory, with CLAUDE.local.md after CLAUDE.md at each level. Rules in .claude/rules/ without a paths field load at launch too. CLAUDE.md files in subdirectories and path-scoped rules load on demand, when Claude works on a file there. LOADED AT LAUNCH, IN THIS ORDER managedorg policy ~/.claude/your preferences parent dirsroot → down ./CLAUDE.mdworking directory CLAUDE.local.mdread last + .claude/rules/*.md without a paths field, same priority as .claude/CLAUDE.md Files are concatenated, not overridden. Closer to the launch directory = read later. LOADED ON DEMAND subdir/CLAUDE.md loads when Claude reads, writes or edits a file in that subdirectory .claude/rules/x.md with paths: loads when Claude works on a file matching the glob
From the memory documentation. A file over 4 MiB is skipped entirely; subdirectory files and path-scoped rules have a smaller per-file limit and Claude receives only the start of one that exceeds it.

Three details that matter in practice. Files are concatenated, not overridden, so a project instruction and a user instruction that conflict do not resolve; Claude may follow either.[1] A CLAUDE.md in a subdirectory does not load at launch; it loads the first time Claude reads, writes or edits a file there, which is why a new one seems not to work until the agent touches that part of the tree.[1] And block-level HTML comments are stripped before the content reaches Claude, so <!-- maintainer notes --> cost no context and are the right place for notes to humans.[1]

The content

What goes in, what stays out

The documentation gives a direct test for when to add a line: Claude makes the same mistake a second time; a code review catches something it should have known about this codebase; you type the same correction you typed last session; a new teammate would need the same context.[1] And it gives a table that is worth reproducing almost verbatim, because most bloated files violate the right-hand column line by line:[2]

Include
Exclude
Commands Claude cannot guess
Anything Claude can figure out by reading the code
Code style rules that differ from defaults
Standard language conventions Claude already knows
Testing instructions and preferred test runners
Detailed API documentation (link to it instead)
Repository etiquette: branch naming, PR conventions
Information that changes frequently
Architectural decisions specific to this project
Long explanations or tutorials
Developer environment quirks: required env vars
File-by-file descriptions of the codebase
Gotchas and behaviors that are not self-evident
Self-evident practices such as “write clean code”

The line-by-line test the documentation proposes is the one to adopt: for each line, would removing this cause Claude to make mistakes? If not, cut it.[2] The /doctor checkup now proposes exactly these cuts for a checked-in file: it removes content Claude can derive from the codebase, such as directory layouts, dependency lists and architecture overviews, and keeps pitfalls, rationale and conventions that differ from tool defaults.[1] Run it before you argue with a colleague about what to keep.

The craft

Four rules of writing

01Concrete enough to verify

A rule you could check is a rule that gets followed

Use 2-space indentation, not format code properly. Run npm test before committing, not test your changes. API handlers live in src/api/handlers/, not keep files organized.[1] The documentation’s examples all share one property: a reviewer could look at a diff and say whether the rule was obeyed. If yours cannot be checked that way, it is not an instruction, it is a mood.

02Under 200 lines

Longer files consume more context and reduce adherence

The target is under 200 lines per file.[1] Claude Code warns at startup and in /status when a file passes the recommended length, and again when several files that are each within it add up past a combined limit.[1] Splitting into @path imports helps you organize a long file but does not reduce its context cost, because imported files load with the file that imports them; only path-scoped rules and skills actually take content out of the every-session load.[1]

03Headers and bullets, not paragraphs

Organized sections are easier to follow than dense prose

Group related instructions under Markdown headers and bullets.[1] There is no required format; the documentation’s own example is two headers (Code style, Workflow) and five bullets.[2] If one instruction keeps being skipped, add emphasis such as IMPORTANT to that line alone; if you emphasize many lines, none of them stands out.[2]

04No contradictions, anywhere in the chain

If two instructions conflict, Claude may pick one arbitrarily

Across the managed file, your user file, every parent directory, the project file, nested files and .claude/rules/, a contradiction does not resolve in favor of the more specific one; it resolves at random.[1] Review the whole chain periodically. /doctor prompt-audit looks for instructions written for older models, references to files or commands that no longer exist, and files that contradict each other, and reports findings with proposed edits without changing anything until you ask.[1]

The test Would removing this line cause Claude to make a mistake? If not, it is costing you attention for nothing.

The decision

Where an instruction actually belongs

Most CLAUDE.md bloat is not bad writing. It is content that belongs in one of five other places, each of which Claude Code provides precisely so that this file can stay short:[1][2]

If the instruction is…It belongs inBecause
a fact that holds every sessionCLAUDE.mdThat is what the every-session load is for: commands, conventions, layout, “always do X”.
only relevant to one part of the codebase.claude/rules/*.md with a paths: fieldLoads only when Claude works on a matching file. Zero cost the rest of the time.
a multi-step procedurea skill (.claude/skills/<name>/SKILL.md)Loads only when invoked or when the task matches its description. The guidance: move it when a section of CLAUDE.md has grown into a procedure rather than a fact.
something that must happen every time, no exceptionsa hookCLAUDE.md is advisory; hooks are deterministic and run at fixed lifecycle events regardless of what Claude decides.
something that must be blockeda setting (permissions.deny, sandbox)Enforced by the client. A sentence in Markdown cannot deny a tool.
a correction you gave onceauto memoryClaude records it itself; you need not write it. See section 08.

The documentation’s own table of what to enforce where is explicit: block tools, commands or paths with managed settings; enforce sandbox isolation with settings; put code style, data-handling reminders and behavioral guidance in CLAUDE.md.[1] Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md instructions shape Claude’s behavior but are not a hard enforcement layer.[1] If you remember one sentence from this piece, that is the one.

For the full account of what a skill is and how it differs from a workspace file, see SKILL.md: the file that teaches an agent a procedure.

The sibling

CLAUDE.md and AGENTS.md

AGENTS.md is the vendor-neutral workspace file, read by more than twenty agent tools and stewarded under the Linux Foundation. Since Claude Code v2.1.277, Claude reads it directly as the project instructions when there is no CLAUDE.md or CLAUDE.local.md in the working directory or above it, so a repository already set up for other agents works without adding anything.[1] The rules for a repository that has both:[1]

The repository hasClaude reads
AGENTS.md onlyAGENTS.md, from the working directory and the directories above it.
AGENTS.md + CLAUDE.mdThe CLAUDE.md files only, unless the Project instructions setting is changed to read both.
CLAUDE.md that imports AGENTS.mdCLAUDE.md, with AGENTS.md included through the import, read once.

The pattern the documentation recommends for one shared file with Claude-specific additions is an import at the top of a CLAUDE.md, with the Claude-only instructions below it:[1]

@AGENTS.md

## Claude Code

Use plan mode for changes under `src/billing/`.

A symlink from CLAUDE.md to AGENTS.md also works, with two constraints: the Edit and Write tools refuse to write through a symlink, and on Windows a committed symlink checks out as a one-line text file unless symlinks are enabled, which leaves that clone with no instructions at all. If anyone on the team is on Windows, use the import.[1] A CLAUDE.md that merely says read AGENTS.md in words is the one setup to avoid: Claude sees the other file only if it decides to open it.[1]

The trap

Because CLAUDE.local.md counts as a CLAUDE.md for this check, adding one to keep your own uncommitted notes in a project that relies on AGENTS.md silently stops Claude reading AGENTS.md for you. Either set Project instructions to read both, or import.[1]

The plumbing

Imports, local files, rules

  • Imports. @path/to/file anywhere in the file expands that file into context alongside it, relative to the importing file, up to four hops deep. Import parsing skips code spans and fenced blocks, so `@README` in backticks stays literal. A path with spaces needs backslash escapes; a quoted path is not imported at all.[1]
  • External imports. An import that resolves outside the working directory, such as @~/.claude/my-project-instructions.md, triggers a one-time approval dialog per project, because it protects you from files other people commit to a shared repository. Declined imports stay disabled.[1]
  • Local file. CLAUDE.local.md at the project root loads alongside CLAUDE.md, is treated the same way, and belongs in .gitignore. It exists only in the worktree where you created it; to share personal notes across worktrees, import a file from your home directory instead.[1]
  • Rules. .claude/rules/ holds one topic per file, discovered recursively. A rule without a paths: field loads at launch with the same priority as .claude/CLAUDE.md; one with paths: loads when Claude uses Read, Write or Edit on a matching file. Glob patterns support brace expansion; paths is the only frontmatter field a rule reads.[1]
  • Monorepos. claudeMdExcludes skips ancestor files by path or glob, at any settings layer, except the managed file.[1]

The other memory

CLAUDE.md versus auto memory

Auto memory is the half of the system people forget they have. Claude saves notes for itself as it works, in four types: your role and preferences, corrections you give and approaches you confirm, project decisions it cannot derive from the code, and pointers to resources outside the project. It skips anything derivable from the codebase and anything your CLAUDE.md already says.[1]

CLAUDE.mdAuto memory
Who writes itYouClaude
What it holdsInstructions and rulesLearnings and patterns
ScopeProject, user or organizationPer repository, shared across worktrees, machine-local
LoadedEvery session, whole file (up to 4 MiB)Every session: the first 200 lines or 25 KB of the index; topic files on demand
Use forStandards, workflows, architectureYour preferences, your corrections, context Claude cannot derive

The practical consequence: a correction you give in chat is already being captured. Always use pnpm, not npm goes to auto memory on its own. To put something in CLAUDE.md instead, ask for that explicitly (add this to CLAUDE.md) or edit the file via /memory.[1] Both are plain Markdown you can open, edit and delete at any time, and /context lists which files actually loaded at launch.[1]

The evidence

The evidence on context files

There is one rigorous evaluation of whether files like this help, and it is worth reading before writing one. In February 2026 researchers at ETH Zurich tested coding agents with and without repository context files and found, from the abstract, that providing them does not generally improve task success rates, while increasing inference cost by over 20% on average, for both LLM-generated and developer-committed files.[3] The longer discussion is in our AGENTS.md piece; the short version is that anything named in a context file gets reached for whether or not the situation calls for it.

Read correctly, that is not an argument against the file. It is an argument for exactly the file the documentation describes: short, limited to what the agent cannot derive, and pruned when the agent already does the right thing unprompted. The documentation’s own failure pattern is named the over-specified CLAUDE.md: a file so long that Claude ignores half of it because the important rules get lost in the noise, with the fix ruthlessly prune; if Claude already does something correctly without the instruction, delete it or convert it to a hook.[2] The study and the vendor agree.

The artifact

A template

Fifty lines that follow every rule above. Replace the specifics; keep the shape; delete anything you did not need to change.

# CLAUDE.md
<!-- Read every session. Keep under 200 lines. Facts only; procedures are skills. -->

## Commands
- Install: `pnpm install` (not npm; the lockfile is pnpm's)
- Test: `pnpm test -- --filter <name>` for one package; the full suite takes 9 minutes, run it only before a PR
- Typecheck after a series of edits: `pnpm typecheck`

## Conventions that differ from defaults
- ES modules only; no `require`
- 2-space indentation; Prettier config is authoritative, do not hand-format
- API handlers live in `src/api/handlers/`, one file per route

## Boundaries
- Never edit files under `migrations/`; propose a new migration instead
- Never push to `main`; open a PR from a branch named `feat/…` or `fix/…`
- Secrets come from `.env.local`; never write them into a file that is committed

## Done means
- Tests for the touched package pass
- `pnpm typecheck` passes
- The PR description names the issue it closes

## Gotchas
- The dev server needs `DATABASE_URL` set or it fails silently on first request
- `apps/legacy/` is frozen; changes there go to the platform team

## Claude Code
- Use plan mode for anything under `src/billing/`
- When compacting, preserve the list of modified files and the test command
No email required

Notice what is absent. No directory tree: Claude can list it. No description of what the app does: Claude can read it. No write clean code. The Boundaries and Done means sections are the two that the context file checker most often finds missing, and they are the two with the most leverage, because an agent without boundaries will attempt everything and an agent without done-criteria stops when the work looks done.[2] Run the draft through the checker when you have one.

The repair

When Claude ignores it

In the order the documentation suggests, because the first two causes account for most cases:[1]

  1. Confirm it loaded. Run /context and check the list under Memory files. A file that is not there cannot be followed. Remember that a subdirectory file will not appear until Claude touches that subdirectory.
  2. Make it specific. Use 2-space indentation works where format code nicely does not. If Claude asks questions the file already answers, the phrasing is ambiguous.
  3. Find the contradiction. Across every file in the chain, including the built-in guidance Claude Code adds on its own: if your file sets commit or PR rules, turn off the built-in ones with includeGitInstructions.
  4. Shorten it. If Claude keeps doing something you have a rule against, the file is probably too long and the rule is getting lost.
  5. Move it to a hook. If the instruction must run at a specific point, before every commit or after each edit, it is not a CLAUDE.md instruction; it is a hook, and hooks apply regardless of what Claude decides.
  6. Check compaction. The project-root file survives /compact; nested files and path-scoped rules reload on demand. An instruction given only in conversation does not survive, so add it to the file if it must.

The InstructionsLoaded hook logs which files loaded, when and why, which is the tool for the stubborn cases.[1]

Questions people ask

What is a CLAUDE.md file?

A Markdown file that Claude Code reads at the start of every session and treats as persistent instructions: build and test commands, conventions, project layout, rules that apply whatever the task. It can live at the project root, in a user's home directory, in a managed organization-wide location, or as a gitignored CLAUDE.local.md for personal notes. Claude Code treats it as context, not as enforced configuration; anything that must happen every time belongs in a hook or a setting instead.

How long should a CLAUDE.md be?

Under 200 lines per file, per Claude Code's documentation. Longer files consume more context and reduce adherence; Claude Code warns at startup when a file passes the recommended length. The test for each line is whether removing it would cause Claude to make mistakes. If not, cut it, move it to a path-scoped rule that loads only for matching files, or move it to a skill that loads only when invoked.

What should go in CLAUDE.md and what should not?

In: commands Claude cannot guess, style rules that differ from defaults, test runners and how to run them, repository etiquette, architectural decisions specific to the project, environment quirks, gotchas that are not self-evident. Out: anything derivable from reading the code, standard language conventions, detailed API documentation, information that changes often, long explanations, file-by-file descriptions, and self-evident practices such as 'write clean code'.

CLAUDE.md or AGENTS.md?

Since Claude Code v2.1.277 Claude reads AGENTS.md as the project instructions when there is no CLAUDE.md or CLAUDE.local.md in the working directory or above it, so a repository already set up for other agents works without a CLAUDE.md. If both exist, Claude reads the CLAUDE.md files only, unless the Project instructions setting is changed to read both. To keep one shared file with Claude-specific additions, put an @AGENTS.md import at the top of a CLAUDE.md and add the Claude-only instructions below it.

Why is Claude ignoring my CLAUDE.md?

Check, in order: that the file loaded (run /context and look under Memory files); that the instruction is concrete enough to verify ('use 2-space indentation', not 'format code properly'); that no other CLAUDE.md, rules file or built-in guidance contradicts it, because Claude may then pick either; and that the file is not too long, since rules in a bloated file get lost. If the instruction must run at a fixed point, such as before every commit, write it as a hook; CLAUDE.md is advisory and hooks are deterministic.

Do context files actually help?

The only rigorous evaluation so far, from ETH Zurich in February 2026, found that providing repository context files did not generally improve coding-agent task success while raising inference cost by over 20% on average, for both generated and developer-written files. That is an argument for a short file of things the agent cannot derive, not an argument for no file; the same study is why Claude Code's own guidance is to prune anything the agent already gets right without the instruction.


Emil Krzemiński is the founder of auxfirst, the agentic experience design agency — helping product, developer and business teams design AI systems that remember, adapt, and earn the right to act. Start with the AGENTS.md pattern, the context file checker, or a conversation. For how machines read auxfirst, see the AI info page. Subscribe to the auxfirst Substack for what's next.