Skip to main content
  1. Articles/

The Complete CLAUDE.md Guide

·1582 words·8 mins·
Author
Florent Clairambault
CTO & Software engineer

If you’ve used Claude Code for more than a week, you’ve encountered CLAUDE.md. If you’ve used it for more than a month, you’ve probably written one badly. The file looks deceptively simple — a markdown doc the agent reads at session start — but the difference between a CLAUDE.md that compounds value over time and one that pollutes every conversation is large.

This is the comprehensive guide. What to put in. What to leave out. The structure that scales across a team. The security model that prevents you from getting owned.

What CLAUDE.md actually is
#

When Claude Code starts a session, it walks the directory tree from your current working directory up to the home directory, reading every CLAUDE.md it finds, and concatenates them into the agent’s system prompt. Project-level overrides user-level overrides org-level. The agent treats this content as authoritative context — not as soft hints, not as documentation, but as facts about the project.

That’s the leverage. That’s also the trap. Anything in CLAUDE.md is in the prompt on every turn. Two paragraphs cost ~250 tokens; ten paragraphs cost 1,200; a sloppy 800-line CLAUDE.md eats 6,000 tokens before you’ve typed anything. On large codebases run via --dangerously-skip-permissions for hours-long sessions, that adds up to real money — and worse, real attention drift: the agent starts treating the preamble as the most important context and the user’s actual request as secondary.

The mental model: “what would I tell a senior engineer joining this project today?”
#

Don’t think of CLAUDE.md as documentation. Think of it as the briefing you’d give a senior engineer who’s joining the project, who already knows how to write code, but doesn’t know this codebase. The questions they would ask in the first thirty minutes are exactly what CLAUDE.md should answer.

What’s the build command? Where do tests live? What linter? What conventions? What’s our policy on dependencies? What are the load-bearing files? What should they read first? What pitfalls should they avoid?

Notice what they would not ask: they wouldn’t ask you to explain what TypeScript is. They wouldn’t ask for a tutorial on React. They know how to code; they need to know how to code here.

The structure that compounds
#

A CLAUDE.md that ages well has a shape. Here’s the template:

# <Project Name>

<One-paragraph description: what this project is, who uses it, why it exists.>

## Stack

- Language: <e.g. TypeScript 5.4, strict mode>
- Framework: <e.g. Next.js 15 with App Router>
- Database: <e.g. PostgreSQL via Prisma>
- Test runner: <e.g. Vitest>
- Package manager: <e.g. pnpm — never use npm>

## Commands

- `pnpm dev` — local dev server
- `pnpm test` — full test suite
- `pnpm test <file>` — single file
- `pnpm build` — production build (must succeed before any commit)
- `pnpm lint` — biome check, run before committing

## Conventions

- File naming: kebab-case for files, PascalCase for React components
- Imports: absolute imports via `@/`, never deep relative paths
- Errors: throw typed errors from `lib/errors`, not generic Error
- Tests: colocated next to source (`foo.ts``foo.test.ts`)
- API routes: thin handlers, business logic in `lib/`

## Architecture

<Two paragraphs max. The map that helps a newcomer orient. Where does
HTTP enter? Where does it persist? Where do background jobs live?>

## Do not

- Do not run database migrations manually — use the `db migrate` command
- Do not introduce new dependencies without checking existing ones first
- Do not edit `dist/` or `.next/` directly
- Do not commit `.env*` files

## Things that aren't obvious

- The `feature-flags/` directory is consumed by GrowthBook, not internal
- `lib/legacy/` is read-only — being migrated, do not extend
- The `migrations/` folder must be alphabetically ordered for the runner

## Where to look

- New developers: read `docs/onboarding.md` first
- Adding a route: see `docs/routing.md` and existing examples in `app/api/`
- Background jobs: `workers/` and the `Inngest` setup in `lib/jobs.ts`

The pattern: factual, not pedagogical. Imperative, not narrative. Short.

What to leave out
#

This is the part most people get wrong. CLAUDE.md is not the place for:

Documentation that belongs in the README. Your project’s README is what humans see on GitHub. CLAUDE.md is what the agent sees on every prompt. They overlap, but they shouldn’t be identical. README explains the project to potential users; CLAUDE.md briefs an engineer who’s already on board.

Implementation details the agent can read from the code. Don’t paste your tsconfig.json into CLAUDE.md. Don’t list every file in src/. Don’t enumerate React components. The agent can read the filesystem; tell it where to look, not what’s there.

