
Every time you close a Claude Code session, the entire context disappears. Stack details, port numbers, commit conventions — gone. The next session starts cold, and you spend the first ten minutes re-explaining what the project is before you can get anything useful done.
CLAUDE.md is the fix. It's a plain Markdown file that Claude Code reads automatically on startup, giving it a structured briefing before your first message. Set it up once, keep it current, and you stop losing tokens to context rebuilding on every session.
1. Why this matters now
Claude Code has no persistent memory across sessions by design. That's not a bug — it's a safety and privacy boundary. But it creates a real tax on every working session: you either repeat yourself, or Claude starts guessing and asks clarifying questions.
On a solo project that's a mild annoyance. On a team project with a custom stack — say, four Mac Minis in a Thunderbolt 5 mesh running n8n, Ollama, and Draw Things — it becomes a serious productivity drain. Without context, Claude Code asks an average of 7 to 9 clarifying questions per session: which ports are in use, what the TypeScript configuration is, whether there are commit message rules. Every one of those questions is a token you paid for and a second you waited.
The gap between "Claude knows your project" and "Claude is meeting your project for the first time" is exactly the gap CLAUDE.md closes.
2. The core idea
CLAUDE.md is a layered configuration system: one global file sets baseline behavior, project-level files set project-specific rules, and subdirectory files narrow scope even further.
Claude Code reads them in this order on startup:
| Priority | Location | Scope |
|---|---|---|
| Lowest | ~/.claude/CLAUDE.md |
All projects on this machine |
| Middle | <project-root>/CLAUDE.md |
Everything in this repo |
| Highest | <subdir>/CLAUDE.md |
That directory only |
Think of it like venue access rules: national policy clears first, then venue-level rules, then VIP-section rules override whatever came before. For a monorepo with a workflows/ directory that has its own domain constraints, you put shared rules at the root and workflow-specific rules inside workflows/CLAUDE.md. The closer file wins.
The practical implication: keep your global ~/.claude/CLAUDE.md lean — just coding style preferences and safety rails. Put stack-specific facts at the project root where they're version-controlled with everything else.
3. How to implement it
The minimal effective structure below comes from measured work on a 4-node Mac Mini cluster. Below this level, Claude Code asks follow-up questions on almost every session. Above it, you start burning context window on facts that aren't relevant to most tasks.
# PROJECT CONTEXT
- Stack: Node 20, n8n 2.8.4, Ollama 0.3.x (Mac Mini M2 Pro)
- Infra: 4x Mac Mini TB5 mesh, Draw Things 20-step default
- Style: TypeScript strict, functional patterns, comments in English
# CONSTRAINTS
- All external API calls: retry 3x with 500ms backoff
- Port map: 5678 = n8n, 11434 = Ollama, 7860 = Draw Things
- Commit format: feat/fix/chore prefix required
# NEVER DO
- Do not edit .env files directly
- Do not run SSH commands on Mac Mini nodes directly — use Ansible only
Create the file at your project root:
touch CLAUDE.md
# Then open and fill in the three sections above
Verify it's being picked up by starting a new Claude Code session and asking:
What stack am I running and what are the port assignments?
If Claude answers accurately without you saying anything else, the file is loading. If it asks, something is wrong with the path or file encoding.
For a global baseline (coding style you want everywhere), create the user-level file:
mkdir -p ~/.claude
touch ~/.claude/CLAUDE.md
Put only truly cross-project preferences there — things like "prefer named functions over arrow functions" or "always add JSDoc to exported symbols." Stack-specific facts belong in the project file, not the global one.
What the three sections accomplish:
PROJECT CONTEXTeliminates the "what stack are you running?" cluster of questions. Include exact version numbers. "Node 20" is more useful than "Node" because Claude Code can tailor advice to that version's API surface.CONSTRAINTSreplaces the most common clarifying questions about rules. If every external call needs retry logic, say it here once instead of reminding Claude every session.NEVER DOsets hard stops. Security and infrastructure safety rails live here. Keep this list short — three to five items — so Claude treats it as firm, not as a long list to approximate.
Measured result from the same project: clarifying questions per session dropped from 7–9 to 1–2, and time from session start to first meaningful code suggestion dropped from 4 minutes 12 seconds to 43 seconds.
4. What to watch in production
Staleness is the main failure mode. A CLAUDE.md that reflects last quarter's stack is worse than no CLAUDE.md, because it generates confident but wrong outputs. Claude Code will use the wrong port number, suggest an API that was deprecated in the version you're actually running, or skip a constraint you removed.
Check the age of your CLAUDE.md before trusting it:
git log --follow -p CLAUDE.md | head -20
If the last commit is more than 30 days old, treat the file as potentially stale. A two-sprint review cycle (roughly four weeks) works well in practice — tie the CLAUDE.md review to your sprint retrospective checklist.
Keep it short. The file competes with your actual task for context window space. If CLAUDE.md grows past roughly 200 lines, you're probably including information that belongs in inline code comments or a separate docs/ reference rather than the startup briefing. The goal is a briefing, not a wiki dump.
Version-control it. CLAUDE.md belongs in git alongside your code, not gitignored. This gives you git blame for change history, makes it reviewable in PRs when the stack changes, and ensures the whole team works from the same context.
Subdirectory files are powerful but easy to forget. If you add a workers/CLAUDE.md six months in and then forget it exists, you'll hit confusing behavior where Claude Code seems to follow different rules in different parts of the codebase. Add a # Subdirectory CLAUDE.md files section to your root file listing any subdirectory overrides that exist.
Secrets and credentials never go in CLAUDE.md. The file is plaintext, version-controlled, and read at startup — it's not a secrets store. Reference the fact that credentials exist (e.g., "API keys are in .env, never hardcode") but never put the values there.
FAQ
When should I use CLAUDE.md?
Use it on any project where you're running more than one or two sessions. The one-time cost to write the file is around 15 minutes; the payoff is recovered on the second session. It's especially worth it on projects with non-standard infrastructure (custom ports, private models, specific toolchains), team projects where consistency matters, and any long-running project where stack details drift over time.
What should I check before applying CLAUDE.md in a real project?
First, make sure the facts you're writing are actually current — verify port numbers, version strings, and constraint rules against your actual config before you paste them in. Second, check whether a ~/.claude/CLAUDE.md already exists on your machine; if it does, anything in it will apply to your new project too, and you may need to reconcile them. Third, keep the file out of CI pipelines or deployment scripts that don't use Claude Code — it's a developer tool, not a runtime config.
What is the easiestway to verify it's working?
Start a fresh Claude Code session (close and reopen, don't continue an existing one) and ask a direct question about something only CLAUDE.md would know: "What port does Ollama run on in this project?" or "What's the commit message format?" If Claude answers from the file without you prompting further, it loaded. If it asks, double-check the file path and make sure it's saved as UTF-8 plaintext with no BOM.
Closing
CLAUDE.md turns every new session from an onboarding call into a standing meeting with a colleague who already knows the project. Write it once, keep it under 200 lines, review it every sprint, and it stays useful indefinitely. The next step is pairing it with subdirectory-level files for domain-specific rule isolation as your project grows.
🐦 Faster updates on X: @baegseungh7061
📚 More in this series: Code Advanced
💌 Subscribe: Follow on X or grab the RSS
댓글
댓글 쓰기