Docs
CLAUDE.md Examples That Actually Work
Four real CLAUDE.md files — Next.js, Python API, monorepo, CLI — plus file locations, imports, /init, and the patterns that make Claude Code ignore it.
CLAUDE.md is Claude Code's project instruction file — loaded into context at the start of every session in your repo. It's the highest-leverage file in the repository: a hundred good lines shape thousands of agent decisions. Here are four examples that hold up in real use, where Claude Code actually looks for this file, and the patterns that quietly break it.
Example 1 — Next.js app
# Agent Instructions
You are a senior engineer pairing with the maintainer. Skip beginner
explanations; flag real risks; push back with reasons.
## Conventions
- Server Components by default; "use client" only when hooks demand it.
- TypeScript strict stays on. No \`any\`, no \`as\` to silence errors.
- Mutations via Server Actions, not ad-hoc API routes.
## Workflow
- Before reporting done: run \`pnpm lint\` and \`pnpm build\`, and
exercise the change in the running app. Report actual results.
## Constraints
- Never read, print, or commit .env values. Names only.
- Change only what the task requires — note other issues, don't fix them.Why it works: every line is checkable. "Run pnpm lint" either happened or didn't. Compare that with "write clean code" — which an agent can neither follow nor violate measurably.
Example 2 — Python API
# Agent Instructions
You are a test-first backend engineer on a FastAPI service.
## Knowledge
- Postgres schema source of truth: alembic/ migrations, never models alone.
- The /internal/* routes bypass auth by design — they're firewalled.
## Workflow
- Bug fixes start with a failing test. Run one test: \`pytest path::test -x\`
- Migrations: \`alembic revision --autogenerate\`, review SQL before apply.
## Constraints
- Raise specific exceptions; bare \`except:\` is banned.
- No new dependencies without approval — state package, size, and what
it replaces.The /internal/* line is the kind that earns its place: it looks like a security bug to a fresh reader, and an uninformed agent would "fix" it.
Example 3 — Monorepo
# Agent Instructions
You are a minimalist engineer: smallest correct change, delete before add.
## Knowledge
Apps live in apps/, shared packages in packages/. Cross-package imports
go through package entry points — never deep-import internals.
## Workflow
- Changes to packages/* require checking every consumer before merging.
- Refactors land separately from behavior changes.
## Tools
- Everything runs through turbo from the root: \`turbo test --filter=web\`.
Never cd into a package and run its scripts directly.Example 4 — Small CLI or library
Single-package projects need less structure, not more — the whole point is that there's no architecture to explain.
# Agent Instructions
You are maintaining a small, single-purpose CLI. Prefer deleting code
over adding options.
## Knowledge
This is one npm package, published as \`snip\`. No monorepo, no server —
the CLI is the entire product.
## Conventions
- Zero runtime dependencies. Before adding one, ask whether 20 lines of
vendored code would do instead.
- Every flag needs a one-line doc string in \`src/cli.ts\` — that string
is also the \`--help\` output.
## Workflow
- Add a test in \`test/\` for a new flag before wiring it up.
- Run \`npm run build && npm pack --dry-run\` before calling a change
release-ready.
## Constraints
- Never bump the version in package.json — that's a human decision.Twelve lines of substance. Nothing here restates what package.json already says.
Where Claude Code looks for CLAUDE.md
Claude Code loads more than one file, and knowing the set helps you decide where a given rule belongs:
| Location | Scope | Shared with |
|---|---|---|
./CLAUDE.md or ./.claude/CLAUDE.md | Project | Team, via version control |
~/.claude/CLAUDE.md | User | Just you, across every project |
./CLAUDE.local.md | Local | Just you, this project only — gitignore it |
path/to/subdir/CLAUDE.md | Subdirectory | Team, for that area of the codebase |
Project and local files load from your working directory and every directory above it as soon as a session starts; a subdirectory's own CLAUDE.md loads on demand, the moment Claude reads a file underneath it. Your personal ~/.claude/CLAUDE.md applies to everything you touch, everywhere — put per-machine habits there, not project facts. CLAUDE.local.md is the release valve for the notes that are true for you but wrong for a teammate: a local database URL, a preferred test fixture, a scratch note you don't want reviewed. It loads alongside CLAUDE.md and is treated the same way — just keep it out of git. Organizations can also deploy a managed, org-wide CLAUDE.md that individual settings can't opt out of — the same mechanism IT teams use to push a security policy to every machine, out of scope for most teams but worth knowing exists if you're on one.
When files disagree
Multiple CLAUDE.md files are concatenated into context, not merged into one ruleset — nothing overrides anything automatically. If a root-level file and a subdirectory file give conflicting instructions, Claude may pick one arbitrarily rather than reconcile them for you, the same failure mode two contradicting bullets inside one file already have. This matters most in a monorepo like Example 3: a package's own CLAUDE.md should narrow or extend the root file, not quietly contradict it. If you're picking up ancestor CLAUDE.md files from a part of a large monorepo that isn't yours, they can be excluded per project or per user rather than edited out of a shared file — worth reaching for before you're tempted to just delete someone else's rules.
Importing other files with @path
A CLAUDE.md doesn't have to contain everything inline. Reference another file with @path/to/file and Claude expands it into context at session start:
See @README.md for the project overview and @package.json for available
scripts.
## Git workflow
@docs/git-instructions.mdBoth relative and absolute paths work; a relative path resolves against the file doing the importing, not your current directory. Imports can chain — an imported file can import another — up to four hops deep before Claude Code stops following the chain. Import parsing skips code spans and fenced code blocks, so if you want to mention a path without triggering an import, wrap it in backticks and it stays literal text instead of pulling the file in.
Drafting a first file with /init
If a repo has no CLAUDE.md yet, run /init inside a Claude Code session. It reads the codebase and writes a starting file with the build commands, test instructions, and conventions it can actually discover. If a CLAUDE.md already exists, /init proposes improvements instead of overwriting it, so it's safe to rerun after a big refactor. Treat its output as a first draft, not a finished file — it can't know that the /internal/* routes in Example 2 are intentional; only you can add that. If you'd rather start from vetted examples than a blank prompt, the Groundrules builder assembles a first draft from curated blocks instead of /init's codebase scan.
CLAUDE.md and AGENTS.md
Claude Code reads CLAUDE.md; on its own, it does not read AGENTS.md. If your repo already has an AGENTS.md for other tools, the common bridge is a CLAUDE.md that's one line:
@AGENTS.mdClaude loads the imported file at session start, the same way it would load inline content. Add Claude-specific instructions below the import if you need a handful:
@AGENTS.md
## Claude Code
Use plan mode for changes under src/billing/.One file stays the source of truth instead of two copies drifting apart. See what belongs in AGENTS.md if you're starting from neither.
What to put in, what to leave out
A quick filter before adding a line: would Claude plausibly get this wrong without being told? If the answer is no — because the code already shows it — leave it out. In practice:
Put in:
- Build, test, and lint commands, verbatim, not "use the usual command."
- Architecture decisions and boundaries the code doesn't advertise (which module owns what, what's frozen, what's intentionally weird).
- Rules you've corrected an agent on more than once — the second correction is the signal it belongs here, not in chat.
- Anything a new teammate would need on day one to avoid an easy mistake.
Leave out:
- Directory listings and type signatures — Claude reads the code.
- Framework tutorials or language basics.
- Aspirational style guidance nobody actually enforces in review.
- Anything that changes weekly; a stale rule is worse than none.
- Multi-step procedures that only apply to one corner of the codebase — those tend to age better as a comment near the code itself than as a permanent line loaded into every single session.
The anti-patterns
The essay. A 3,000-word CLAUDE.md costs its full length in tokens on every request, and the important rules drown. Under ~150 lines is the working range.
Vague adjectives. "Be careful with the database" gives the agent nothing to act on. "Schema changes go through migrations; direct SQL against production is never acceptable" does.
No commands. If the file doesn't say how to run tests, the agent reads package.json and guesses — sometimes wrong, always slower.
Stale facts. A file that says "we use yarn" two migrations after moving to pnpm is worse than no file. Treat CLAUDE.md like code: update it in the same PR that changes what it describes.
Everything is shouting. When half the file is bold ALL-CAPS warnings, nothing stands out. Reserve emphasis for the few rules that hold even when a request implies otherwise — and state the why, which travels further than volume. System prompts have the same failure mode — the fix is the same wording pattern either way.
Frequently asked questions
Does CLAUDE.md replace the system prompt?
No. CLAUDE.md content is delivered as a user message after Claude Code's system prompt, not as part of it. Claude reads it and tries to follow it, but treat it as strong context rather than enforced configuration — for anything that must run every time regardless of what Claude decides, that's a job for a hook, not a CLAUDE.md line.
What if my repo already has an AGENTS.md?
Add a one-line CLAUDE.md that imports it — a single line reading @AGENTS.md. Claude Code loads the imported content at session start the same way it loads inline text, so both files stay in sync without hand-copying. Append Claude-specific instructions below the import if you need a few.
How long should CLAUDE.md be?
Aim for well under 200 lines. Longer files cost more context on every request and adherence drops as they grow. Claude Code loads a CLAUDE.md up to 4 MiB and skips anything larger, but the practical ceiling is much lower than that — see the anti-patterns above.
Does Claude Code read CLAUDE.md files in subdirectories?
Yes. The project-root file (and any CLAUDE.local.md next to it) loads at the start of every session. A CLAUDE.md placed deeper in the tree loads on demand, the moment Claude reads a file in that subdirectory — useful for rules that only matter in one part of a large repo.
What's the difference between CLAUDE.md and CLAUDE.local.md?
CLAUDE.md is checked into version control and shared with your team. CLAUDE.local.md sits next to it, is meant for your .gitignore, and holds personal, project-specific notes — a local database URL, your own test fixtures. It loads alongside CLAUDE.md and is treated the same way; it just never leaves your machine.
Skip the blank page.
Groundrules assembles files like this from curated blocks — pick a starter pack, fill in your project facts, export.