CLAUDE.md Explained: Teach Claude Code Your Project Once
13 min read
Every new Claude Code session starts with an empty head. You tell it to use pnpm, not npm. You tell it where the tests live. You tell it not to touch the generated folder. Tomorrow you tell it all of that again.
CLAUDE.md is the place you write down what you would otherwise re-explain.
It is a plain text file in Markdown. Claude Code reads it at the start of every session, so whatever is in it is already known before your first prompt. This guide shows where the file goes, how to write one Claude follows, and what to keep out of it.
What CLAUDE.md is, and what it is not
Each Claude Code session begins with a fresh context window. Two mechanisms carry knowledge from one session to the next:
| CLAUDE.md | Auto memory | |
|---|---|---|
| Who writes it | You | Claude |
| What goes in it | Instructions and rules | Learnings and patterns it picks up |
| Loaded | Every session | Every session (first 200 lines or 25 KB) |
| Best for | Coding standards, workflows, project layout | Your corrections and preferences |
Both are loaded as context. That word matters: Claude reads CLAUDE.md and tries to follow it, but it is not a setting that is enforced. A vague or contradictory line can be ignored. We come back to that in the troubleshooting section, because it decides how you should write the file.
Already have an AGENTS.md?
If your repository has an AGENTS.md written for other coding agents, Claude Code can read it in place of a CLAUDE.md, as long as there is no CLAUDE.md or CLAUDE.local.md in your working directory or above it. If both exist, Claude reads the CLAUDE.md files only. To use both, import the AGENTS.md from your CLAUDE.md. Reading AGENTS.md directly needs Claude Code 2.1.277 or later.
Where the file goes
There are four places, and they stack. Claude loads them from the broadest scope to the most specific, so what is closer to your project is read last.
OrganizationJust you, this project
- Managed policySet by IT for everyone in the organization
- User~/.claude/CLAUDE.md, your preferences in every project
- Project./CLAUDE.md or ./.claude/CLAUDE.md, shared with your team in git
- Local./CLAUDE.local.md, personal to this project, kept out of git
The two you will use are the project file and the user file.
- Project file. Put
CLAUDE.mdat the root of your project, or in a.claudefolder at the root. Commit it, so everyone who works on the project gets the same instructions. Write what is true for anyone: build commands, conventions, project layout. - User file.
~/.claude/CLAUDE.mdfollows you into every project. Use it for personal habits, such as how you like explanations to be phrased. - Local file.
CLAUDE.local.mdis for notes that are yours and specific to one project, like a sandbox URL. Add it to your.gitignoreso it is not committed.
Claude also looks in the folder you launched from and every folder above it. If you start in foo/bar/, it loads foo/bar/CLAUDE.md and foo/CLAUDE.md. Files in folders below you load later, on demand, the first time Claude reads or edits a file in that subfolder.
Start with /init
You do not have to write the first version by hand. Inside a session, run:
> /initAnalyzing your codebase...Created CLAUDE.md with build commands, test instructions and conventions it found.
Claude Code reads your project and writes a CLAUDE.md with the build and test commands and conventions it discovers. If a CLAUDE.md already exists, /init suggests improvements instead of overwriting it. Treat the result as a first draft. Your job is to add what Claude could not have found out on its own.
To confirm that the file loaded, run /context in a session and look under Memory files.
What belongs in the file
A good test, before you write any line, has two questions:
- 1
Could Claude find this by reading the code?
Folder layout, the test framework, the way existing components are built: Claude reads these in seconds. Writing them down adds weight and no value.
- 2
Would it actually go and look?
Some facts are in the repo but take minutes to dig out, and Claude would dig again every session. Those are worth a line.
If both answers are yes, leave the line out. What is left is information that was never in the code, or that costs real time to rediscover:
The exact commands to build, test and lint, with the flags you use
A decision your team made in a meeting that the code does not show
The environment variable or local service your tests need
A convention that differs from the tool's default, and why
Things to never touch, such as a generated folder
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. That is the signal the fact belongs in the file.
An example worth copying
Here is a short project file. Notice how every line is something you could verify, and how little describes the architecture.
# Project notes
## Commands
- Install: pnpm install (never npm or yarn)
- Dev server: pnpm dev (port 3000)
- Tests: pnpm test -- --run, run before every commit
- Typecheck: pnpm typecheck, must pass before a pull request
## Conventions
- 2-space indentation, double quotes
- API handlers live in src/api/handlers/
- Do not edit anything in src/gen/, it is generated by pnpm codegen
## Gotchas
- Integration tests need a local Redis: docker compose up redis
- Dates are stored in UTC, formatted only in the UI layer
That is 15 lines, and every one earns its place.
How to write lines Claude follows
Because CLAUDE.md is context and not configuration, the way you word a line decides whether it is followed. Write instructions concrete enough to check.
| Vague | Concrete |
|---|---|
| Format code properly | Use 2-space indentation |
| Test your changes | Run npm test before committing |
| Keep files organized | API handlers live in src/api/handlers/ |
| Be careful with the database | Never run migrations against production, use the staging URL in .env.staging |
Then keep the file in shape:
- Short. Aim for under 200 lines per file. Longer files use more context and Claude follows them less reliably.
- Organized. Group related lines under Markdown headers and bullets. Claude follows structure better than dense paragraphs.
- Consistent. If two lines disagree, Claude may pick one at random. Read your files now and then, including those in subfolders, and delete anything outdated.
Shouting does not help
Adding IMPORTANT or ALL CAPS to a line Claude keeps missing tends to make it over-apply the rule. If a line truly cannot bend, it does not belong in CLAUDE.md at all. It belongs in a hook or a deny rule, which Claude Code enforces every time no matter what the model decides.
To have Claude audit your instruction files for outdated or conflicting lines, run /doctor prompt-audit. It reports findings and proposes edits, and changes nothing until you ask. It requires Claude Code 2.1.283 or later.
Importing other files
CLAUDE.md can pull in other files with an @ before the path. The imported file loads alongside the CLAUDE.md that mentions it.
See @README for the project overview and @package.json for the npm commands.
# Additional instructions
- git workflow: @docs/git-instructions.md
Relative paths resolve from the file that contains the import. Imports can import other files, up to four levels deep. The @ is only read outside code spans, so wrap a path in backticks if you want to mention it without importing it.
Imports are good for organization, but they do not shrink the context: imported files still load in full. For personal instructions you want in several copies of the same repository, import a file from your home folder, such as @~/.claude/my-project-instructions.md. The first time a project imports a file from outside the working directory, Claude Code asks for your approval.
When one file gets too long
At some point the file grows past what every session needs. You have four tools, each for a different job.
| Tool | Use it for | Loads |
|---|---|---|
| CLAUDE.md | Facts needed in every session | Every session |
Rules in .claude/rules/ | Instructions for one part of the codebase | When Claude touches matching files (if scoped) |
| Skills | Multi-step procedures, team playbooks | Only when used or relevant |
| Hooks | Things that must always or never happen | Run by Claude Code itself |
Rules scoped to certain files
Put one Markdown file per topic in .claude/rules/, such as testing.md or api-design.md. To make a rule apply only to certain files, add a paths field at the top:
---
paths:
- "src/api/**/*.ts"
---
# API rules
- Every endpoint validates its input
- Use the standard error response format
A rule without paths loads every session. A scoped one loads when Claude reads or edits a matching file, which keeps the instructions out of the way the rest of the time.
If a block in CLAUDE.md is a multi-step procedure, such as how to prepare a release, move it to a skill instead. Skills load only when they are used.
Auto memory: the notes Claude keeps for itself
Besides the file you write, Claude Code can keep notes on its own. Auto memory is on by default in local sessions. As Claude works, it saves four kinds of notes: about you (role and preferences), feedback (corrections and approaches you confirmed), the project (decisions and deadlines not visible in the code), and references (where to find things outside the project).
It does not save what it can read from the code, or what your CLAUDE.md already says. You will see messages like "Saved 2 memories" in the session. The notes are plain Markdown under ~/.claude/projects/, and the first 200 lines or 25 KB of the index file load at the start of each session.
Run /memory to see every instruction file and the auto memory folder, to open any of them in your editor, and to switch auto memory on or off. If you tell Claude "always use pnpm, not npm", it saves that to auto memory. To put something into CLAUDE.md instead, say so: "add this to CLAUDE.md".
Inside Claude Tutorial
Writing down what you would otherwise repeat
Turning the same correction into a standing instruction is a habit that pays off in any kind of work with Claude, not only in code, and it is one the app teaches step by step.
When Claude does not follow it
Work through these in order. They solve most cases.
- 1
Check the file actually loaded
Run
/contextand look under Memory files. If your file is missing there, Claude cannot see it. A CLAUDE.md in a subfolder will not appear at launch because it loads on demand. - 2
Make the line more specific
Replace "format code nicely" with "use 2-space indentation". A line you can verify is a line Claude can follow.
- 3
Look for contradictions
Two files that say different things about the same behavior leave Claude guessing. Check the project file, the user file and any rules together.
- 4
Cut the length
A long file dilutes every line. Move the part about one area into a scoped rule and trim what Claude could read itself.
- 5
Enforce it if it must happen
If an instruction has to run at a fixed point, such as before every commit, write it as a hook. A hook is run by Claude Code, so the model cannot skip it.
Two extra cases are worth knowing. After a /compact, the CLAUDE.md at your project root is read again from disk, so it survives. An instruction you only gave in conversation does not survive, so move it to the file. And when a CLAUDE.md in a subfolder is very long (more than about 40,000 characters in a smaller context window), Claude receives only the start of it, so keep those short.
Frequently asked questions
Where do I put CLAUDE.md?
At the root of your project (./CLAUDE.md) or in ./.claude/CLAUDE.md. Put personal preferences for all projects in ~/.claude/CLAUDE.md. Use ./CLAUDE.local.md, added to .gitignore, for private notes about one project.
How long should a CLAUDE.md be?
Aim for under 200 lines. If you are over, Claude Code shows a warning at startup and in /status. Move area-specific parts into scoped rules and cut what Claude can read from the code.
Is CLAUDE.md the same as a system prompt?
No. CLAUDE.md is delivered as a message after the system prompt. Claude tries to follow it, but there is no guarantee of strict compliance. For instructions that must hold every time, use a hook or a permission rule.
Should I commit CLAUDE.md to git?
Yes for the project file, so the whole team shares it and it improves with every correction. No for CLAUDE.local.md, which is personal.
Does Claude read CLAUDE.md in subfolders?
Yes, on demand. It loads a subfolder's file the first time Claude reads or edits a file in that folder, and shows a Loaded line with the path.
What is the difference between CLAUDE.md and a skill?
CLAUDE.md is for facts needed in every session. A skill is a procedure or playbook that loads only when it is invoked or relevant, so it does not use space the rest of the time.
Your CLAUDE.md checklist
The file is at the project root and committed, with a separate local file in
.gitignorefor anything personalIt holds your build, test and lint commands exactly as you run them
Every line passes the test: Claude could not learn it from the code, or would waste time rediscovering it
No two lines contradict each other, and the file is under 200 lines
/contextlists the file under Memory files
Continue reading
- Claude Code for Beginners: Install, Sign In and Run Your First Task if you have not started a session yet.
- Claude Code Best Practices: Habits That Get Better Results for prompts, checks and context management.
- Claude Code Permission Modes and Plan Mode, Explained for deciding what Claude may do without asking.
- Claude Projects: Context That Sticks Around for the same idea in the Claude app: standing instructions kept with a project.
