Skip to content

02: CLAUDE.md — Teaching Claude Your Codebase

25 minutes | You need: Claude Code running in your project

CLAUDE.md is injected into Claude’s context on every single request. It’s not optional reading — it’s always there, always consuming tokens, always influencing behavior. This makes it:

  • The highest-leverage file you’ll write — a good CLAUDE.md transforms every interaction
  • An always-on cost — every line consumes context on every turn. Keep it under ~200 lines / 2,000 tokens
  • Compaction-proof — when Claude compresses conversation history to reclaim space, CLAUDE.md survives intact

If your project has two error handling patterns (old and new), Claude will mix them. If your team uses a specific test framework but there’s a stale config for another one, Claude will guess. CLAUDE.md resolves ambiguity with authority.

/init

Claude analyzes your codebase and generates a first draft. It won’t be perfect.

Open the generated CLAUDE.md. The goal isn’t a comprehensive wiki — it’s the minimum instructions that produce maximum behavior change. Focus on:

What Claude gets wrong without guidance:

  • Which test framework and how to run tests (npm test, pytest, etc.)
  • Build commands and how to verify things work
  • Naming conventions (camelCase vs snake_case, file naming patterns)
  • The architectural pattern you actually use (not the one in the old docs)
  • Things that will break if Claude does them (e.g., “never modify migration files directly”)

Before/after example:

Without CLAUDE.md, you ask Claude to write a test:

Claude generates a Jest test with describe/it blocks, expect() assertions, and creates __tests__/ directory.

With this in CLAUDE.md:

## Testing
- Framework: Vitest (NOT Jest)
- Tests live next to source files: `foo.ts` → `foo.test.ts`
- Use `test()` not `it()`, `assert` from vitest not `expect`
- Run: `pnpm test`

Now Claude gets it right the first time, every time.

Ask Claude something where CLAUDE.md should change the answer:

Write a new test for [module]. Follow our testing conventions.

Does it use the right framework? Right patterns? Right location? If not, refine and retry.

Claude merges CLAUDE.md files from multiple locations:

LocationScopeShared?
~/.claude/CLAUDE.mdGlobal — all your projectsNo (personal)
project-root/CLAUDE.mdProject-wide — team conventionsYes, commit to git
project-root/.claude/CLAUDE.mdProject-specific — team conventionsYes, commit to git
Any subdirectory CLAUDE.mdActive when working in that directoryYes
project-root/.claude/settings.local.jsonLocal settings and hooksNo (gitignored by default)

For conventions that only apply to certain files, use .claude/rules/ with glob patterns:

.claude/rules/api-routes.md
---
paths:
- "src/api/**/*.ts"
---
All API routes must validate input with zod schemas.
Return standardized error responses: { error: string, code: number }.
Never throw raw exceptions — always catch and wrap.

This only loads when Claude is working on files matching the path pattern — zero context cost otherwise.

Terminal window
git add CLAUDE.md
git commit -m "Add CLAUDE.md with project conventions"

Your CLAUDE.md is now a shared team asset. Every team member’s Claude sessions benefit.

A committed CLAUDE.md in your project repo. Optionally, path-specific rules in .claude/rules/.

Playbook M04 — Context Engineering for the four failure modes of large contexts (poisoning, distraction, confusion, clash) and why CLAUDE.md is the antidote to each.