TL;DR: Claude Code loads CLAUDE.md from your working directory and every directory above it at session start, concatenating rather than overriding. A good CLAUDE.md template is short: non-obvious commands, conventions a model would otherwise violate, hard constraints, and repo-specific traps. Everything else belongs in a skill or nowhere. Five templates below.
Most CLAUDE.md templates you can copy off the internet are too long, and the length is not a style problem. A CLAUDE.md is a standing instruction that sits in the context window for the whole session, so every line is charged against every turn and against the attention left for the lines that matter. Anthropic's best-practices page puts it bluntly: "Bloated CLAUDE.md files cause Claude to ignore your actual instructions!"
This is Anthropic's feature, not ours. Below: the mechanics, verified against their documentation on August 27, 2026; the editorial rule most templates get wrong; and five complete files to paste and edit, including one deliberately bad example taken apart line by line.
Where does Claude Code look for CLAUDE.md, and which one wins?
Four scopes, and they do not override each other. The memory documentation lists them in load order, broadest to most specific, so the more specific file lands later in context.
| Scope | Location | Shared with |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md on macOS, /etc/claude-code/CLAUDE.md on Linux and WSL, C:\Program Files\ClaudeCode\CLAUDE.md on Windows | Everyone in the organisation |
| User instructions | ~/.claude/CLAUDE.md | Just you, every project |
| Project instructions | ./CLAUDE.md or ./.claude/CLAUDE.md | The team, via source control |
| Local instructions | ./CLAUDE.local.md | Just you, this project, gitignored |
The word "precedence" is misleading here, and that is the most common misreading. In the docs' words: "All discovered files are concatenated into context rather than overriding each other." Nothing shadows anything. If your user file says one thing and the project file says another, Claude sees both and, per the same page, may pick one arbitrarily. Contradictions are not resolved for you.
Directory traversal works the same way. Claude Code reads CLAUDE.md and CLAUDE.local.md from your working directory and every directory above it, ordered from the filesystem root down to where you launched, so starting in packages/api/ loads the repository root file first and the package file after it. Within a directory, CLAUDE.local.md is appended after CLAUDE.md.
Subdirectories behave differently, and this is the part worth internalising: "Files in subdirectories load on demand when Claude reads files in those directories." A per-package file below your working directory costs nothing until Claude opens code in that package. That asymmetry is what makes the monorepo layout below work.
# Confirm what actually loaded, from inside a session
/context # lists loaded files under "Memory files"
/memory # browse and open every CLAUDE.md scope in your editor
/init # generate a starter file from the current codebase
Run /context before debugging anything else. A rule ignored because its file never loaded looks identical to a rule ignored because it is buried on line 300.
The local file is the underrated one: personal specifics that should never reach a teammate's context.
# CLAUDE.local.md — gitignored. Mine, not the team's.
My sandbox API is at `https://nafiul-dev.internal.example.com`, not the shared one.
Seed with `pnpm seed:small` — the full fixture set takes 11 minutes on this machine.
I run Postgres on 5433. Port 5432 belongs to another project's container.
When is a CLAUDE.md loaded, and what does that cost?
At session start, in full, before your first prompt. One line from the troubleshooting section explains much of the observed behaviour: "CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself." It is not a system prompt. That is why the docs call it context rather than enforced configuration, and why they point you at a hook when something must happen without exception.
Two size numbers, routinely confused. The guidance number is under 200 lines per file, because "Longer files consume more context and reduce adherence." The mechanical ceiling is far higher: "Claude Code loads a CLAUDE.md file of up to 4 MiB in full and skips a larger file." You will never reach 4 MiB. You hit the adherence wall around a few hundred lines, silently. The symptom is not an error; it is Claude quietly not doing the thing you wrote down twice.
# Imports: relative paths resolve against the file containing them,
# not against your working directory. Both forms are valid.
See @README for the project overview and @package.json for scripts.
- git workflow @docs/git-instructions.md
- personal notes @~/.claude/my-project-instructions.md
Two footnotes. Import parsing skips code spans and fenced blocks, so backticks around a path keep it literal. And an import resolving outside your working directory, like that home-directory line, counts as external: Claude Code shows an approval dialog the first time it sees one, and declining disables them permanently.
What actually earns a place in a CLAUDE.md?
Four categories. A line outside all four is costing you context and buying nothing.
Commands that are not guessable. Not npm test, if that is what package.json says. The dev server on a non-standard port, the typecheck script under a different name, the one-liner that brings up the test database. The first entry in Anthropic's own include column is this exact category: the bash commands Claude cannot guess.
Conventions a model would otherwise violate. The value is entirely in the delta from the default. "Use TypeScript" is worthless in a TypeScript repo. "Server actions live in actions/, one file per domain" earns its line, because a model with no instruction invents a different layout and is reasonable about it.
Hard constraints. The things that cause an outage or data loss rather than a bad diff. Never edit a migration that has run. Never rename a public export. Never push to the branch that auto-deploys. These lines justify the whole file.
Traps specific to this repository. The failure mode that has already bitten a human. A suite where 25 of 638 specs need a database and fail with a connection error otherwise. An env var that must never change because it is an encryption key. Config split across two places with different precedence. None of it is readable out of the code, which is why it belongs here.
Anthropic reduces the same test to one question per line: "Would removing this cause Claude to make mistakes?" If not, cut it.
What should never go in a CLAUDE.md?
Three families, in rough order of how much space they waste.
Anything discoverable by reading the code. Directory trees, file-by-file descriptions, dependency lists, architecture overviews. The docs put this first in their exclude column, and the /doctor checkup now proposes trimming exactly this content from a checked-in file. If Claude can open the folder, do not describe the folder.
Restatements of the framework's own documentation. A section explaining how React hooks work, or what a Postgres index is, is pure loss. It is in the training data, and where it is not, a link costs one line instead of forty.
Aspirational style guides. "Write clean, maintainable code." "Follow SOLID principles." "Always consider edge cases." These read as instructions and function as noise, because they are unfalsifiable: no diff visibly violates them. Worse, they dilute the lines that are falsifiable. Anthropic's advice on emphasis makes the mechanism plain: emphasise one line and it stands out, but "If you emphasize many lines, none of them stands out."
| Keep | Cut |
|---|---|
| The port your dev server actually uses | The full scripts block, restated |
| A rule contradicting the framework default | A rule restating the framework default |
| "Never edit a migration after it has merged" | "Be careful with database changes" |
| The env var whose absence breaks tests | A list of every env var |
| Why the odd thing is odd | What the odd thing is, when code says so |
What does a minimal CLAUDE.md template look like?
Start here. Twelve lines beats two hundred on day one, and you add to it the way the docs suggest: when Claude makes the same mistake a second time, when a review catches something it should have known, when you type the same correction you typed last session.
# Project
One sentence on what this is and who uses it.
## Commands
- `npm run dev` — dev server on port 3001, not 3000
- `npm run build:check` — typecheck plus build. Run before saying a change is done.
- `npm test` — vitest. 25 suites need a local database; see `db/README.md`.
## Conventions
- Server actions live in `actions/`, one file per domain.
- All user-facing strings go through next-intl. An untranslated literal is a regression.
## Never
- Never edit a file under `db/migrate/` that has already run. Add a new numbered file.
- Never push to `main`. It auto-deploys to production with no review gate.
What does a web-app CLAUDE.md look like?
Fuller, but still one screen. Note how much of it is negative space: no folder tree, no dependency list, no explanation of what Next.js is.
# Acme Dashboard
Next.js App Router app. Production, ~2,000 paying accounts. Every merge to `main` ships.
## Commands
- `npm run dev` — port 3001. Port 3000 is taken by the API proxy.
- `npm run build:check` — typecheck plus build. Required before any "done".
- `npm test` — vitest. `tests/security/*` are build gates, not advisory.
- `npm run stripe` — forwards webhooks to `localhost:3001/api/webhooks/stripe`.
## Conventions
- Data fetching runs in server actions under `actions/`, one file per domain.
Client components never query the database directly; a test enforces this.
- Validation is zod. Forms are react-hook-form. Client cache is TanStack Query.
- UI comes from the existing shadcn components in `components/ui/` before any new dependency.
- User-facing copy goes through next-intl. 24 locale files; an English literal is a visible bug.
## Constraints
- Never rename or drop a database column, a server action, or an exported symbol
without shipping the new path alongside the old one first.
- Never change `PA_USER_ENCRYPTION_KEY`. Every stored user secret becomes undecryptable.
- Never widen validation on a field where existing rows might fail it.
- Auth, billing and plan gating: propose the change, do not make it.
## Traps
- `.env` is committed and Coolify env vars override it. Change one and you get drift
that typecheck will not catch. Check both.
- RLS fails open. If the connecting role owns the tables, every policy silently no-ops.
- `npm run dev` points at the staging database, not local Postgres. Confirm before writing.
That "Traps" section is the part no template generator will produce for you, and the part that pays for the file. Every line is something a person discovered the hard way.
What changes for a library or package?
A library has no dev server, no deploy, and a sharper compatibility boundary. The constraints move from "do not break production" to "do not break the public API", so the commands section shrinks and a release section appears.
# @acme/parser
Zero-dependency parser published to npm. Node 20+ and modern browsers.
## Commands
- `pnpm build` — tsup, emits ESM and CJS. Both must build.
- `pnpm test` — vitest. `pnpm test:types` runs the type tests in `test-d/`.
- `pnpm size` — size-limit. The budget is 8 kB gzipped and it is a hard gate.
## Public API
- Everything exported from `src/index.ts` is public and semver-bound.
Anything else is internal, whatever its visibility modifier says.
- Adding an optional parameter is a minor. Reordering parameters is a major.
- Never change a thrown error's `code` string. Consumers match on it.
## Conventions
- No runtime dependencies. Ever. A dev dependency that leaks into the bundle fails `pnpm size`.
- Every public function needs a type test in `test-d/`, not only a unit test.
- Errors subclass `ParserError`. Never throw a bare `Error`.
## Release
- Changesets. A PR that touches `src/` without a changeset fails CI.
- Never edit `CHANGELOG.md` by hand.
How do you write a warning that actually works?
By making it falsifiable. A useful warning names a path, a command or a symbol, and describes an action that either happened or did not. "Be careful" describes a mood.
The test: could you write a script that detects a violation? If yes, the warning is concrete enough for a model to follow and a human to enforce. If no, you have written a feeling.
# Vague — costs a line, changes nothing
- Be careful when modifying the database.
- Try to keep the bundle small.
- Don't break backwards compatibility.
- Be thoughtful about performance.
# Falsifiable — same subjects, actually actionable
- Never edit a file under `db/migrate/` that has already run. Add a new numbered file.
- The bundle budget is 8 kB gzipped, enforced by `pnpm size`. Do not add runtime deps.
- Never remove or rename an export from `src/index.ts`. Deprecate, ship both, remove later.
- Never call `getUser()` inside a loop. Batch through `getUsers(ids)`.
Anthropic's own monorepo example is written in this register: copy the env example file before running anything because tests and the dev server fail without it, and never edit a migration after it has merged. Both name a file, an action and a consequence.
How should a monorepo split its CLAUDE.md files?
Root plus one per package, the layout Anthropic documents for large codebases. The root carries rules that apply everywhere; each package carries only its own stack's conventions. Because subdirectory files load on demand, a session working in packages/api never pays for the frontend's rules.
# monorepo/CLAUDE.md — applies in every package
Run package scripts from the package directory, not the repository root.
Prefix commit subjects with the package name, e.g. `api: add rate limiting`.
Never edit files under `packages/*/generated/`. Run `pnpm codegen` in that package instead.
Shared types live in `packages/shared`. A cross-package import of anything else is a bug.
# monorepo/packages/api/CLAUDE.md — only loads when Claude opens code here
Copy `.env.example` to `.env` before running anything. Tests and the dev server fail without it.
Write queries with the Knex query builder. Never put raw SQL strings in route handlers.
Never edit a migration after it has merged. Add a new migration instead.
Integration tests need `docker compose up db`. They are excluded from `pnpm test` by default.
Where you launch matters. From the repository root, only the root file loads at launch and package files arrive as Claude reads them. From packages/api/, that file plus every ancestor loads immediately and no sibling package ever enters context. For focused work, launching inside the package is cheaper.
If another team's file keeps loading, exclude it by glob rather than deleting anything:
{
"claudeMdExcludes": [
"**/packages/web/**",
"**/packages/legacy-*/**"
]
}
Put that in .claude/settings.local.json if the exclusion is yours alone. Patterns match absolute paths, so relative-style ones need a leading double-star. Managed policy files cannot be excluded, by design.
A second mechanism works from the other end. A file in .claude/rules/ with a paths: frontmatter field loads only when Claude touches a matching file, wherever it lives:
---
paths:
- "src/api/**/*.ts"
- "src/handlers/**/*.{ts,tsx}"
---
# API rules
- Every endpoint validates its input with zod before touching the database.
- Errors use the shared `ApiError` shape. Never return a bare string.
Per-directory files put conventions next to the code and let directory owners maintain them. Path-scoped rules centralise everything in one .claude/ directory and suit rules that apply to scattered paths. Both load lazily, so pick on where you want the file to live, not on capability.
What does a bad CLAUDE.md look like?
Composed from patterns that recur across shared templates. Nothing in it is wrong. All of it is wasted.
# My Project
This project is a web application built with Next.js, a popular React framework
created by Vercel. React is a JavaScript library for building user interfaces.
## Project Structure
- `/src` — source code
- `/src/app` — Next.js App Router pages
- `/src/components` — React components
- `/src/lib` — utility functions
- `/src/hooks` — custom React hooks
- `/public` — static assets
- `/tests` — test files
## Dependencies
next, react, react-dom, typescript, tailwindcss, zod, date-fns, clsx,
lucide-react, sonner, recharts, @tanstack/react-query
## Coding Standards
- Write clean, readable, maintainable code
- Follow SOLID principles
- Use meaningful variable names
- Add comments where appropriate
- Always consider edge cases and error handling
- Prioritise performance and accessibility
- Write tests for new functionality
## Git
- Use conventional commits
- Keep pull requests small
## Commands
- `npm run dev` — start the dev server
- `npm run build` — build the project
- `npm test` — run tests
What each block is doing to you:
| Block | Verdict |
|---|---|
| The Next.js and React explainer | In the training data. Two sentences of pure cost. |
| Project Structure | Claude can list the directory. The docs put file-by-file descriptions in the exclude column. |
| Dependencies | package.json restated, stale on the next install. |
| Coding Standards | Unfalsifiable. No diff visibly violates it, so none of it steers anything. |
| Git | True, generic, already the model's default. |
| Commands | The one useful block, and it adds nothing to the scripts field. |
The rewrite is shorter, not longer: the dev server is on 3001 because 3000 is taken, build:check is the gate rather than build, 25 specs need a database, nobody edits a migration that has run. Ten lines, each one something you would otherwise retype next week.
Do Skills change what belongs in CLAUDE.md?
Yes, and this is the most recent shift worth acting on. Anthropic's skills documentation now states plainly that "Custom commands have been merged into skills." A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both produce /deploy and behave the same; existing command files keep working, and on a name collision the skill wins.
The consequence is a sharper boundary. Skills load on demand; CLAUDE.md loads every session. The split is by cost, not topic, and the docs give the trigger directly: create a skill when you keep pasting the same instructions into chat, "or when a section of CLAUDE.md has grown into a procedure rather than a fact."
| CLAUDE.md | .claude/rules/ | Skill | |
|---|---|---|---|
| Loads | Every session | Every session, or when matching files open | On demand, invoked or judged relevant |
| Scope | Whole project | Scoped by paths: glob | Task-specific |
| Best for | Core conventions and build commands | Language or directory-specific guidance | Reference material and repeatable workflows |
Concretely: a six-step release checklist belongs in a skill, where its body costs nothing until someone runs it.
---
name: release
description: Cut a release — changeset, version bump, tag, publish
disable-model-invocation: true
---
1. Confirm `main` is clean and CI is green.
2. `pnpm changeset version`, then review the generated CHANGELOG diff.
3. `pnpm build && pnpm size` — the size gate must pass before tagging.
4. Commit as `chore: release`, tag `v$(node -p "require('./package.json').version")`.
5. `pnpm publish --access public`.
6. Open a release note in GitHub from the changeset entries.
What stays in CLAUDE.md is the one fact every session needs: releases go through the release skill, never by hand. One line, pointing at a body that loads only when used.
How do you keep a CLAUDE.md honest as the repo drifts?
A stale CLAUDE.md is worse than none, because a model told the wrong thing confidently acts on it. If the file says the dev server is on 3000 and you moved it last quarter, Claude keeps telling you the port is in use and keeps being wrong about why.
Four habits, in rough order of payoff:
- Review it in pull requests. Treat it as documentation that ships with the code, so a change invalidating a line updates that line in the same diff. The only habit that scales.
- Run
/doctoron a checked-in file. Per the docs it proposes cuts to whatever it can derive from the codebase, while protecting gotchas and rules that depart from tool defaults. Needs Claude Code v2.1.206 or later. - Revisit after major model releases. Instructions written around an older model's limitation become overhead once a newer model handles the case. The docs use a rule forcing single-file refactors as their example.
- Add a
Stophook that proposes updates. It receives the session transcript path when Claude finishes, so a script can suggest edits while the gap is fresh.
A thirty-second drift audit, from the repository root:
wc -l CLAUDE.md .claude/CLAUDE.md 2>/dev/null # over 200 lines? start cutting
# Every script the file tells Claude to run:
grep -ohE '(npm|pnpm|yarn) run [a-z0-9:_-]+' CLAUDE.md packages/*/CLAUDE.md | sort -u
# Every script that actually exists:
node -p "Object.keys(require('./package.json').scripts || {}).join('\n')"
Every command named in the file should still exist in that scripts list. When one does not, you have found a line that has been lying to Claude for months.
One check for any repo that already serves other agents: Claude Code reads CLAUDE.md and does not read AGENTS.md. The documented pattern is a thin CLAUDE.md importing the other file, keeping one source of truth.
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
# Or a symlink, if you have nothing Claude-specific to add.
# Windows needs Administrator privileges or Developer Mode; use the import there.
ln -s AGENTS.md CLAUDE.md
Where does a prompt library fit alongside CLAUDE.md?
Mostly it does not, and the boundary is worth stating. A CLAUDE.md is repository state: it belongs in git, it is scoped to one codebase, and its whole value is that specificity. Nothing about it wants to live in a general prompt manager.
What does cross the boundary is the other half of your prompting: reusable instructions not about any one repo. Code review framings, refactor briefs, the phrasing that reliably makes a model ask questions first. Those are portable and identical in every project, which is the argument for treating prompts like versioned assets. Our own product is a prompt library and enhancer with an MCP server Claude Code connects to, so its tools appear as slash commands beside your skills. That is the genuine overlap, and it is not a CLAUDE.md manager.
Connection details rather than pitch: the MCP inside Claude Code guide, and server-side prompt templates for publishing shared prompts as slash commands. For getting an AI to explain a codebase it has never seen, this walkthrough beats any template, and the constraints-over-aspirations discipline transfers to no-code builders too.
Stop rewriting prompts. Start shipping.
Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.
Create An AccountStart with twelve lines
The best version of this file grew out of a real session where Claude got something wrong. Run /init for a skeleton, delete everything it inferred from the directory listing, keep the commands you had to look up, then add a line each time you catch yourself typing the same correction twice.
Inherited a long one? Do not rewrite it. Run /doctor, take the trims, and read what survives against one question: would removing this line cause a mistake? What passes is your template. What does not was costing you attention you wanted spent elsewhere.
Sources. Anthropic's Claude Code documentation: /docs/en/memory for locations, load order, imports, size limits, exclusions and compaction; /docs/en/skills for the commands-to-skills merge; /docs/en/best-practices for the include and exclude table; /docs/en/large-codebases for monorepo layout and claudeMdExcludes; /docs/en/features-overview for the rules and skills comparison. All accessed August 27, 2026 on the code.claude.com host, since the older platform.claude.com paths for Claude Code now return 404. Version-gated features are dated in the docs, so re-check anything version-specific against the live page.