TLDR; CLAUDE.md is the instruction file Claude Code reads at the start of every session. Cover four areas (project, house rules, output format, hard boundaries) and aim for under 200 lines, Anthropic’s own target. Move detail that only some tasks need into files that load on demand. After setup, add a rule when Claude makes a mistake or the project changes, and delete anything Claude could learn by reading the code.
When to use a CLAUDE.md file
- A new project, or a mistake Claude keeps repeating. One written rule carries the fix into every later session.
- A file past about 200 lines, or rules Claude seems to ignore. The file may need trimming. The audit in step 6 shows what to cut.
- A shared repository. Team conventions go in git (the shared version history); personal preferences stay out of it (step 2).
- Skip it for rules a linter or formatter can enforce. A linter checks code style automatically, so put the rule there and keep CLAUDE.md for what the tools can’t check.
- Skip it for facts Claude can read from the code. File layout and config values are one read away; writing them down only costs tokens, the small chunks of text Claude is billed by.
How CLAUDE.md works
CLAUDE.md is a Markdown file Claude Code reads automatically at the start of every session. Its text stays in Claude’s context window for the whole conversation. The context window is the amount of text Claude can hold at once. Custom sub-agents (helper sessions Claude starts for one job) normally inherit the applicable project instructions. The built-in Explore and Plan agents get a narrower context by design. Claude also keeps notes of its own, called auto memory; the memory hierarchy guide covers both.
Length matters because attention is limited. Lakshmi Narasimhan argues that the leading models reliably follow roughly 150–200 instructions before they start to miss some. Claude Code’s built-in instructions (its system prompt) use about 50 of those slots, which leaves your CLAUDE.md maybe 100–150 effective instructions. Past that, each line you add dilutes the ones that matter, and every line costs tokens.
Anthropic’s Data Infrastructure team points new data scientists at Claude Code, which reads the team’s Claude.md files to guide them through the codebase. That is the right aim for the file: the minimum context a competent colleague needs to start work without avoidable mistakes. It is neither a full reference manual nor a personality setting.
Claude Code reads up to four CLAUDE.md files, in this order, and keeps them all in context:
| File | Scope | Committed to git? |
|---|---|---|
Managed policy (/etc/claude-code/CLAUDE.md on Linux) |
Organisation-wide, set by IT | N/A (deployed by admins) |
~/.claude/CLAUDE.md |
Global, applies to every project | N/A (personal machine) |
CLAUDE.md (project root) |
Project-specific, shared with team | Yes |
CLAUDE.local.md (project root) |
Personal project preferences, never credentials | No (add it to .gitignore) |
In a normal session Claude reads your global file, the project file and your local file. A later file doesn’t override an earlier one; if two instructions conflict, Claude may follow either, so keep the files consistent.
How to write and maintain a CLAUDE.md
1. Cover four areas in your CLAUDE.md
I have studied dozens of CLAUDE.md files from real projects, including ones the community has shared publicly. The structure I settled on covers four areas; use whatever headings suit the project:
- Project identity: two or three sentences on what the project is, the tech stack and what matters most.
- House rules: conventions that differ from the defaults. Build commands Claude can’t guess, naming patterns, architectural boundaries, forbidden patterns.
- Output format: how you want code and text structured, such as commit message format, test patterns and response style.
- Hard boundaries: what Claude must never do here. Security rules, protected files, off-limits operations.
Here is a condensed CLAUDE.md, from this site:
# CLAUDE.md
## Project
Kam's personal site: an isometric "knowledge islands" scene over
static pages. 11ty v3 (Nunjucks), Tailwind CSS v4, ES-module
client scripts with no bundler.
## Commands
npm run dev # 11ty --serve + Tailwind watch
npm run gate # clean build + deploy checks (links, SEO, markup, weight)
npm test # node --test runs test/*.test.js
## House rules
npm run build wipes _site/, including the dev server's CSS:
touch src/css/main.css or restart dev afterwards.
A page file holds front matter and Markdown, never HTML.
Old URLs go in ops/redirects.journal.jsonl, append only.
A page module that adds a listener removes it in destroy().
## Hard boundaries
Never decode the protected email into source, data or HTML.
Never hand-edit _redirects.
## Rules files
Subsystem detail lives in .claude/rules/, one file per area,
each loaded only for the paths it covers.
Apply one test to every line: would removing it cause Claude to make a mistake? If not, delete it. Claude can read config/routes.rb and list a directory itself, so writing down its routes or file layout spends tokens on what it can already see.
Don’t ask Claude to generate the file. “Generate a CLAUDE.md for this project” produces something that looks thorough and mostly restates the code. Sabrina Ramonov’s advice: think “email with links”, not a “2000-page employee handbook”. If you want Claude’s help, start with a blank file and add rules as mistakes appear.
Check: the file covers the four areas, and removing any line would cause Claude to make a mistake.
2. Split shared CLAUDE.md rules from personal ones
CLAUDE.local.md separates the two: your team needs shared project instructions, but you have personal preferences, local paths and context that don’t belong in git.
- CLAUDE.md (committed, shared): build and test commands, conventions the whole team follows, architectural decisions and hard constraints.
- CLAUDE.local.md (personal; add it to
.gitignoreyourself): your preferred response style (“keep responses terse”, “Australian English”), local tool paths, and personal shortcuts. For local test credentials, name the environment variable or credential store to read them from, and never paste the value.
Listing a file in .gitignore only keeps it out of git. Claude still reads it and can quote it back. Passwords, access tokens and private keys belong in a credentials store or environment variables, never in any CLAUDE file.
Check: git check-ignore CLAUDE.local.md prints the file name, and a search of both files finds no secret.
3. Move situational detail out of the root file
A single root file works for a small project. In a larger codebase, with several services or subsystems, the root file either bloats or stays lean and misses rules that apply to one part. Three mechanisms keep instructions out of the context window until a task needs them.
Subdirectory files. Any directory can have its own CLAUDE.md (an api/CLAUDE.md for endpoint patterns, a tests/CLAUDE.md for fixtures). It loads when Claude reads a file in that directory, and costs tokens only then.
Path-scoped rules. For finer control, a file in .claude/rules/ starts with a header listing path patterns (globs), and loads only when Claude works on a matching file:
---
paths:
- test/controllers/**/*.rb
---
- Always use integration tests, never unit tests for controllers
- Test both JSON and HTML response formats
- Include authentication context in every test
A rule about test conventions doesn’t load while Claude edits a database migration. To confirm a new rule loads, add an InstructionsLoaded hook (a script Claude Code runs each time an instruction file loads), then have Claude read a matching file and check the log.
Backtick pointers. Write a file path in backticks inside a sentence, such as `docs/deployment.md`. It costs about ten tokens. Claude Code doesn’t load it at launch; Claude reads the file itself when a task seems to need it. A 400-line deployment procedure then costs tokens only in the sessions that use it.
A backtick path is only a hint: Claude skips a bare path more often than it follows one. Give the path a trigger: a sentence that says when to read it. My global file lists my custom command-line tools and, for each, the path to its skill (a packaged set of instructions). The rule above the list says “before the first use of any of them in a session, read its skill”. Claude obeys the sentence; the path only says where to go. Use pointers for situational material (procedures, flag references, lookup tables) and keep hard constraints in the file itself, where they load every session.
The @import syntax splits a root CLAUDE.md into referenced files, but it saves no tokens. Imported files load at startup exactly as if pasted into the root file, so a 280-line CLAUDE.md split into five imports is still 280 lines at session start. Use @import for tidiness only.
Use the three mechanisms above and the root file’s detail loads only when a task needs it. On this site the split cut the text loaded every session by about three-quarters (see In practice).
@import
- Loads at startup, as if pasted in
- 280 lines in five imports is still 280
- Tidiness only; saves no tokens
Subdirectory CLAUDE.md or rules
- Loads when Claude touches a matching file
- Costs tokens only when relevant
Backtick path
- About ten tokens in a sentence
- Claude reads it on its own initiative
- Needs a trigger; situational material only
Check: in a session that never touches a subsystem, the InstructionsLoaded hook logs no load for that subsystem’s file.
4. Keep session-wide rules in the root CLAUDE.md
Deferred loading has a cost the token arithmetic doesn’t show. After /compact, which condenses a long conversation to free space, Claude Code reloads the root CLAUDE.md. It does not reload subdirectory files or path-scoped rules straight away. Compaction summarises them like any other part of the conversation, and the summary usually drops them. They load again only when Claude next reads or edits a matching file. The session craft guide covers when to compact and when to start fresh.
So a long session can drift. Claude follows the rules in api/CLAUDE.md for the first hour; then compaction fires, and until Claude next opens a file in api/, its plans and answers can miss them.
Two habits follow:
- Put anything that must hold for the whole session in the root file, even when it reads as subsystem-specific: security boundaries, protected paths, the conventions you would catch in review.
- After a compaction, read a file in the relevant directory before resuming work there. The terminal prints a
Loaded <path>line when a subdirectory CLAUDE.md comes back, and theInstructionsLoadedhook logs rules files too.
- Root CLAUDE.mdLoads at launch, reloaded
- Rules without pathsLoad at launch, reloaded
- Auto memoryLoads at launch, reloaded
Subdirectory CLAUDE.mdLoaded when Claude read a file in that directory (lost after /compact)Path-scoped rulesLoaded when Claude touched a matching path (lost after /compact)
Check: after /compact, a file you read in the directory prints Loaded <path>.
5. Add a rule when Claude makes a mistake
After setup, two things call for an edit: Claude did something wrong, or the project changed (a new command, a new boundary). Correct a mistake in the session, then add a rule that prevents a repeat.
Boris Cherny, who created Claude Code, runs his team’s shared file this way. It lives in git and is updated several times a week. “Anytime we see Claude do something incorrectly we add it to the CLAUDE.md.” Say Claude wrote camelCase where the project uses snake_case: add the rule. Leave out guesses about what Claude might get wrong, and the file holds only what this codebase needs.
Pruning is the other half. Once a quarter, or when the file passes 200 lines, run the audit in step 6. A rule that was essential six months ago may now do nothing: a linter enforces it, the deprecated API was removed, the framework was upgraded, or a newer model gets it right unprompted. A stale instruction still costs tokens and competes with the rules that matter.
Check: each recent line traces back to a specific mistake or project change you can name.
6. Audit an overgrown CLAUDE.md
If the file has passed 200 lines, review it for detail it doesn’t need. /init can analyse a project and suggest improvements to CLAUDE.md. /doctor proposes trims for a CLAUDE.md committed to git: it suggests cutting what Claude can work out from the codebase, and keeping the pitfalls and conventions that differ from tool defaults. I still do the manual pass because it makes the trade-offs explicit.
Tag every line as essential, situational or discoverable.
Essential
- Needed every session, not discoverable from the code
- Non-obvious build flags, naming conventions no linter checks, architectural boundaries, hard constraints
Situational
- Needed for specific tasks, not all tasks
- Deployment procedures, API quirks, client-specific domain rules
Discoverable
- Claude can find it by reading the codebase
- File structure, module purposes, existing patterns, config values
- Delete the discoverable lines. File structure, module purposes and config values are all one read away.
- Move the situational lines out. Deployment procedures become a skill. Client-specific rules go to subdirectory files or
.claude/rules/. Only a skill’s short description is present at startup; the body loads only when a task needs it. The skills guide covers the move in detail. - Tighten what remains. “Use kebab-case for all URL slugs” is enough. “It’s important to use kebab-case for URL slugs because this ensures consistency across the project and improves SEO readability” costs more than three times the tokens, and Claude follows it no better.
- Test. Run the same tasks before and after the trim. In my experience, quality stays the same or improves slightly.
Check: the same tasks give the same or better output, and every line left passes the removal test. Aim for under 200 lines.
Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
| Claude ignores a specific rule | Too many competing instructions | Trim the file; move non-essential rules out; enforce a hard rule with a hook |
| Claude asks about things CLAUDE.md already answers | The file is long and the rule is buried | Move the rule near the top, or into a targeted .claude/rules/ file |
| Claude forgets conventions mid-session | The context window is filling and instructions lose weight | Condense the file; see the session craft guide |
| A subsystem rule holds early, then lapses | Compaction dropped a subdirectory CLAUDE.md or scoped rule | Read a file in that directory, or promote the rule to the root file |
| The context cost didn’t fall after splitting the file | The pieces are @imported, which load at startup |
Use subdirectory files, path-scoped rules or backtick pointers |
| A generated CLAUDE.md produces worse output | It restates the code and wastes instruction slots | Delete it; rewrite by hand with rules that prevent real mistakes |
In practice
Over two weeks on a client’s Rails project, I built its CLAUDE.md alongside the codebase: coding conventions, deployment procedures, domain model, API patterns, test expectations and gotchas. It reached 280 lines and I was proud of it. Then I trimmed it to 85, keeping only instructions that prevented mistakes Claude had made, and ran the same set of tasks. Output quality didn’t drop, and one task came out better. Fewer instructions competing for attention meant the remaining ones were followed more reliably.
The file for this site shows the other route to a smaller load. It was about 740 lines until I moved the subsystem detail (the router, the reading window, the chart generator, the PDF scripts) into twelve path-scoped files in .claude/rules/, which left 216. Those rules load only when Claude reads or edits a matching file, so a session that never touched the charts never paid for their 56 lines. The text loaded every session fell to about 3,000 tokens, down from about 12,700. A later pass took it to 77 lines and eighteen rules files, and each line left passes the removal test from step 1. The _site/ rule exists because a build run during a dev session silently deleted the dev server’s CSS, twice in one afternoon.
My global ~/.claude/CLAUDE.md started with preferred languages, absolute rules (never commit secrets, never force-push to main) and git conventions. It has since grown to about 105 lines, almost all of it lessons added the day something went wrong. One early entry read: “zsh kills unmatched globs before the command runs, bit twice: 2026-06-10, 2026-06-11.” A global file earns its length the same way a project file does, one documented error at a time.
In a fractional CTO engagement, I write these conventions down for the team’s repositories and keep each file lean.
Related reading
- Claude Code memory: CLAUDE.md, auto-memory and persistent context, where CLAUDE.md fits in the broader memory system
- Claude Code pricing: what plans, tokens and models cost, the cost of CLAUDE.md in context and dollars
- Claude Code skills, hooks, subagents and commands: when to use each, moving knowledge from CLAUDE.md to on-demand skills
- Session craft, when to start fresh, resume, or compact, managing the context window your CLAUDE.md loads into
- How I use CLAUDE.md across six client projects, these conventions applied day to day across real client engagements
Sources
- CLAUDE.md Best Practices, Lakshmi Narasimhan, The ~150-200 instruction compliance ceiling argument. Blog post
- How Anthropic teams use Claude Code, Data Infrastructure onboarding via Claude.md. White paper
- 6 Ways I Cut My Claude Token Usage, Sabrina Ramonov, The 2,000-token CLAUDE.md target and “email with links” framing. Blog post
- How Boris Uses Claude Code, The add-on-mistake maintenance pattern. Secondary source (fan-made collection)
- Claude Code Docs, CLAUDE.md configuration, Official documentation for file structure and loading order. Documentation
Common questions
What is a CLAUDE.md file?
It is the instruction file Claude Code reads at the start of every session: what the project is, the house rules, the output format and the hard boundaries a new colleague would need. It belongs to the project, so every conversation starts with the same instructions.
What should go in a CLAUDE.md file?
Only what prevents mistakes or sets direction: project context, key commands, rules that differ from the defaults, and hard boundaries. Add a rule when Claude makes a mistake, and delete anything Claude could learn by reading the code.
How long should a CLAUDE.md be?
Aim for under 200 lines, Anthropic’s own target. In my test I trimmed a 280-line file to 85 with no drop in quality, and one task improved. Fewer competing instructions get followed more reliably.
Do subdirectory CLAUDE.md files survive compaction?
No. Compaction (the `/compact` command, or the automatic version when the window fills) condenses a long conversation to free space. Afterwards Claude Code reloads the root CLAUDE.md, rules files that apply to the whole project, and auto memory (Claude’s own notes). A subdirectory CLAUDE.md, or a rule limited to certain files, is not reloaded straight away: it loads again only when Claude next reads or edits a matching file. Keep session-wide rules in the root file, and read a file in the directory again to reload the scoped ones.