Claude Code’s Secret Weapon: A Complete Guide to CLAUDE.md A developer who ignored CLAUDE.md for two months discovered that writing a proper project-memory file dramatically reduced correction cycles with Claude Code. CLAUDE.md is plain Markdown loaded at every session start, giving the model persistent context about architecture, conventions, and commands. Files are concatenated from the directory tree, not merged with strict precedence, and the author warns against context rot from overloading the file with situational details. I ignored CLAUDE.md for almost two months after I started using Claude Code seriously. I figured it was optional flavor text something for people who like tinkering with config files more than they like shipping code. Then I spent an entire Tuesday re-explaining, for what felt like the fortieth time, that our API routes use a specific error-response shape and that we’re on Postgres, not MySQL. That was the day I actually sat down and built one properly. My correction cycles dropped so noticeably in the following weeks that I genuinely felt a little embarrassed about how long I’d waited. This is the guide I wish someone had handed me that first week what CLAUDE.md actually is, how the loading hierarchy really works under the hood, and the mistakes that quietly wreck it for almost everyone who tries. At its core, it’s nothing exotic. A CLAUDE.md file is plain Markdown that Claude Code automatically loads at the start of every session, giving the model persistent project memory your architecture, your conventions, the commands it can’t infer just from reading the code. Think of it like onboarding a brilliant new hire who happens to have amnesia every morning. They know every language, every framework, every design pattern in existence but they don’t know that your team squashes commits before merging, that the utils package was deprecated eight months ago in favor of utils-v2, or that touching anything under src/billing/ requires plan mode first. CLAUDE.md is where you write that down, once, so you never have to say it again. Here’s the framing that made everything click for me: CLAUDE.md is RAM. Subagents and skills are disk. You don’t load your entire hard drive into memory the moment your computer boots you page things in as you need them. Your CLAUDE.md deserves the same discipline. It’s the precious, expensive, always-loaded tier of context. Anything situational a one off migration script’s quirks, a rarely-touched legacy module’s history belongs somewhere that loads on demand, not somewhere that eats tokens on every single turn, whether you’re touching that part of the codebase or not. Get this backwards, and you end up with what practitioners now call context rot a memory file so long that the instructions that actually matter get diluted into the noise, and adherence quietly drops without you noticing why. This is the part that surprised me most, because I’d assumed it worked like a typical config override system most specific wins, everything else gets ignored. It doesn’t quite work that way. When you start a session, Claude Code walks up the directory tree from your current working directory toward the repository root, collecting every CLAUDE.md file it finds along the way. Here’s the important detail: these files are concatenated, not merged with strict precedence. Every discovered file contributes to the active instruction set none of them get silently dropped. Files discovered lower in the tree, closer to where you’re actually working, get read later in that sequence, and in practice, later-read instructions tend to carry a bit more weight if two things conflict. But that’s a soft weighting effect, not a hard override which is exactly why writing clear, non-contradictory rules matters far more than trusting the load order to bail you out. The full hierarchy spans several scopes: Scope Location Shared with Enterprise Managed policy settings Entire organization Global user ~/.claude/CLAUDE.md Every project on your machine Project CLAUDE.md at repo root Your whole team checked into git Local CLAUDE.local.md Just you auto gitignored Directory-level Nested CLAUDE.md in subfolders Team members working in that subfolder Path-scoped rules .claude/rules/ .md Team, loaded only for matching file paths If you want to actually see what’s loaded rather than guessing, run /memory at any point in a session. It shows you exactly which instruction files Claude has loaded, their paths, and the order it read them in the single most useful debugging command I didn't know existed for my first month. The fastest path to a first draft is running /init in your project root. It analyzes your codebase and generates a starting CLAUDE.md automaticallyand if a repo already has an AGENTS.md, .cursorrules, or .windsurfrules file, /init reads those too and folds the relevant parts in. Here’s the counterintuitive part, and it’s the single biggest mistake I see people make: delete most of what it generates. The default output tends to state the obvious yes, Claude, I can see from package.json that this is a TypeScript project. Every line in that file competes for the model's attention with the actual instructions that matter. A generated file stuffed with things Claude could've inferred anyway isn't harmless; it's actively diluting the rules you need it to follow. There’s now tooling for exactly this problem running /doctor available from Claude Code v2.1.206 onward checks a committed CLAUDE.md and proposes trims: it cuts content Claude can already derive from the codebase itself, like directory layouts and dependency lists, while keeping the things that genuinely differ from tool defaults pitfalls, rationale, non-obvious conventions. After going back and forth on this more times than I’d like to admit, here’s what earns a permanent place in mine: Commands Claude can’t guess. Your actual build, test, and lint commands especially if they’re non-standard. Nobody infers npm run test:integration -- --runInBand from reading source files. Naming and structural conventions. Where features live, how files are organized, what pattern new components should follow. The things Claude keeps getting wrong. This is the real engine of a good CLAUDE.md. Every time you correct a mistake, ask yourself: should this be written down? If yes, just tell Claude directly “update your CLAUDE.md so you don’t make that mistake again” and it’ll add the rule itself. Over months, the file becomes a running record of every hard-won lesson your project has taught it. Non-obvious rationale. Not just what the rule is, but why “always import from @company/utils-v2, not @company/utils; the old package is deprecated and silently drops null values." The why is what stops the model from "helpfully" reverting your rule the next time it looks reasonable to do otherwise. Genuine guardrails. Which directories need plan mode before edits. Which files should never be touched without an explicit ask. Anything Claude can derive by actually reading your code. Your dependency list. A directory tree it can list itself in one tool call. Generic reminders that this is a React project, or that you use Git. All of it is just token tax with no payoff. The consequence of ignoring this is concrete, not theoretical: frontier models reliably follow only around 150 to 200 instructions well, and Claude Code’s own system prompt already spends roughly 50 of that budget before your file even loads. The consistent recommendation across the Claude Code community is to keep your CLAUDE.md under 200 to 300 lines shorter is genuinely better, not just tidier. For anything long enough to organize separately, Claude Code supports pulling in other files with @ syntax: See @README.md for project overview and @package.json for available commands. Git Workflow@docs/git-instructions.md Both relative and absolute paths work, and imports can nest recursively up to five hops deep. This is genuinely useful for splitting a large instruction set into composable pieces instead of one sprawling monolith but here’s the catch that trips people up: imports do not reduce context usage. Imported content is expanded inline at launch and counts against the active window exactly the same as if you’d pasted it in directly. Splitting your file into @imports is an organizational win, not a token-savings trick. One nice side effect: if your team already maintains an AGENTS.md the open, cross-tool standard also adopted by other coding agents you don’t need to duplicate it. Either symlink CLAUDE.md to AGENTS.md directly, or, more portably and required on Windows, where symlinks need admin privileges , just import it: @AGENTS.md Claude CodeUse plan mode for changes under src/billing/ . That keeps one shared source of truth for every AI tool your team uses, while still layering in Claude-specific behavior underneath it. This is the one I wish I’d found earlier. Any Markdown file placed in .claude/rules/ is loaded automatically alongside your main CLAUDE.md no import needed, discovered recursively through subdirectories, and committed to source control like everything else. The genuinely powerful part is frontmatter-based path scoping: ---paths: - 'src/routes/api/ / .ts'---API routes must validate input at the boundary and return the shared error shape. Rules without a paths field apply everywhere, all the time. Rules with a paths field only load into context when Claude is actually working with matching files. This is exactly how you keep your always loaded core file small while still having deep, specific guidance available exactly when it's relevant paging in from disk instead of hoarding everything in RAM. Since Claude Code v2.1.59, there’s a second memory system running alongside CLAUDE.md: Auto Memory . Claude proactively saves its own notes build commands it figured out through trial and error, debugging insights, preferences it picked up from your corrections to ~/.claude/projects/