CLAUDE.md is a markdown file at the root of your repository. Claude Code reads it and prepends it
to the conversation, so it is context every agent has before it has read a single line of code.
Think of it as the note you would write for a competent contractor who starts on Monday and has never seen the codebase.
What actually goes in a good one
The test for every line: would an experienced developer get this wrong by reading the code?
If they would not, the line is costing you context and teaching nothing.
Things that pass the test:
- How to build, test and lint. The exact commands. Not "run the tests", but the command, including the flags that matter.
- Architectural rules and the reason for them. "The renderer never imports from main" is a rule. "The renderer never imports from main, because it is the untrusted boundary and a compromise there would have filesystem access" is a rule that survives being questioned.
- Non-obvious constraints. The dependency that must not be upgraded. The generated file that must not be hand-edited. The test that is slow for a real reason.
- Traps. The bug that has been reintroduced three times. The API that looks synchronous and is not.
- Conventions a linter cannot express. How errors are handled, what gets a comment, how commits are worded.
Things that fail it:
- A directory listing. The agent can list directories.
- A description of what each function does. The agent can read them, and your description will be wrong within a month.
- General coding advice. The model already writes tests.
- Aspirations. "We are migrating to X" is only useful if it says which half is which and what to do in new code.
The failure mode nobody warns you about
The stale line is worse than the missing line.
A CLAUDE.md that describes a directory structure you refactored last quarter does not simply fail
to help. It actively sends the agent to the wrong place, and it does so with authority, because the
agent has no reason to doubt a file the repository is offering as fact.
This is the argument for keeping it short. Every line is a line somebody has to keep true.
Length
A few hundred lines is a lot. If yours is longer, that is usually a sign it is documenting rather than instructing.
The good ones read like a list of constraints. The bad ones read like a README written for a human who has never used git.
Scope
Instructions can be layered: user-level, project-level, and local ones you do not check in. The project file is the one your team shares, so it is the one that must be true for everyone.
A per-directory file, in a subproject with different rules, is a good pattern for a monorepo, and it keeps the root file from having to caveat everything.
The thing to check in your own tooling
The Claude Code SDK defaults to loading no settings at all. A client that does not explicitly opt
in to user, project and local settings will not see your CLAUDE.md, will not see your project's
settings, and will not see your slash commands. It will then behave subtly differently from your
terminal on the same repository, and nothing about the symptom points at the cause.
If you write a client, opt in. If you use one, this is a reasonable thing to ask about.
Where Fleet fits
Fleet loads user, project and local settings, so a worktree's CLAUDE.md, its .claude/settings.json
and its slash commands all work exactly as they do in your terminal. That is one less way for the
app to disagree with the tool it is driving.
Fleet also writes a starting CLAUDE.md for projects created from a template, and it writes it
after the scaffolder has run so it never clobbers one the generator produced.