Claude Code for Engineering Teams: 1. The Setup That Compounds · 2. CLAUDE.md: Write It Like the Creator Does · 3. CLAUDE.local.md: Your Private Layer
CLAUDE.md loads at the start of every Claude Code session. Every session. It's the first thing Claude reads before touching a single file in your codebase.
Most people fill it with a codebase tour. Tech stack overview, folder structure, which services talk to which. The result is a file that's long, mostly ignored, and buries the rules that actually matter.
Boris Cherny, who built Claude Code, is direct about what belongs in it and what doesn't. The principles are simple. Following them requires some discipline.
Keep it short
Every line in CLAUDE.md should earn its place. Boris's test: "Would removing this line cause Claude to make a mistake?" If not, cut it.
This is harder than it sounds. The instinct is to add more — more context, more explanation, more caveats. Resist it. A long file buries important rules. Claude treats everything with roughly equal weight, so a critical constraint buried in paragraph six competes with filler in paragraph one.
The real CLAUDE.md from the Claude Code team's own repo is a useful reference point. The whole file:
# Development Workflow
**Always use `bun`, not `npm`.**
# 1. Make changes
# 2. Typecheck (fast)
bun run typecheck
# 3. Run tests
bun run test -- -t "test name" # Single suite
bun run test:file -- "glob" # Specific files
# 4. Lint before committing
bun run lint:file -- "file1.ts"
bun run lint
# 5. Before creating PR
bun run lint:claude && bun run test
That's it. Build commands Claude can't guess, the exact order to run things, the pre-PR ritual. No style preferences. No codebase tour. No "please be careful with the database layer."
The team maintains it and edits it multiple times a week. When someone sees Claude do something wrong, they add a rule. That's the whole workflow.
Let Claude write the rules
The highest-leverage habit in the entire Claude Code workflow is this: when Claude makes a mistake, end your correction with "Update CLAUDE.md so you don't repeat this."
Boris describes Claude as "eerily good at writing rules for itself from its own failures." A mistake that happens once becomes a constraint. The same mistake never happens again.
Do this for a few weeks and CLAUDE.md becomes something different — not documentation you wrote, but a curated list of every gotcha your codebase has, each one captured the moment it surfaced.
The team takes it further. In PR reviews, Boris uses @claude to commit rules directly from review comments:
nit: use a string literal, not a ts enum
@claude add to CLAUDE.md to never use enums, always prefer literal unions
He calls this Compounding Engineering. Every PR review is an opportunity to make Claude better at the next one. The file becomes a living record of institutional knowledge — the kind that usually lives only in the heads of your most senior engineers.
What to put in it
Four sections cover most of what a real codebase needs:
Code style — the conventions that differ from language defaults. Not "use meaningful variable names." Things like: use ES modules not CommonJS, never write raw SQL strings in handlers, all new consumers need a DLQ in the same PR.
Workflow — build commands, test invocations, the pre-commit ritual, how to run a single test. Claude will guess wrong here if you don't tell it. Specify exactly.
Architecture — load-bearing constraints. Which middleware all API routes go through. Where new database queries live. What the difference is between two types with similar names. These are the things a new engineer would ask in their first week.
Gotchas — this is the magic section. Every entry is a mistake Claude made, captured the moment it happened. Over time, this becomes the most valuable part of the file. It's specific, accurate, and something no amount of codebase documentation would have produced.
A practical template:
# Code style
- Use ES modules (import/export), not CommonJS (require)
# Workflow
- Always use `bun`, not `npm`
- Run `bun run typecheck` before claiming done
- Never push to main directly. Always open a PR.
# Architecture
- All API routes go through src/api/middleware/auth.ts
- New database queries go in src/db/queries/. No inline raw SQL.
# Gotchas
- `User` and `UserRecord` are distinct types. UserRecord is the DB row,
User is the runtime object.
- `formatCurrency` assumes USD. Use `formatCurrencyByLocale` for international.
Words like IMPORTANT and YOU MUST improve adherence. Use them sparingly — once they're everywhere, they lose weight.
What doesn't belong
Standard language conventions. File-by-file codebase descriptions. API documentation. Anything that changes so frequently it'll be stale within a sprint.
The test is always the same: if removing it wouldn't cause a mistake, it doesn't belong.
The EM's role
CLAUDE.md is team infrastructure. It gets committed to git. When someone joins the team and clones the repo, they inherit whatever your team has learned about working with Claude in this codebase.
That makes it your responsibility to establish the habit. Not to write the whole file yourself — the best entries come from the engineers closest to the code — but to make "update CLAUDE.md" the default response whenever Claude does something wrong.
Run that habit for a month. Look at what the file becomes.
Next: CLAUDE.local.md — the private layer that never leaves your machine, and why your PR review comments are the best training data you're not using.