Guide · updated 2026-10-12 · 9 min read
How to Write a CLAUDE.md File That Claude Follows
To write a CLAUDE.md file, create a Markdown file at your repo root (./CLAUDE.md or ./.claude/CLAUDE.md) and fill it with the short list of facts Claude can't work out from the code: build and test commands, conventions that differ from defaults, project layout, and "always do X" rules. Keep it under about 200 lines, write instructions concrete enough to verify, and move anything procedural into skills or path-scoped rules so it only loads when needed.
That is the whole job. The rest of this guide is about doing it well, because a bad CLAUDE.md is worse than none: it burns context on every session and buries the three rules you actually care about.
What CLAUDE.md actually is
CLAUDE.md files are Markdown files Claude Code reads at the start of every session. They are delivered as a user message after the system prompt, not as part of the system prompt, and the docs are blunt about what that means: "Claude treats them as context, not enforced configuration." Claude tries to follow them. It is not guaranteed to.
That one fact should shape everything you write. CLAUDE.md is for guidance. If something must happen every time with zero exceptions, such as running a formatter after every edit or never touching .env, that belongs in a hook, not in prose.
Claude Code also has auto memory, where Claude writes its own notes to ~/.claude/projects/<project>/memory/. That is separate. CLAUDE.md is the file you write; auto memory is the file Claude writes.
Where CLAUDE.md files live
There are four scopes, loaded from broadest to most specific, and they are concatenated rather than overriding each other:
| Scope | Location | Use it for |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS), /etc/claude-code/CLAUDE.md (Linux and WSL), C:\Program Files\ClaudeCode\CLAUDE.md (Windows) |
Org-wide standards deployed by IT |
| User | ~/.claude/CLAUDE.md |
Your personal preferences across all projects |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md |
Team-shared instructions, committed to git |
| Local | ./CLAUDE.local.md |
Your private notes for this project, gitignored |
A few loading details matter in practice:
- Claude Code loads CLAUDE.md and CLAUDE.local.md from your working directory and every directory above it at launch. Files closer to where you launched are read last.
- Files in subdirectories load on demand, when Claude reads or edits a file in that subdirectory. That makes nested CLAUDE.md files a cheap way to give a package its own rules in a monorepo.
- Within a directory, CLAUDE.local.md is appended after CLAUDE.md, so your personal notes are the last thing Claude reads at that level.
To confirm what loaded, run /context and check the list under Memory files. Run /memory to open and edit any of them.
Start with /init, then cut
Run /init in a repo and Claude analyzes the codebase and drafts a CLAUDE.md with build commands, test instructions and conventions it finds. If a CLAUDE.md already exists, it suggests improvements instead of overwriting. Setting CLAUDE_CODE_NEW_INIT=1 before running it switches to an interactive flow that also offers to set up skills and hooks and asks follow-up questions before writing anything.
Treat the output as a first draft. /init is good at finding commands and bad at knowing which of the things it found you actually care about. Your job is mostly deleting.
What to include and what to cut
The best practices page gives the most useful test I know for every line: "Would removing this cause Claude to make mistakes?" If not, cut it.
Include:
- Bash commands Claude can't guess (
pnpm test:unit,make dev-db, the flag your test runner needs) - Code style rules that differ from defaults
- Testing instructions and the preferred test runner
- Repo etiquette: branch naming, PR conventions, commit format
- Architecture decisions specific to this project
- Environment quirks, like required env vars
- Gotchas that aren't obvious from reading the code
Cut:
- Anything Claude can figure out by reading the code
- Standard language conventions it already knows
- Detailed API docs (link to them instead)
- Information that changes often
- File-by-file descriptions of the codebase
- Self-evident advice like "write clean code"
The docs list a good trigger for adding a line: Claude makes the same mistake a second time, a code review catches something Claude should have known, or you type the same correction you typed last session.
Write instructions Claude can verify
Vague instructions get vague compliance. The memory docs give three before-and-after pairs that are worth copying as a pattern:
- "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"
Group related rules under headers. Keep each rule to one line where you can. If two rules contradict each other, the docs warn that Claude "may pick one arbitrarily," so when you add a rule, search for the old one it replaces.
If Claude keeps skipping one specific instruction, the docs suggest adding emphasis such as "IMPORTANT" to that line alone. Emphasize ten lines and none of them stands out.
A template you can start from
Here is the shape I use for a typical web app. It is about 30 lines, which is plenty for most repos.
# Project: acme-dashboard
## Commands
- Install: `pnpm install`
- Dev server: `pnpm dev` (needs `make dev-db` running first)
- Unit tests: `pnpm test:unit -- <path>` (prefer single files, the full suite takes 6 min)
- Typecheck: `pnpm typecheck` after any series of changes
## Conventions
- TypeScript strict mode. No `any` without a comment explaining why.
- API handlers live in `src/api/handlers/`, one file per resource.
- Use the `Result` type from `src/lib/result.ts` for errors, never throw in handlers.
- Dates are stored as UTC ISO strings. Format only in the UI layer.
## Git
- Branches: `feat/<ticket>-<slug>` or `fix/<ticket>-<slug>`
- Never commit directly to `main`.
## Gotchas
- `src/legacy/` is frozen. Do not refactor it, only patch bugs.
- The Stripe webhook tests need `STRIPE_WEBHOOK_SECRET` set in `.env.test`.
## Compaction
- When compacting, always preserve the list of modified files and the test commands.
That last section is a trick straight from the docs: you can tell Claude in CLAUDE.md what to keep when it compacts the conversation. Project-root CLAUDE.md itself survives compaction, because Claude Code re-reads it from disk afterward.
Imports: organize, but they don't save context
CLAUDE.md can pull in other files with @path/to/file syntax:
See @README for project overview and @package.json for available npm commands.
# Additional Instructions
- git workflow @docs/git-instructions.md
Relative paths resolve from the file containing the import, imports can nest up to four hops, and a path inside backticks is left as literal text. The catch: imported files load at launch too, so splitting a 600-line CLAUDE.md into six imports doesn't reduce what Claude reads. It only makes the file easier to maintain.
Imports are also how you keep personal instructions across git worktrees. A gitignored CLAUDE.local.md exists only in the worktree where you created it, so the docs suggest importing a file from your home directory instead, like @~/.claude/my-project-instructions.md. The first time a project imports a file outside the working directory, Claude Code shows an approval dialog.
Path-scoped rules for the rest
When a rule only matters for part of the codebase, put it in .claude/rules/ with a paths field in the frontmatter. It then loads only when Claude touches matching files:
---
paths:
- "src/api/**/*.ts"
---
# API rules
- All endpoints validate input with zod schemas from `src/api/schemas/`
- Use the standard error response format in `src/api/errors.ts`
Rules without paths load at launch like CLAUDE.md. paths is the only frontmatter field Claude Code reads from a rule; anything else is ignored. Personal rules that apply to every project go in ~/.claude/rules/.
For multi-step procedures, like "how we cut a release," use a skill instead. A skill's body loads only when it's used, so a long checklist costs almost nothing until you need it.
CLAUDE.md and AGENTS.md together
If your repo already has an AGENTS.md for Codex or Cursor, Claude Code v2.1.277 and later reads it directly, but only when there is no CLAUDE.md or CLAUDE.local.md in your working directory or above it. Add a CLAUDE.md and Claude reads that instead.
The cleanest setup for a multi-tool team is one shared file plus a thin Claude layer:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
You can also change the default in /config under Project instructions, for example to claude-md-and-agents-md to load both. If you are comparing agents, our Claude Code vs Codex vs Cursor guide covers how each tool reads instruction files.
Debugging a CLAUDE.md that isn't working
Work through these in order:
- Run
/contextand check Memory files. If the file isn't listed, Claude can't see it. Nested CLAUDE.md files won't show here because they load on demand. - Make the rule more specific. "Use pnpm, never npm" beats "use the right package manager."
- Look for conflicts across your user file, project file, nested files and
.claude/rules/. - Check whether your rule competes with Claude Code's built-in git guidance. If you set your own commit rules, the docs point to the
includeGitInstructionsandattributionsettings. - Run
/doctor prompt-audit(v2.1.283 or later) to have Claude flag outdated or conflicting instructions and propose edits without changing anything until you approve.
If a rule still gets skipped, accept that it needs enforcement and write a hook.
Bottom line
A good CLAUDE.md is short, specific and boring. Start from /init, delete everything Claude could learn from the code, phrase every rule so you could check whether it was followed, and move procedures to skills and enforcement to hooks. Then treat it like code: when Claude gets something wrong twice, fix the file, and prune it every few weeks. For the wider set of habits around it, see Claude Code best practices.
If you want tested CLAUDE.md setups and workflows like this in your inbox, subscribe to Agent Shipped for two short issues a week.
FAQ
Where should I put my CLAUDE.md file?
For a team project, put it at ./CLAUDE.md or ./.claude/CLAUDE.md in the repo root and commit it. Personal preferences for every project go in ~/.claude/CLAUDE.md, and private per-project notes go in ./CLAUDE.local.md, which you should add to .gitignore.
How long should a CLAUDE.md be?
Anthropic's docs recommend targeting under 200 lines per file. Longer files use more context and reduce adherence, so move anything that only matters for part of the codebase into path-scoped rules or skills.
Does Claude Code read AGENTS.md?
Yes, on Claude Code v2.1.277 or later. By default it reads AGENTS.md only when there is no CLAUDE.md or CLAUDE.local.md in your working directory or above it. To share one file across tools, put @AGENTS.md at the top of your CLAUDE.md.
Why is Claude ignoring my CLAUDE.md?
CLAUDE.md is context, not enforced configuration. Run /context to confirm the file loaded, make vague rules concrete, remove contradictions, and move anything that must happen every time into a hook.