CLAUDE.md is the highest-leverage file in your repository: Claude Code reads it at the start of every session, before it looks at a single line of your code. Written well, it saves the agent twenty minutes of re-discovering your conventions on every task. Written badly, it burns tokens, dilutes attention, and can actively steer the model wrong.
Most CLAUDE.md files are written badly, and in a very specific way: they document things the agent could discover on its own and skip the things it never could. This guide covers how the file is loaded, the one rule that decides what earns a line, a complete example you can adapt, what to leave out (with the research behind each cut), and how to keep the file honest over time. If you want to skip ahead, our free CLAUDE.md generator produces a solid draft in about two minutes, no signup required.
What CLAUDE.md is and how Claude Code loads it
CLAUDE.md is a plain Markdown file that Claude Code automatically pulls into context when a session starts. There is no schema and no frontmatter: whatever you write becomes standing instructions for the agent. What makes it powerful is the loading hierarchy:
- Project memory (
./CLAUDE.mdat the repo root) is the main one: shared with your team, checked into git. Claude Code also walks up the directory tree, so in a monorepo a root CLAUDE.md and a package-level one both load, and CLAUDE.md files in subdirectories load on demand when the agent works with files there. - User memory (
~/.claude/CLAUDE.md) applies to every project on your machine. Personal preferences belong here (your commit style, your "never kill my processes" rules), not in the repo file, where they would be noise for teammates. - Imports let you split a large file: a line like
@docs/deploy-checklist.mdinlines another file at load time (up to five hops deep). Use them for content that only some sessions need.
Two workflow notes worth knowing: pressing # in a session lets you add a memory to a chosen file without leaving your task, and /init bootstraps a starter CLAUDE.md by scanning the repo. Treat /init output as a first draft to prune hard, not a finished file; we will get to why below.
The golden rule: only write what the agent cannot infer
Here is the mental model that fixes 90% of bad CLAUDE.md files: the agent can read your code. It can list directories, open package.json, grep for call sites, and run your test suite. Anything discoverable that way is a waste of your context budget, because you are paying tokens to tell the model something it would have found anyway.
What the agent cannot infer, no matter how good it gets, is everything that lives outside the code:
- Rationale. Why database access goes through the repository layer, not just that it does. A model that knows the reason applies the rule to cases you never wrote down.
- Pitfalls. The test suite that fails only outside UTC. The route that silently breaks on the edge runtime. The migration you must never regenerate from a template. These are scars, and scars are exactly what a new session lacks.
- Conventions that differ from defaults. The agent assumes standard tool behavior. If your project deviates (named exports only, a custom error helper, a nonstandard directory that must not receive new files), say so, and say why.
- Commands with non-obvious flags. Not
npm install, but the fact that your tests needTZ=UTC, or thatpnpm testruns in watch mode and CI needspnpm vitest run.
Before every line you write, ask: could Claude figure this out by reading the repo? If yes, delete the line. If no, keep it, and attach the reason.
A complete example
Here is a realistic CLAUDE.md for a typical Next.js + TypeScript + Prisma project. Notice that almost every line is either a command with a gotcha, a deviation from defaults, or a pitfall with its reason attached:
# CLAUDE.md
Guidance for Claude Code in this repository.
## Commands
- `pnpm dev`: dev server on :3000. Use this, not `next dev` directly,
because the script also runs env validation.
- `pnpm test`: Vitest in watch mode. For a one-shot run (CI, hooks)
use `pnpm vitest run`.
- `pnpm db:migrate`: applies Prisma migrations to the local Postgres.
Start it first with `docker compose up -d db`.
- `pnpm lint:fix` before committing; CI blocks on lint errors.
## Architecture notes
- App Router only. `pages/` still exists for two legacy webhook
endpoints; do not add new files there.
- All DB access goes through `src/server/repositories/`. Route
handlers never import Prisma directly, because the repository
functions carry the row-level tenancy filter.
- Feature flags come from `src/lib/flags.ts` and are cached for 30s,
so tests must stub `getFlag`, not the network call.
## Conventions that differ from defaults
- Named exports everywhere; default exports break `pnpm generate:api`.
- Use `invariant()` from `src/lib/invariant.ts` instead of throwing
raw errors: the global handler maps it to a 400 with a safe message.
- Dates are stored in UTC and formatted only in components via
`formatInTz`. Never format dates in server code; that caused the
double-booking bug in #482.
## Pitfalls
- `pnpm test` needs `TZ=UTC` (set in `.env.test`); without it the
booking specs fail only on machines outside UTC.
- The Stripe webhook route must stay on the Node runtime
(`export const runtime = "nodejs"`): the edge runtime cannot
verify webhook signatures.
That is around 40 lines, and a session that loads it starts with everything a senior teammate would tell a new hire on day one, and nothing else.
What to leave out, and the evidence
Every cut below traces to a published study or an official doc; the full list lives in our context-file linter rules post.
Raw /init boilerplate. The ETH Zurich AGENTS.md benchmark (138 tasks, four agents including Claude Code) found that auto-generated context files reduced agent success by roughly 2-3% while raising cost by more than 20%. They restate what the agent can discover, so you pay for the tokens twice: once to load them, once for the agent to verify them.
Directory trees. In the same benchmark, agents ignored pasted folder-structure dumps while paying roughly 14-22% more reasoning tokens for them. Claude Code's own /doctor trim now strips directory layouts. The agent will run ls; let it.
Forcing language. "IMPORTANT: You MUST ALWAYS…" was written to fix under-triggering on 2024-era models. Current models over-trigger on it: Anthropic's own guidance now says to rewrite "CRITICAL: You MUST use this tool when…" as a plain "Use this tool when…". A file with eight or more ALL-CAPS markers has no emphasis left, because everything is emphasized.
Vague quality prose. "Write clean code," "follow best practices," "be helpful." GitHub's study of 2,500+ agent instruction files found vagueness to be the number-one failure mode: agents act on specific, checkable instructions and skip hedged prose. If a style rule matters, anchor it to a command (ruff check --select D), or delete it.
Everything past line 200. Anthropic's memory docs now give an explicit target: keep CLAUDE.md under about 200 lines, because longer files measurably reduce adherence. There is also a 40,000-character hard limit. If you are over budget, move detail into @-imported files or delete the discoverable parts; do not fight for adherence with more capital letters.
Keeping it alive
A CLAUDE.md is living configuration, not documentation you write once. Three habits keep it useful:
- Update it at the moment of friction. When the agent does something wrong that a sentence would have prevented, add the sentence right then (
#makes this a five-second operation). This is how the pitfalls section grows real scars instead of hypotheticals. - Review it on model upgrades. Instructions are tuned to a model generation. The forcing language that helped Claude 3 hurts current models; a file nobody has reread since 2024 is probably steering the agent wrong today. Put a CLAUDE.md pass on your checklist for every major model bump.
- Prune as aggressively as you add. Rules accumulate; context budgets do not. If a convention became the default, or a pitfall was fixed, remove the line.
If your team also uses Cursor, Copilot, or Codex, do not maintain four divergent files by hand: write the model once and export one config for every agent, CLAUDE.md included.
Validate it before you commit it
You can check most of the rules in this post mechanically. Paste your file into the free CLAUDE.md linter, or run it offline:
npx promptarch lint CLAUDE.md
It grades the file 0-100 against ~30 research-backed rules: the 200-line budget, forcing language, generated boilerplate, directory-tree dumps, contradictory directives, and security checks (leaked keys, hidden-Unicode injection) that most reviewers never think to look for. It runs fully offline and needs no account.
Start with a draft, not a blank file
Two free ways to get going right now:
- Generate: the free CLAUDE.md generator asks for your stack, conventions, and restrictions, and produces a structured draft. No signup needed for your first one.
- Lint: already have a CLAUDE.md? Run it through the linter and see what a year of model changes did to your instructions. Also free.
Either way, the two minutes you spend beat every session where the agent has to rediscover your project from scratch.