How to Write CLAUDE.md: Claude Code's Most Important File
Master CLAUDE.md to give Claude Code persistent project context. Covers file hierarchy, effective instructions, auto memory, rules, and common anti-patterns.
How to Write CLAUDE.md: Claude Code's Most Important File
Key Takeaways#
- Every Claude Code session starts with zero memory. CLAUDE.md is the file that bridges sessions by giving Claude persistent project context.
- Multiple CLAUDE.md files stack across scopes — global, user, project, and local — all concatenated together, with more specific scopes taking precedence on conflicts.
- Keep each file under 200 lines. Vague instructions get vague results; write concrete, actionable rules instead.
- Use the
.claude/rules/directory for path-scoped rules with glob patterns, and the@path/to/importsyntax to pull in shared instructions without bloating context. - Start with guardrails, not a manual. Add rules incrementally based on what Claude actually gets wrong.
What CLAUDE.md Does and Why It Matters#
Claude Code is stateless. Every time you start a new session, Claude has no idea what your project is, what conventions you follow, or what mistakes to avoid. It re-reads your codebase from scratch every time.
CLAUDE.md is the single mechanism that fixes this. It is a markdown file that Claude reads at the start of every session before doing anything else. Think of it as onboarding documentation for an engineer who joins your team every single day and forgets everything overnight.
This is not optional. This is the single highest-leverage thing you can do to improve Claude Code's output quality. A good CLAUDE.md turns Claude from a generic coding assistant into a team member who knows your stack, your conventions, and your boundaries.
Without it, Claude guesses. With it, Claude knows.
File Locations and Scope Hierarchy#
Claude Code reads multiple CLAUDE.md files and concatenates them together. More specific scopes take precedence on conflicting instructions — they do not override, they layer.
| Scope | File Path | Who It Affects | Use For |
|---|---|---|---|
| Managed Policy | /Library/Application Support/ClaudeCode/CLAUDE.md | All users in the org | Org-wide rules, compliance, security guardrails |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | Everyone on the team (via git) | Team conventions, tech stack, architecture decisions |
| User | ~/.claude/CLAUDE.md | Just you, across all projects | Personal preferences, editor settings, workflow habits |
| Local | ./CLAUDE.local.md | Just you, current project only | Project-specific personal tweaks (add to .gitignore) |
All files are concatenated, not overridden. If your project CLAUDE.md says "use tabs" and your user CLAUDE.md says "use spaces," the more specific scope wins. But if they say different things about different topics, both apply.
Put team-shared rules in ./CLAUDE.md and commit it. Put personal rules in ~/.claude/CLAUDE.md. Put machine-specific or experimental rules in ./CLAUDE.local.md and gitignore it.
Writing Effective Instructions#
The quality of Claude's output is directly proportional to the quality of your instructions. Vague rules produce vague behavior. Concrete rules produce consistent results.
Good vs Bad Examples#
| Bad (Vague) | Good (Concrete) |
|---|---|
| Format code properly | Use 2-space indentation, no trailing commas |
| Test your changes | Run npm test before committing |
| Follow our architecture | Routes go in src/routes/, handlers in src/handlers/ |
| Don't make breaking changes | Always add new fields as optional; never remove existing fields |
| Write good commit messages | Use conventional commits: feat:, fix:, chore: |
The difference is specificity. Good instructions tell Claude exactly what to do. Bad instructions leave room for interpretation, and Claude will interpret differently than you expect.
Length Matters#
Keep each CLAUDE.md file under 200 lines. Every line you add consumes context window space in every session. Long files mean more context used and reduced adherence to individual rules. Be ruthless about cutting anything that Claude can figure out from reading your code.
Import System#
CLAUDE.md supports an import syntax to pull in instructions from other files without duplicating content:
@path/to/instructions.md
This is useful for shared conventions across multiple repos or large instruction sets you only want loaded conditionally. Key details:
- Maximum import depth is 5 hops. After that, further imports are ignored.
- Imports are resolved relative to the file containing the
@reference. - Compatible with
@AGENTS.md— Claude Code's agent configuration files can also be imported.
Use imports to keep individual CLAUDE.md files short while still having a rich instruction set. For example, your project CLAUDE.md can import a shared style guide that lives in a separate file.
.claude/rules/ Directory#
For rules that should only apply to specific files or paths, use the .claude/rules/ directory. Each file in this directory can include YAML frontmatter with a glob pattern to scope when the rule applies.
Example .claude/rules/typescript.md:
--- glob: "**/*.ts" --- - Use `interface` over `type` for object shapes - Prefer `unknown` over `any` - Always add return type annotations to exported functions
Example .claude/rules/tests.md:
--- glob: "**/*.test.ts" --- - Use `describe/it` style, not `test()` - Each test file must have at least one happy path and one error path
Rules without a glob field apply to the entire project, just like CLAUDE.md instructions. Use glob-scoped rules to avoid cluttering your main CLAUDE.md with path-specific details.
Auto Memory vs CLAUDE.md#
Claude Code has two persistence mechanisms. They serve different purposes and should not be conflated.
| CLAUDE.md | Auto Memory | |
|---|---|---|
| Who writes it | You (the human) | Claude (automatically) |
| What it contains | Instructions, rules, guardrails | Learned preferences, patterns observed across sessions |
| Scope | Defined by file location | Per-user, per-project |
| Control | Full — you edit it directly | Claude decides what to remember |
| When to use | Prescriptive rules Claude must follow | Observational notes Claude picks up over time |
Auto memory is Claude's learning mechanism. It records things like "this user prefers concise explanations" or "this project uses a specific error handling pattern." You do not edit it directly.
CLAUDE.md is your instruction mechanism. You write it, you control it, Claude reads it. Use it for rules, not observations.
If you notice Claude learning something wrong via auto memory, add a corrective rule to CLAUDE.md. Your explicit instructions always take precedence.
Common Anti-Patterns#
1. @-importing entire documentation files#
Do not do this:
@docs/api-reference.md @docs/architecture.md @docs/contributing.md
This bloats the context window with static content Claude may not need for the current task. Instead, tell Claude when to read those files:
- When modifying API endpoints, read docs/api-reference.md first - For architecture questions, check docs/architecture.md
This way, Claude only loads that context when relevant.
2. Prohibitions without alternatives#
Saying "Never use any" without saying what to use instead leaves Claude guessing. Always pair prohibitions with the correct action:
- Never use `any` — use `unknown` and narrow with type guards
3. Writing a manual instead of guardrails#
Do not start by documenting everything Claude might need. Start with the rules that prevent the most common mistakes. Add more rules when Claude gets something wrong. Your CLAUDE.md should grow from experience, not from speculation.
4. Contradictory rules#
If your project CLAUDE.md says "prefer functional components" and your user CLAUDE.md says "use class components," Claude will pick arbitrarily. Contradictory rules are worse than no rules. Audit your stacked files for conflicts.
5. Over-specifying obvious things#
Do not tell Claude things it can infer from your codebase. If your project is all TypeScript, Claude will figure that out. Spend your 200 lines on things Claude cannot infer — conventions, boundaries, and gotchas.
Getting Started: /init#
Claude Code includes a built-in command to generate a starting CLAUDE.md:
/init
This scans your project and produces a reasonable first draft based on your tech stack, file structure, and existing conventions. It is not perfect, but it gives you a solid foundation to edit.
For a more thorough interactive flow that walks you through multiple phases of project analysis:
CLAUDE_CODE_NEW_INIT=1 claude
Then run /init inside the session. This enables a multi-phase interactive generation process that produces a more detailed CLAUDE.md by asking you questions about your project.
Either way, treat the generated file as a starting point. Edit it ruthlessly. Cut what is obvious, strengthen what is vague, and add rules as you discover what Claude gets wrong in practice.
The Bottom Line#
CLAUDE.md is not a nice-to-have. It is the primary way you turn Claude Code from a generic assistant into a project-aware collaborator. Write it once, iterate as you go, and keep it sharp. The 30 minutes you spend on a good CLAUDE.md pays back in every session you ever run.