CLAUDE.md: how to write one, best practices and a template
What a CLAUDE.md file is, where it lives, what to put in it and what not — with best practices from real projects, imports, .claude/rules and a template to copy.
Every Claude Code session starts with an empty memory. Whatever you explained yesterday — how to run the tests, where the API handlers live, that you use pnpm and not npm — is gone. CLAUDE.md is the file that fixes this. Here is what a CLAUDE.md file is, where it goes, what belongs in it, and the best practices that make Claude actually follow it, with a template you can copy.
1. What is CLAUDE.md
CLAUDE.md is a plain Markdown file with instructions that Claude Code loads into context at the start of every session. Think of it as the onboarding note you would give a new colleague: how the project is built, what the conventions are, what to never do.
One thing to understand early: Claude treats CLAUDE.md as context, not as enforced configuration. It usually follows it — and follows it more reliably the more specific and concise it is — but it is not a guarantee. When something must never happen, use permission rules or a hook, not a sentence in CLAUDE.md.
2. Where CLAUDE.md files live
| File | Scope | Shared? |
|---|---|---|
./CLAUDE.md or ./.claude/CLAUDE.md | the project | yes, commit it |
./CLAUDE.local.md | your personal notes for this project | no, add to .gitignore |
~/.claude/CLAUDE.md | you, in every project | no |
| managed policy file | everyone in the organization | set by IT |
How they load: Claude Code reads CLAUDE.md and CLAUDE.local.md from the directory where you start it and every directory above it, and puts them all into context — nothing overrides anything, the files are concatenated, the closest one last. CLAUDE.md files in subdirectories load on demand, the first time Claude works with a file there. That makes a short root file plus small CLAUDE.md files in big subprojects a natural fit for monorepos.
3. Create your first CLAUDE.md with /init
Do not start from an empty file. In your project, run:
/init
Claude analyzes the codebase and writes a starting CLAUDE.md with the build and test
commands and conventions it discovers. If a CLAUDE.md already exists, it suggests
improvements instead of overwriting it. Then cut and refine: keep what is right, delete
what Claude would figure out anyway, and add what it could not discover from
the code. To check what is loaded in a session, run /context and look
under Memory files.
4. What to put in CLAUDE.md (and what not)
A good test from the official docs: write down what you would otherwise re-explain. Add a line when Claude makes the same mistake a second time, when a code review catches something it should have known, or when you type the same correction you typed last session.
Belongs in CLAUDE.md:
- build, test, lint and run commands — exact, copy-pasteable;
- project layout: where things live, which folder is generated and must not be edited;
- conventions that are not obvious from the code;
- “always” and “never” rules: “never commit to main”, “always add a migration for schema changes”.
Does not belong:
- long step-by-step procedures — put them in a skill, which loads only when needed;
- rules for one part of the codebase — use a path-scoped rule (below);
- things Claude sees in the code anyway, general programming advice, and secrets.
5. CLAUDE.md best practices
- Be concrete enough to verify. “Use 2-space indentation” instead of
“format code properly”; “run
npm testbefore committing” instead of “test your changes”; “API handlers live insrc/api/handlers/” instead of “keep files organized”. - Keep it short. The docs recommend under 200 lines per file. Longer files cost context on every turn and reduce how well Claude follows them.
- Structure it. Headings and bullets, not paragraphs. Claude follows a short list better than a wall of text.
- Remove contradictions. If two instructions conflict, Claude may pick either. Review the file now and then — including nested CLAUDE.md files and rules.
- Say why, briefly. “Never edit
generated/— it is rebuilt bymake codegen” is followed better than a bare ban, because Claude knows what to do instead. - Treat it like code. Commit it, review changes to it, and update it when the project changes. An outdated CLAUDE.md is worse than none.
6. CLAUDE.md example and template
CLAUDE.md
# Project: Shop API
Node 22 + TypeScript, Fastify, PostgreSQL via Prisma.
## Commands
- Install: `pnpm install` (never npm)
- Dev server: `pnpm dev` (port 3000)
- Tests: `pnpm test` — run before every commit
- One test file: `pnpm test src/orders/orders.test.ts`
- Lint + types: `pnpm check`
## Layout
- `src/routes/` — HTTP handlers, one file per resource
- `src/services/` — business logic; routes stay thin
- `prisma/schema.prisma` — schema; every change needs `pnpm prisma migrate dev`
- `src/generated/` — generated, never edit by hand
## Conventions
- Validate all input with zod schemas in `src/schemas/`
- Errors: throw `AppError` from `src/errors.ts`, never raw `Error`
- Money is integer cents, never floats
## Never
- Commit to `main` directly
- Change a migration that is already merged — add a new one
Thirty lines, every line checkable, nothing Claude could not act on.
7. Imports, .claude/rules and AGENTS.md
Imports. CLAUDE.md can pull in other files with
@path, for example See @README.md for an overview. Imports
can nest up to four levels. They help organize, but do not save context — imported
files load together with the CLAUDE.md.
Path-scoped rules. For bigger projects, split instructions into files
in .claude/rules/. A rule with paths loads only when Claude
works with matching files:
.claude/rules/api.md
---
paths:
- "src/api/**/*.ts"
---
# API rules
- Every endpoint validates its input
- Use the standard error response format
AGENTS.md. Codex, OpenCode and other agents read
AGENTS.md. Recent versions of Claude Code read it too when the project has
no CLAUDE.md. If you want both, keep the shared rules in AGENTS.md and put
@AGENTS.md at the top of CLAUDE.md, followed by anything specific to
Claude. More in
Claude Code vs Codex vs
OpenCode.
8. When Claude ignores your CLAUDE.md
- Check it is loaded —
/context, section Memory files. - Make the instruction concrete. Vague rules are the first to be dropped.
- Shorten the file. In a 600-line CLAUDE.md, line 412 loses.
- Look for a conflict — another CLAUDE.md up the tree, a rule, or
your personal
~/.claude/CLAUDE.mdmay say the opposite. - Enforce what is critical. If it must never happen, use a deny permission rule or a hook. CLAUDE.md asks; rules and hooks enforce.
A good CLAUDE.md makes the agent predictable enough to leave alone for a while. With coden you can then really leave — the agent keeps working on your computer and asks your phone when it needs a decision.
Do you see it differently? Write to support@coden-app.com.