A CLAUDE.md file is how you stop re-explaining your project to Claude Code every session. It's a plain markdown file you drop in your project that gives Claude Code persistent instructions: your stack, your conventions, your build commands, the rules you want followed. Claude reads it at the start of every session, so you stop re-explaining your project every single time. Here's how to write one that actually helps, where to put it, and how to keep it from bloating.
If you're brand new to the tool, start with what Claude Code actually is and come back. This assumes you're already building and want your setup dialed in.
The fastest start: run /init
You don't have to write the first one from scratch. Open Claude Code in your project and run /init. Claude analyzes your codebase and generates a starting CLAUDE.md with the build commands, test instructions, and conventions it can discover on its own. If a CLAUDE.md already exists, /init suggests improvements instead of overwriting it. Treat the generated file as a first draft, then add the things Claude couldn't have known by reading the code, which is where the real value lives.
If you're coming from another tool, /init also reads existing Cursor rules, in .cursor/rules/ or .cursorrules, along with Copilot instructions, and folds the relevant parts into the generated file, so a migration doesn't start from a blank page.
Where to put it
CLAUDE.md files live in different places depending on how widely you want the instructions to apply. From broadest to most specific:
- User:
~/.claude/CLAUDE.mdholds personal preferences that apply to every project on your machine, like your code-style habits. - Project:
./CLAUDE.mdor./.claude/CLAUDE.mdis the team-shared file, committed to source control so everyone working on the repo gets the same context. This is the one most people mean. - Local:
./CLAUDE.local.mdis for your personal, project-specific notes, like your sandbox URLs or test data. Add it to.gitignoreso it never gets committed. - Managed: organizations can deploy a machine-wide policy file for company standards, which individuals can't override.
They stack rather than replace: all the files in your directory tree get concatenated into context, so a project instruction sits alongside your user instruction. To confirm what actually loaded, run /context and check the list under Memory files.
One naming note, because it trips people up. Claude Code reads CLAUDE.md, not AGENTS.md. If your repo already keeps an AGENTS.md for other coding tools, don't copy it across. Put @AGENTS.md as the first line of your CLAUDE.md and Claude loads that file at the start of the session, then reads any Claude-specific notes you add below it. A symlink works too if you have nothing Claude-specific to add.
What belongs in it
The best test for a CLAUDE.md entry is simple: is this something you'd otherwise re-explain in every session? Good candidates are your build and test commands, your coding conventions, the project's architecture and file layout, and any firm "always do X, never do Y" rules. The official guidance for when to add something is a great habit: add it the moment Claude makes the same mistake twice, or a code review catches something Claude should have known about your codebase, or you find yourself typing the same correction you typed last session.
What does NOT belong in it
This is where most bloated CLAUDE.md files go wrong. Three things do not belong:
- Multi-step procedures: a long "how to deploy" checklist should be a skill, not a permanent context tax on every session.
- Stuff that only matters in one part of the codebase: rules about your API layer shouldn't load while you're editing CSS. Put those in path-scoped rules under
.claude/rules/, which only load when Claude touches matching files. - Anything Claude can derive from the code itself: directory listings, dependency lists, and architecture overviews it can just read. Spending context to describe what's already in front of it is pure waste.
That last point is the one people miss, and it's exactly what tips a file over the edge into the territory we wrote about in the large-CLAUDE.md performance warning.
Write it so Claude actually follows it
Here's the part that separates a CLAUDE.md that works from one that gets ignored. The file is loaded as context, not enforced as configuration, which means how you write it changes how reliably Claude follows it. Three rules:
- Be specific enough to verify. "Use 2-space indentation" beats "format code properly." "Run npm test before committing" beats "test your changes." "API handlers live in src/api/handlers/" beats "keep files organized." Vague instructions get vague compliance.
- Structure it. Use markdown headers and bullets to group related rules. Claude scans structure the same way you do, so organized sections beat dense paragraphs.
- Stay consistent. If two rules contradict each other, Claude may pick one at random. Review the file periodically and cut anything stale or conflicting.
One more: keep each CLAUDE.md under about 200 lines. Longer files eat more context and, counterintuitively, reduce how well Claude follows them, because the signal gets diluted. If you need a hard guarantee that something happens, like a lint check before every commit, that's a job for a hook, not a CLAUDE.md line, since hooks run as actual commands regardless of what Claude decides.
A minimal example
Here's an example of a lean, effective project CLAUDE.md:
# MyApp
Next.js 15 + Postgres store-locator app.
## Commands
- Build: npm run build
- Test: npm test (Vitest)
- Lint: npm run lint (must pass before commit)
## Conventions
- 2-space indentation, no semicolons
- API handlers live in src/api/handlers/
- Use the shared db client from src/lib/db.ts, never new connections
## Rules
- Never commit secrets; keys live in .env (gitignored)
- Prefer server components; only add "use client" when you need interactivity
Short, specific, verifiable, structured.
The other half: auto memory
CLAUDE.md is the memory you write. Claude Code has a second memory system that writes itself, on by default, and it's worth understanding even though you don't manage it by hand. As you work, Claude saves its own notes, things like a build command, a debugging insight, or a preference it noticed you have, into a per-project folder at ~/.claude/projects/<project>/memory/. It doesn't save something every session; it decides what's worth keeping.
The division of labour is clean. CLAUDE.md is for instructions you want followed. Auto memory is for learnings Claude accumulates from your corrections without you lifting a finger. Both load at the start of every conversation. The one limit to know is that only the first 200 lines or 25KB of that folder's MEMORY.md index loads at startup, so Claude keeps that index short and files the detail into separate notes it reads on demand. Run /memory to browse, edit or delete any of it, or to switch the whole thing off if you would rather Claude used only what you wrote.
Keeping it lean over time
CLAUDE.md files grow. A few tools keep them healthy. Move situational depth into .claude/rules/ so it only loads when relevant. Know that @path imports help you organize a file into pieces but do not save any context, since imported files still load at launch. Use HTML comments for notes to human maintainers, since those get stripped before the file hits Claude's context. And run /memory anytime to browse and edit your files. Do this and your CLAUDE.md stays the sharp, load-bearing thing it's supposed to be, instead of the junk drawer it tends to become.
Anthropic's own guidance puts the target at under 200 lines per file, and the /doctor checkup will propose trims against a checked-in CLAUDE.md if you want a second opinion on what to cut.
Sources
Claude Code documentation: How Claude remembers your project - The official reference for CLAUDE.md file locations and load order, the /init and /memory and /context commands, the under-200-line size guidance, path-scoped rules in .claude/rules/, the @path import behavior, the note that CLAUDE.md is loaded as context rather than enforced configuration, the auto-memory system with its per-project storage and the 200-line or 25KB startup limit on the MEMORY.md index, and how to point Claude at an existing AGENTS.md.






