What it is and why it matters
Every Claude Code session starts with an empty context. What you explained in the chat yesterday isn't there today. So you start over: “so, my app is…”. And the times you forget, it guesses: the tool, the folder, how much it's allowed to change.
That's what CLAUDE.md is for. It's a plain text file, in the project folder, with the rules you want to hold every time. Claude Code reads it at the start of every session, before your first message. That's why I call it the file Claude reads before anything else.
It matters because you write down once what you'd otherwise repeat every day. Claude starts out already knowing it, and you go straight to what you want to do.
One thing to know right away: it's an instruction, not a padlock. Claude reads it and tries to follow it, and the clearer the rules, the better it follows them. But to really block something, it isn't enough: I cover that in the questions at the bottom.
1. My file, ready to copy
Here's my file to copy, on an example app: a recipe book. It's ten lines. Replace the parts between < > with the ones from your project, and remove the < > symbols.
# <Recipe Book>: <recipe app> Stack: <Next.js and TypeScript> Code in <src/>, tests in <tests/> Don't touch <.env> or <the payments folder> Ask before deleting files Read before changing After every change: <npm test>, and tell me the result One change at a time Talk to me in English Write the code in English
I keep the lines without < > the same in every project. In fact, the ones that apply everywhere, like the language, I move to my user file: more on that in a moment.
2. The ten lines explained
Each line is there because it got rid of a problem I used to have often:
- What the app is. No more “so, my app is…” at every new session.
- What it's built with. It won't suggest tools other than the ones you already use.
- Where the code and the tests are. It doesn't go looking for them every time.
- What it must not touch. Keys and money stay yours: secret keys usually live in the .env file, and payments are the part where a mistake does the most damage. But it's an instruction, not a block: to really block it you need a deny rule or a hook. I cover that in the GUARDIA guide (strikt.fit/guardia).
- Ask before deleting. No surprise deletions.
- Read before changing. It understands what's there before rewriting it.
- The test command. It's the one that proves the app still works. And I ask for the result, not just for it to be run.
- One change at a time. Small changes: if something breaks, you know where.
- The language. It answers you in your language.
- The code in English. Names, functions and comments stay in English, the way anyone can read them.
These are all things you can't tell from the code, or can only tell by digging: that's exactly what's worth writing down.
3. Where it goes
The name is always CLAUDE.md. What changes is the folder, and the folder decides where it applies:
- In the project's main folder: ./CLAUDE.md, or ./.claude/CLAUDE.md. They're equivalent, pick one. It holds the rules for that project, and if the project is on git, whoever works on it with you sees them too.
- In your user file: ~/.claude/CLAUDE.md. The rules that apply to all your projects, like the language, go here. Only you see them.
Claude Code reads them at the start of every session, both of them: they add up, they don't replace each other. So don't repeat in the project what's already in your user file, and make sure they don't contradict each other: if two lines say opposite things, Claude may follow either one.
When you change a file, open a new session: that way you're sure it's working with the updated version.
4. How to create and edit it
- Open Claude Code in the project folder and type /init. It looks at your code and writes you a first CLAUDE.md, with the commands to build and test the project and the conventions it finds. If a CLAUDE.md already exists, it doesn't overwrite it: it suggests improvements.
- Then add the rules it can't guess on its own: what it must not touch, how you want it to work, which language to talk to you in. They're the ones from my file above.
- To edit it, type /memory. It shows you the memory files for the project and for your user. Pick the file and it opens in your editor; if it doesn't exist, it creates it.
- To check that it loaded, type /context in a new session and look at the list under Memory files. Your CLAUDE.md files should be there: if one is missing, Claude can't see it.
You can also have Claude write new rules itself. When you notice one is missing:
Add this rule to the project's CLAUDE.md: [the rule]. Write it in one line, short and precise.
How you say it matters. With “add it to CLAUDE.md,” it ends up in the file. If you just say “remember that…,” it usually saves it to its auto memory, which is something else: I explain it in the questions at the bottom.
5. Keep it short
Keep it short and precise: the clearer and fewer the rules, the more it follows them. The Claude Code documentation recommends staying under 200 lines per file: beyond that, the rules get followed less well.
Precise means you can check it. “Run npm test after every change” works better than “test the code properly.” “The code is in src/” works better than “keep the files organized.”
And then you have to keep it alive. I follow three rules:
- If you tell it the same thing twice, that's a missing line: add it.
- If a line is no longer true, remove it.
- If it's something Claude can see on its own by opening the code, there's no need to write it.
Common mistakes
- Leaving the /init file as it is. It's a starting point: add the rules you can't see in the code, like what not to touch and which language to use with you.
- Repeating in every project the rules that apply everywhere. Put them once in ~/.claude/CLAUDE.md.
- Writing vague rules, like “be careful.” Write things that can be checked: a command, a folder, a file.
- Treating it like a padlock. It's an instruction: to really block a file you need a deny rule in Claude Code's permissions or a hook.
- Changing it and carrying on in the same session, assuming Claude sees the change. Open a new session and check with /context.
Checklist
- CLAUDE.md is in the project's main folder
- The parts between < > now describe my project
- The command that runs the tests is in it
- The language is in ~/.claude/CLAUDE.md, not in every project
- In a new session, /context shows it under Memory files
- It's short, with no repeated or outdated lines
Frequently asked questions
Doesn't Claude Code already have its own memory?
Yes, auto memory, on by default: Claude takes notes on its own, for example about the corrections you give it, and reads them again in later sessions. The difference is who writes: you write CLAUDE.md, and it's the place for rules; Claude writes auto memory. With /memory you can open its folder or turn it off.
If I write “don't touch .env,” can I be sure it won't open it?
No. CLAUDE.md is context: Claude reads it and tries to follow it, but it doesn't stop it. For a real block there are the permission rules in Claude Code's settings: with a deny rule like Read(./.env), Claude Code keeps its file-reading tools from opening that file, whatever Claude decides. Keep the line in CLAUDE.md anyway: it tells Claude what to avoid even where you haven't set up a block.
My CLAUDE.md has gotten really long. What do I do?
First remove the lines that are no longer true and the ones Claude can work out from the code. If you're left with rules that only apply to one part of the project, you can move them into separate files in the .claude/rules/ folder: if you state at the top of the file which files they apply to, they're only loaded when Claude works on those files. Splitting it into several files with @path imports helps keep it organized, but doesn't make it lighter: imported files are loaded at the start too.