Writing an effective CLAUDE.md is not about knowing the right sections to include. Most guides cover that part. The harder problem is knowing how to phrase instructions so Claude reliably follows them, which types of instructions actually change behavior versus which are ignored, and the common mistakes that make CLAUDE.md files actively worse than having none at all.
For the basics of what CLAUDE.md is and why it matters, see our complete CLAUDE.md guide. This article focuses on the craft of writing instructions that work.
Browse effective CLAUDE.md examples from real open-source projects in our gallery.
Step 1: Identify What Actually Belongs in CLAUDE.md
The most common mistake is writing instructions that describe behavior Claude already exhibits by default. These add tokens without changing anything.
Before writing any section, ask: “What would Claude do wrong on this project without this instruction?”
If the answer is “nothing, Claude does this correctly anyway,” don’t write the instruction.
To generate a useful list of what to include, spend one session observing Claude’s unprompted behavior on your project and note what it gets wrong. Then write CLAUDE.md entries specifically for those failures.
Concretely, gather:
From repeated corrections. What have you corrected Claude on in the last month? Every time you type “no, we use X not Y,” that belongs in CLAUDE.md.
From inconsistent output. Where does Claude produce different results on the same type of task in different sessions? These are places where it is guessing because it has no stable instruction.
From project-specific knowledge. What would a new engineer need to know on day one that isn’t in the README? Non-obvious commands, surprising architectural choices, gotchas about the codebase.
What not to include:
- General best practices Claude already follows
- Instructions about quality (“write clean code”) — not concrete enough to change behavior
- Documentation for human readers — CLAUDE.md is read by Claude, not your team
Step 2: Write Instructions That Are Concrete and Testable
The critical attribute of a CLAUDE.md instruction is that you can test whether Claude is following it. Abstract instructions fail this test.
Abstract (bad):
Write code that is easy to maintain and well-organized.
You cannot test this. What does “well-organized” mean in this codebase specifically?
Concrete (good):
Organize utility functions by domain in src/lib/:
- src/lib/auth.ts — authentication utilities
- src/lib/formatting.ts — date, number, currency formatting
- src/lib/api.ts — API request helpers
Never put utility functions directly in component files.
This is testable: either a new utility function goes in the right place or it doesn’t.
The positive-rule pattern
Prefer telling Claude what to do over what not to do, when possible.
Negative framing:
Don't use default exports.
Don't use var.
Don't write class components.
Positive framing:
Use named exports only.
Use const/let, never var.
Write functional components with hooks.
The positive framing is easier to follow (and verify) because it describes the target state, not the things to avoid.
The “instead” pattern for prohibitions
When a prohibition genuinely needs to be negative, pair it with the approved alternative:
## API Calls
Never use fetch() directly in components.
Instead: use the useApi() hook (src/hooks/useApi.ts) which handles auth headers,
error states, and loading states automatically.
“Never use X” alone leaves Claude to guess what to do instead. “Never use X, use Y instead” eliminates the guessing.
Step 3: Structure for Scannability
CLAUDE.md is not read linearly — it is scanned. Claude tokenizes the entire file, but its attention mechanisms favor content that appears early, that appears at the start of a line, and that appears under clear headings.
Structure for that reading pattern:
Put the most critical rules at the top. If there are three things that matter more than anything else, say so explicitly:
## The Three Rules That Matter Most
1. Never write to the database directly — go through src/lib/db.ts
2. All API endpoints require auth middleware — see src/middleware/auth.ts
3. Run npm test before suggesting a PR is ready
Use ## headers for major categories. Headers create navigational anchors. Group related rules under a clear header rather than mixing everything in a flat list.
Use code blocks for anything syntactic. Show, don’t tell, for code patterns:
## Import Convention
# Correct
import { createUser } from "@/lib/user";
import type { User } from "@/types";
# Wrong
import createUser from "@/lib/user"; // no default exports
import { User } from "@/types"; // type imports use `import type`
Showing the pattern is faster than describing it.
Step 4: Test Your CLAUDE.md
A CLAUDE.md is a hypothesis about what Claude will do with these instructions. Test it before considering it done.
The blank-context test. Start a fresh session, write a test task that your CLAUDE.md is specifically designed to handle, and verify Claude behaves correctly without any prompting beyond the task itself.
For example, if your CLAUDE.md says “use named exports,” ask Claude to create a new utility function. Does it use a named export without being told?
The edge-case test. Find the ambiguous scenarios — where two rules could conflict, or where the right behavior is not obvious from the rules as written. See what Claude does. If it chooses wrong, you have found a gap.
The tone check. Read your CLAUDE.md with fresh eyes. Are the instructions clear? Do any sections sound like they were written for a human README rather than for Claude? The voice should be direct and instructional, not explanatory.
Common Mistakes and How to Fix Them
Mistake 1: Instructions that contradict each other
# Conflicting
Use Tailwind for all styling.
...
[ten sections later]
Use CSS Modules for component styles to avoid global scope issues.
When two instructions conflict, Claude picks one and proceeds. The other instruction is effectively dead. Audit for conflicts before finalizing.
Fix: Search CLAUDE.md for the same topic mentioned in multiple places. Consolidate and resolve the conflict explicitly.
Mistake 2: Instructions that require external context to interpret
# Ambiguous
Follow the team's conventions for error handling.
Claude has no access to “the team’s conventions” unless you define them. This instruction does nothing.
Fix: Replace references to external context with the actual content:
## Error Handling
- Use our custom AppError class (src/lib/errors.ts) for all thrown errors
- Always include an error code: throw new AppError("User not found", "USER_NOT_FOUND")
- Log errors with logger.error() from src/lib/logger.ts before throwing
- Never expose raw database errors to the API response
Mistake 3: Too many sections, all at the same level of importance
When everything is marked as important, nothing is. A CLAUDE.md with 30 equally-weighted sections gives Claude no signal about what actually matters.
Fix: Use a tiered structure:
# CRITICAL — Read First
[The 3-5 things Claude must never get wrong]
# Development Conventions
[Standard coding patterns for this project]
# Reference
[Info Claude should look up when needed, not memorize]
Mistake 4: Writing CLAUDE.md before observing real failure modes
Writing a thorough CLAUDE.md before you have used Claude Code on your project for a while is premature optimization. You are guessing at what instructions will matter.
Fix: Use Claude Code for 1–2 weeks with no CLAUDE.md. Take notes on every correction you make. Then write your CLAUDE.md from that observation log. The result will be shorter, more targeted, and more effective than anything written speculatively.
Mistake 5: Updating CLAUDE.md by adding but never removing
CLAUDE.md grows over time. Instructions get added when problems appear, but rarely removed when they stop being relevant. After six months, you end up with a file full of outdated context.
Fix: Review CLAUDE.md quarterly. For each section, ask: “Has this instruction changed Claude’s behavior in the last three months? Is the pattern it describes still in use?” Remove sections that fail these tests.
Formatting Conventions That Work
These patterns consistently produce better results than alternatives:
Bold for the most important words in a rule:
**Always** use named exports. **Never** use default exports.
Inline comments for code examples:
// Correct
const user = await db.findUser(id); // use our db wrapper
// Wrong
const user = await prisma.user.findUnique({ where: { id } }); // direct Prisma access
Status labels for section relevance:
## Database Access (applies to all backend work)
## Frontend Conventions (applies to /src/components and /src/pages)
## Deployment (refer to this section only when preparing a release)
Short sentences over long ones. Instructions with multiple clauses get parsed less reliably than single-clause rules. Break complex rules into multiple lines:
# Harder to parse
Use TypeScript strict mode which means you should enable noImplicitAny,
strictNullChecks, and all related compiler options in tsconfig.json.
# Easier to parse
TypeScript: strict mode required.
Enable: noImplicitAny, strictNullChecks.
Config file: tsconfig.json.
A Calibrated Starting Template
This is a minimal template that forces you to fill in only what actually matters:
# [Project Name] — Claude Code Instructions
## What Claude Must Know to Work Here
[3-5 sentences about what makes this project unusual or hard to work in without context]
## Non-Obvious Setup
- Build: [command]
- Test: [command]
- [anything that differs from typical conventions for this language/framework]
## Conventions
### Code Style
[Only rules that differ from language defaults — what you'd have to correct Claude on]
### Architecture
[File organization, module boundaries, patterns to use or avoid]
### Testing
[Test framework, what to test, what not to test]
## Never Do These Things
- [Thing 1 that would break the project] → Do [alternative] instead
- [Thing 2]
- [Thing 3]
Start with this and add only when you discover Claude getting something wrong. A 200-token CLAUDE.md with targeted, effective rules outperforms a 3,000-token CLAUDE.md full of instructions Claude already follows.
For real CLAUDE.md examples from production projects, browse the Prompt Shelf gallery. For how to keep your CLAUDE.md token-efficient as it grows, see our token budget optimization guide.