The Anatomy of a Great CLAUDE.md File (2026 Guide)
Your CLAUDE.md is the highest-leverage file in any Claude Code project. The five rules, a real example dissected, when to split with .claude/rules/, and a linter skill that audits your own file.
Your `CLAUDE.md` is the single highest-leverage file in any project that uses Claude Code. Written well, it makes every session smarter: Claude knows your build commands, respects your conventions, and stops reinventing patterns you already settled on. Written poorly, it is context tax — tokens you pay for on every session that deliver nothing.
Most developers who use Claude Code have never seriously designed their `CLAUDE.md`. They ran `/init`, kept what it generated, and moved on. That works, but it leaves 80% of the value on the table. This article walks through the five rules that separate a useful `CLAUDE.md` from a great one, deconstructs a real one from a live project, shows when to split into `.claude/rules/`, and hands you a bonus skill that audits your own file for common problems.
If you have not yet set up Claude Code at all, start with our Claude Code hub guide for the 30-minute quickstart. This article assumes you already have a working installation.
Why CLAUDE.md is not a system prompt
A common misconception: because `CLAUDE.md` controls Claude's behavior, it must be the system prompt. It is not. `CLAUDE.md` content is delivered as a user message, delivered after the system prompt, at the start of every session. That distinction matters. System prompts are enforced by the model provider. User messages are context — Claude reads them, tries to follow them, but there is no guarantee of strict compliance, especially for vague or conflicting instructions.
The practical consequence: `CLAUDE.md` shapes behavior, it does not enforce it. For real enforcement (blocking dangerous commands, requiring tests before commits), you use hooks or managed `permissions.deny` settings. Both are deterministic. `CLAUDE.md` is not.
This is also why specificity matters so much. If you write 'format code properly', Claude makes its best guess about what you mean. If you write '2-space indentation, single quotes, trailing commas', Claude has nothing to guess about. The stronger your wording, the more consistent the output.
The four scopes — where CLAUDE.md files live
Claude Code walks up the directory tree from your current working directory, concatenating every `CLAUDE.md` and `CLAUDE.local.md` it finds. More specific locations take precedence over broader ones. Understanding the scopes lets you put each rule where it belongs.
CLAUDE.md scopes, from broadest to narrowest
- Managed policy — deployed organization-wide by IT or DevOps via MDM, Group Policy, or Ansible. Location: `/Library/Application Support/ClaudeCode/CLAUDE.md` on macOS, `/etc/claude-code/CLAUDE.md` on Linux, `C:\\\\\\\\Program Files\\\\\\\\ClaudeCode\\\\\\\\CLAUDE.md` on Windows. Cannot be excluded by users.
- User personal at `~/.claude/CLAUDE.md` — your preferences across every project on your machine. Good place for code style defaults, shortcut abbreviations, 'always prefer pnpm over npm.'
- Project team at `./CLAUDE.md` or `./.claude/CLAUDE.md` — committed to git, shared with teammates. This is where your build commands, architecture, and project conventions live.
- Project local at `./CLAUDE.local.md` — gitignored, your per-project personal notes. Sandbox URLs, test credentials, WIP notes. Never commit.
Because all discovered files concatenate rather than override, you can layer them cleanly. Your personal `~/.claude/CLAUDE.md` says 'I prefer concise commit messages'; your project `./CLAUDE.md` says 'use conventional commits format'; both load, both apply, the project one wins on any direct conflict because it comes later in the walk-up order within the project directory.
The five rules of a great CLAUDE.md
After writing dozens of these files and reviewing many more, a pattern emerges. The good ones share five properties. The bad ones break at least one of them.
Rule 1: Under 200 lines
Anthropic's official guidance is clear: target under 200 lines per `CLAUDE.md` file. Longer files consume more context and — counterintuitively — reduce adherence. Claude starts to miss rules buried in the middle of long sections. If your file is over 200 lines, you have two splitting options: use `@path/to/file` imports to pull in referenced files on demand, or move path-specific rules into `.claude/rules/` (covered below).
Rule 2: Specific instead of general
Every sentence in your `CLAUDE.md` should be concrete enough to verify. If you cannot answer 'did Claude follow this?' with yes or no, the rule is too vague. One critical corollary: do not put code style rules in . Send a linter to do a linter's job. Code style instructions inflate your context window, degrade instruction-following uniformly, and are enforced inconsistently. Configure ESLint, Prettier, or Ruff — let your pre-commit hook enforce it deterministically. Reserve for what only Claude knows: architecture decisions, domain vocabulary, and workflow conventions that no formatter can capture.
Rewrites that matter
- 'Format code properly' → 'Use 2-space indentation, single quotes, no trailing semicolons'
- 'Test your changes' → 'Run `npm test` before committing; all tests must pass'
- 'Keep files organized' → 'API handlers live in `src/api/handlers/`. Types in `src/types/`. Utilities in `src/lib/`'
- 'Use modern JavaScript' → 'Target ES2022. No `var`. Prefer `for...of` over `forEach` when mutating. Use optional chaining over manual null checks'
Rule 3: Structure like a human reads
Claude scans `CLAUDE.md` the way humans scan documentation: top-down, looking for section headers, falling into bullet lists. Dense paragraphs get skimmed. Use markdown headers to group related rules. Use bullet lists for enumerations. Keep paragraphs to 2-3 sentences. If a section runs longer than 15 lines, break it into sub-sections with `###` headers.
Rule 4: No contradictions
When two rules contradict each other, Claude picks one arbitrarily. Review your `CLAUDE.md` files — including nested ones in subdirectories and any `.claude/rules/` — periodically, hunting for contradictions. The most common sources: a rule added last year that the team now does differently, a personal `~/.claude/CLAUDE.md` that disagrees with a project `./CLAUDE.md`, two imports that each define the same convention differently.
If you maintain a large project, schedule a quarterly `CLAUDE.md` review the same way you would review dependency versions. Your conventions drift; your instructions should drift with them.
Rule 5: CLAUDE.md is not a hard enforcement layer
This is the rule everyone learns the hard way. Your `CLAUDE.md` says 'never edit production config files directly' and yet one day Claude does exactly that because a chain of reasoning made it seem warranted. This is not a bug. `CLAUDE.md` is guidance, not enforcement.
For rules that must be enforced, use the right tool: `permissions.deny` in managed settings blocks tools at the system level; hooks with `exit 2` block specific commands like `Bash(rm *)` deterministically; managed policy CLAUDE.md files cannot be excluded by individual users, so organization-wide requirements go there, not in project CLAUDE.md. Use `CLAUDE.md` for how things should be done. Use settings and hooks for what cannot happen.
The target structure of a good CLAUDE.md
A strong `CLAUDE.md` follows a predictable shape. Here is the skeleton we recommend starting from, then adapt to your project:
That is 40 lines. If your first attempt blows through 200, you have scope creep. Push detailed procedures out into skills, path-specific conventions into `.claude/rules/`, and keep `CLAUDE.md` as the project's front-page.
Deconstructing a real CLAUDE.md
To make this concrete, here is the structure of the actual `CLAUDE.md` powering this site, GetuWork — publicly available in our repo. The full file is longer than the skeleton above because we have explicit SEO rules, a multilingual content structure, and specific editorial conventions. It still fits under 200 lines.
Sections in the GetuWork CLAUDE.md (roughly 180 lines)
- Project Vision — one paragraph on positioning and audience. This stays because every content decision should trace back to it.
- Tech Stack — versions and key choices (Astro 5, Tailwind 4 via Vite, custom i18n). No history, just current state.
- Commands — five lines listing dev/build/preview/deploy. Claude reaches here first.
- Architecture — route structure, i18n system, data layer. This is the map someone new would need to navigate the repo.
- Key Conventions — numbered list of rules (i18n first, Astro syntax rather than JSX, SEO rules). Numbers make it easy to reference later.
- Content Clusters — how we structure our content (pillar/child pages). This is specific to our editorial strategy and would be out of scope for most projects.
- Documentation Map — pointers into `docs/` for deeper references. Keeps `CLAUDE.md` short by outsourcing detail.
The critical choices: no history (we do not tell Claude what changed last month), no procedures longer than 5 steps (those live in skills), and heavy use of pointers into the `docs/` directory rather than inlining documentation. The file tells Claude enough to start. For anything deeper, it tells Claude where to look.
When to split into .claude/rules/
For larger projects, you can organize instructions into `.claude/rules/` — a directory of modular markdown files, each covering one topic. The structure looks like this:
Rules without frontmatter are loaded unconditionally, same priority as your main `CLAUDE.md`. The interesting feature is path-scoped rules — rules that only load into context when Claude is actually working on matching files. You declare scoping with glob patterns in YAML frontmatter:
src/api/**/*.ts This rule file only loads when Claude reads a file matching `src/api/**/*.ts` or `src/**/*.{ts,tsx}`. When Claude is editing CSS or markdown, these rules do not consume context. Your project gets deep, domain-specific guidance where it matters, without paying token cost everywhere.
Glob patterns support brace expansion (`{ts,tsx}`), recursive matches (`**`), and multi-pattern declarations. You can symlink a rules directory from a central location to share a standard rulebook across multiple repos — circular symlinks are detected and handled gracefully.
The @ import feature nobody uses
`CLAUDE.md` files can import other files with `@path/to/file`. The imported file is expanded into context at launch alongside the importing file. Paths are relative to the importing file unless absolute. Imports can recurse up to five hops deep.
The killer use case is the last line. A personal `CLAUDE.local.md` at the project root is gitignored, which means it only exists in the worktree where you created it. If you work across multiple git worktrees, you lose your personal notes every time. Importing from `@~/.claude/my-project-instructions.md` solves this — your personal preferences live in your home directory and every worktree imports them.
For multi-day sessions, Anthropic now recommends pairing `CLAUDE.local.md` with a `@CHANGELOG.md` import — a running log of decisions and WIP state that updates as you work. This acts as working memory bridging compaction events: when `/compact` fires, your permanent `CLAUDE.md` re-injects cleanly, and the changelog import restores session continuity. The May 2026 `/goal` command integrates naturally here: record the goal in `CHANGELOG.md`, invoke `/goal` to set a completion condition, and Claude works across turns until it holds.
The AGENTS.md compatibility pattern
Claude Code reads `CLAUDE.md`, not `AGENTS.md`. If your repo already has an `AGENTS.md` from Cursor, Continue, or another agent, you do not have to duplicate the content. Create a `CLAUDE.md` that imports it, then add your Claude-specific instructions below:
Both tools read the same `AGENTS.md` content. Claude Code gets the additional Claude-specific behavior below the import. No drift between the two.
The monorepo pattern — claudeMdExcludes
If you work in a monorepo, ancestor `CLAUDE.md` files from other teams can pollute your context. The `claudeMdExcludes` setting lets you skip them by absolute path or glob pattern:
claudeMdExcludes Add this to `.claude/settings.local.json` to keep the exclusion personal to your machine. Note that managed policy `CLAUDE.md` files cannot be excluded — organization-wide instructions always apply. This is intentional: it gives IT a way to enforce requirements no individual user can bypass.
Debugging: Claude is ignoring my CLAUDE.md
When a rule is not being followed, the debugging checklist has four steps. Run through them in order.
Debugging checklist
- Is the file being loaded? Run `/memory` in Claude Code. It lists every `CLAUDE.md`, `CLAUDE.local.md`, and rules file currently loaded. If your file is missing, Claude cannot see it. Check the file path and the walk-up behavior — `CLAUDE.md` files in subdirectories load on demand when Claude reads files in those subdirectories, not at launch.
- Is there a conflicting rule? Look across your CLAUDE.md, local CLAUDE.md, user-level CLAUDE.md, and any `.claude/rules/` files for instructions that contradict each other. When two rules conflict, Claude picks one arbitrarily.
- Is the rule specific enough? 'Use modern JavaScript' means nothing concrete. 'Target ES2022, no `var`, prefer `for...of` over `forEach` when mutating' is actionable.
- Has it survived compaction? Project-root `CLAUDE.md` is re-injected after `/compact`, but nested `CLAUDE.md` files in subdirectories are not re-injected automatically — they reload the next time Claude reads a file in that subdirectory. Instructions you gave in conversation (not in a file) are lost on compaction. Add them to `CLAUDE.md` to persist.
For deep debugging, use the `InstructionsLoaded` hook to log exactly which instruction files loaded, when, and why. It gives you a paper trail for every session and is the fastest way to diagnose weird path-specific loading behavior. If a session grows long and you suspect compaction has dropped nested instructions, use the Rewind menu ("Summarize up to here") to compress earlier context — project-root `CLAUDE.md` re-injects automatically, but conversation-level instructions do not survive; the Rewind menu is faster than `/compact` and gives you a preview before committing.
A linter skill you can install today
To put this all into practice, here is a skill that audits your `CLAUDE.md` against the five rules and reports what needs fixing. Save as `~/.claude/skills/claude-md-audit/SKILL.md`:
properly Invoke it with `/claude-md-audit` in any project with a `CLAUDE.md`. The skill reports on all five rules, surfaces contradictions, and points you at rules that would be better enforced as hooks. For teams onboarding a new project's `CLAUDE.md`, running this once saves a round of code review.
This skill uses the same `allowed-tools` pattern covered in our skills deep dive — Read, Grep, and Glob are pre-approved for this skill, so you are not prompted for permission on every file access during the audit. May 2026 update: if you package this into a plugin with a root-level `SKILL.md` (no `skills/` subdirectory), Claude Code now automatically surfaces it as a skill — no manual `/plugin` install step needed.
FAQ
What should I put in user-level versus project-level CLAUDE.md? User-level (`~/.claude/CLAUDE.md`) is for personal preferences that apply to every project: code style you prefer, shortcut abbreviations, 'prefer pnpm over npm.' Project-level (`./CLAUDE.md`) is for things specific to this codebase: build commands, architecture, naming conventions, rules code review catches most often.
Should my CLAUDE.md be committed to git? Yes for the project-root `CLAUDE.md`. It represents shared team knowledge and the whole team benefits from it. No for `CLAUDE.local.md`, which is personal and should be added to `.gitignore`. Running `/init` with the personal option handles this automatically.
Do small projects need a CLAUDE.md? Even 10 lines beats none. Minimum viable content: build commands, test command, and one or two conventions Claude would otherwise get wrong. The minute you find yourself typing the same correction twice in chat, that correction belongs in `CLAUDE.md`.
How long should I spend writing it initially? About 30 minutes for a first draft. Then iterate — every time you find yourself correcting Claude on the same thing twice, add that instruction. Over a month, a `CLAUDE.md` matures from a rough start into a file that represents exactly how your codebase wants to be edited.
How do I know if my CLAUDE.md is actually working? Observe whether Claude repeats the same mistakes across sessions. If a rule is in `CLAUDE.md` and Claude still breaks it: the rule is either not being loaded (run `/memory` to verify), in conflict with another rule, or too vague. The audit skill above catches the last two.
Where do I go next? Pair this with our deep dive on Claude Code skills to understand when to move knowledge out of `CLAUDE.md` entirely — skills load on demand, keeping your context lean for sessions where they are not needed. Beyond skills, explore the plugins ecosystem: as of May 2026, there are 425+ published packages in the `claude-code-plugins` namespace. Any plugin that ships a root-level `SKILL.md` (without a `skills/` subdirectory) is automatically surfaced as a skill when installed — the `--plugin-dir` flag lets you load plugins from a custom path for team-wide deployments.
Commands first — the single highest-ROI line in your `CLAUDE.md`. If your file has one section that pays for itself on day one, it is the commands block: `npm run build`, `npm test`, `npx eslint .`. Claude reads these first and uses them to validate every change it makes. Every other section improves the quality of the session; this one prevents broken code from landing at all.
Gostou deste artigo?
Receba nossos melhores guias e reviews de ferramentas na sua caixa de entrada toda semana. Junte-se a 5.000+ desenvolvedores que estão à frente da curva da IA.