Aspirational rules. “We try to write tests for everything” is noise unless you actually do. The agent will treat aspiration as fact and produce code that assumes the rule is enforced. Rules in CLAUDE.md should be rules you’d fail a PR over.

Multi-step workflows. A deploy procedure, a migration playbook, a release process — these are skills, not CLAUDE.md content. CLAUDE.md is loaded on every turn; skills load when triggered. Putting a deploy procedure in CLAUDE.md eats context for every conversation, including the ones that have nothing to do with deploys.

Secrets, paths to secrets, or anything sensitive. This is non-negotiable. CLAUDE.md is committed to your repo. Anyone running the agent in your project sees it. Anyone who clones your repo sees it. See the security section below.

Long opinionated essays about software philosophy. The agent is paid by the token. So is the model behind it. Save the manifesto for the README.

The CLAUDE.md hierarchy
#

Three levels, three purposes:

~/.claude/CLAUDE.md — your personal preferences. Things you want every project to inherit: “I prefer functional patterns over class-based when both work,” “always run gh pr create with --draft first,” “never use emoji in code or commit messages.” These persist across all your work.

<project-root>/CLAUDE.md — the project’s source of truth. Everything in the template above. Committed to the repo. Treated as a project artifact: changes go through code review, the file is versioned alongside the code.

<subdirectory>/CLAUDE.md — local overrides. The frontend/ directory has different conventions than backend/? Each gets its own CLAUDE.md with the deltas. The agent reads all of them, with deeper directories overriding shallower ones.

The hierarchy is the lever for big monorepos. A 10,000-line root CLAUDE.md is unmaintainable; ten 200-line subdirectory CLAUDE.mds, each scoped to a service, are.

The security model: don’t get owned
#

CVE-2026-21852 (covered in detail) was a patched vulnerability where a malicious CLAUDE.md could escalate the agent’s permissions silently — bypassing user-defined deny rules and exfiltrating credentials. Patched in v2.1.90. The lesson generalizes beyond the specific CVE: a CLAUDE.md cloned from a stranger’s repo is executable trust.

The rules:

  1. Never put secrets in CLAUDE.md. Reference environment variable names, never values. Use $DATABASE_URL is fine. Use postgresql://user:hunter2@... is a credential leak.

  2. Treat CLAUDE.md from untrusted repos like npm install from an unverified package. Read it before running the agent in that repo. Look for instructions that override permissions, exfiltrate data, or invoke unfamiliar tools. The agent will follow the instructions; if you didn’t write them, you don’t know what you’re authorizing.

  3. Use deny rules in ~/.claude/settings.json for paths the agent should never touch. A CLAUDE.md cannot grant access to denied paths; deny rules are the floor.

{
  "permissions": {
    "deny": [
      "Read(./.env*)",
      "Read(./secrets/**)",
      "Read(./credentials.json)",
      "Read(~/.aws/**)",
      "Read(~/.ssh/**)",
      "Read(~/.gnupg/**)"
    ]
  }
}
  1. For shared CLAUDE.md across a team or org, treat it like production code. Pull request review. Git history. Linting (yes, lint your CLAUDE.md — there are early linters that catch ambiguous instructions). Sign-off for changes that grant new tool permissions.

  2. Audit your CLAUDE.md when you add an MCP server. A CLAUDE.md that says “use the company-db MCP server for all queries” combined with an MCP server that has prod write access is a single line away from “delete the production users table.” Cross-check the trust surface every time it grows.

The check: does this file pay rent?
#

A working test for whether your CLAUDE.md is healthy:

  • Open it.
  • For each section, ask: “Would removing this make the agent measurably worse at common tasks here?”
  • If the answer is no, delete it.

The discipline matters more than the absolute size. A 100-line CLAUDE.md where every line earns its place outperforms a 600-line one where 80% is filler. The signal-to-noise ratio is what the agent’s attention is allocated against; ratio matters more than total length.

The forward-looking pattern
#

A few teams are now generating CLAUDE.md programmatically — pulling stack info from package.json, build commands from npm scripts, conventions from a linter config, file structure from tree. This is good. It means the file stays in sync with the code, and the parts that humans write (the “do not” list, the architecture summary, the things that aren’t obvious) get the entire attention budget instead of being buried in a long auto-stale tutorial.

If you have the cycles, it’s worth automating the boilerplate part. The bits that matter — the rules, the architectural map, the gotchas — still need a human author who’s been burned by this codebase enough times to know what to write.

See also
#

CLAUDE.md isn’t documentation. It’s the contract between you and the agent. Write it like one.

Related