MD Vessel
All posts

November 5, 2026·8 min read

How Claude Code Uses CLAUDE.md — and How to Write a Good One

A CLAUDE.md file is a Markdown document that Claude Code reads at the start of every session to understand your project — how to build it, how to test it, and the conventions it should follow. It lives in your repository and acts as the agent's project memory.

Every coding agent shares the same weakness: when a session starts, it knows nothing. It has the repository, a prompt, and a lifetime of general training — but no idea that this project builds with pnpm, tests with vitest, or that /generated is build output you never touch. Without help, it spends the first part of every session rediscovering the obvious, and the rest occasionally getting it wrong.

CLAUDE.md is the file that fixes this. It's the closest thing a Claude Code session has to project memory — and how you write it decides how much of that memory the agent actually uses.


What Happens at Session Start

When you start Claude Code in a project that contains a CLAUDE.md file (in the project root), the file's contents are loaded as context for the session — before the agent starts reading code, running commands, or answering questions.

That ordering matters. The file isn't a hint the agent may or may not consult; it's part of the session's input, alongside your prompt and the repository itself. Instructions in it carry the same weight as instructions in the conversation — which is why a good file makes every session dramatically cheaper, and a bad one actively misleads.

Everything in it steers the session:

  • The commands — it knows npm run dev, pytest, or bun run build without guessing, and runs the right one for the task
  • The architecture — it understands where things live, so a "where does checkout live?" question gets answered from the file, not from a scan of your whole repo
  • The conventions — naming, formatting, what not to touch. Agents follow written instructions far more reliably than they infer them
  • The boundaries — files to leave alone, generated directories, where secrets live

The file is the cheapest way to make a coding agent behave like a developer who's been in the repo for months instead of a visitor who just arrived.


What a Good CLAUDE.md Actually Does

The file's whole job is to convert "agent that guesses" into "agent that knows." Concretely:

1. It Ends Command Guessing

The single highest-ROI content in any CLAUDE.md is the command block:

## Commands
- Install: `pnpm install`
- Test: `pnpm vitest run`
- Build: `pnpm build`
- Typecheck: `pnpm tsc --noEmit`

Without these lines the agent will try npm install on a pnpm project, or "test" by running whatever looks plausible. With them, the right command is the obvious one.

2. It Maps the Architecture in One Paragraph

A repository is a tree of thousands of files; the agent's first instinct is to search it. Two sentences can replace that exploration:

## Architecture
- Next.js app in /app, Convex backend in /convex
- Shared UI components in /components
- Data access via generated client in /convex/_generated

3. It Makes Conventions Followable

Agents write code that matches its surroundings — but "surroundings" is a weak signal. Written rules are stronger:

## Conventions
- TypeScript strict; no `any`
- Tailwind for styling; no CSS modules
- Errors return { error: { code, message } }

4. It Draws Boundaries

The most expensive mistakes are touching things that shouldn't be touched: generated directories, migration files after production, credentials files. The file can say it plainly:

## Don't
- Never edit /generated — it's build output
- Don't commit migration files
- Don't read or modify .env files

What Should Go in a CLAUDE.md

The best files are short, specific, and command-first. A good skeleton:

# Project: [name]

## Commands
- Build: `npm run build`
- Test: `npm test`
- Dev server: `npm run dev`

## Architecture
- Next.js app in /app, Convex backend in /convex
- Shared components in /components

## Conventions
- TypeScript strict, no `any`
- Tailwind for all styling
- Commit messages: conventional commits

## Don't
- Don't edit files in /generated — they're build output
- Don't add new runtime dependencies without asking

Every line should be actionable. "The codebase is a mess" is not actionable; "don't touch /legacy" is.


Example: One of the Better Ones

# analytics-service

## Commands
- Install: `pnpm install`
- Test: `pnpm vitest run`
- Typecheck: `pnpm tsc --noEmit`
- Lint: `pnpm eslint`

## Stack
- Deno + Hono, Postgres via Drizzle, deployed on Fly.io

## Conventions
- Handler files live in /src/handlers, named <resource>.handler.ts
- Errors return { error: { code, message } }
- All DB access via repository modules in /src/repositories

## Don't
- Don't commit migration files — they're generated by `pnpm db:gen`
- Don't touch /infra unless the task is explicitly about deployment

How to Write Yours in Ten Minutes

  1. Start with commands. Build, test, lint, typecheck — verbatim and copy-pasteable.
  2. Add the architecture map. Three bullet points beat three paragraphs.
  3. List conventions as rules, not descriptions. "Use pnpm" over "we prefer pnpm".
  4. Write the Don't list. It's the least flattering and most useful part of the file.
  5. Keep it under ~100 lines. Link out for detail:
    ## Detail
    Database design: see /docs/db.md
    
  6. Commit it in the same PR as the conventions it documents.

Best Practices That Keep the File Useful

  1. Commands first. If the file only gets ten lines, spend them on how to build, test, and run the project.
  2. Keep it short. A CLAUDE.md that needs scrolling is a wall that gets ignored. Aim for 50–100 lines; link out to detailed docs instead of embedding them.
  3. Write rules, not descriptions. "Use pnpm" beats "we prefer pnpm as our package manager".
  4. Version it with the repo. The file is documentation — review it in PRs like code, update it when conventions change.
  5. Never put secrets in it. The file ships in the repo and is loaded into every session.
  6. One source of truth. If a rule exists in both CLAUDE.md and the README, they will drift. Keep canonical rules in one place and link from the other.
  7. Let the agent update it. When conventions change, the agent that discovered the change is often the best one to record it — in the same style as the rest of the file.

What Happens When the File Is Bad

A bad CLAUDE.md is worse than no CLAUDE.md, because the agent trusts it. The failure patterns have names:

  • The novel. Eight hundred lines of prose architecture history. The agent skims; the useful three lines are in the middle of paragraph forty.
  • The stale command. The test command changed three months ago; the file still says make test. The agent runs it confidently, reports the failure as your bug, and you burn a round-trip discovering the file was the problem.
  • The contradiction. "Never edit /config" in one section, "update the API key in /config/secrets.json" in another. Whatever the agent resolves, it resolves wrong.
  • The secrets trap. The file is loaded into every session and committed to the repo. A token in CLAUDE.md is a token in your git history.

The rule that covers all four: write the file like code — short, precise, reviewed, and updated when the world changes.


CLAUDE.md vs AGENTS.md

Claude Code reads CLAUDE.md natively. Other tools have their own conventions — and many are converging on AGENTS.md, a cross-agent file that any tool can support. Some teams ship both: AGENTS.md as the shared, tool-agnostic file and CLAUDE.md as a short pointer to it. If you only run Claude Code, one file is enough; if your team is split across Cursor, Codex, and Claude Code, the cross-agent file saves you from maintaining two sources of truth.


The Maintenance Problem Nobody Mentions

Files rot, and CLAUDE.md files rot faster than most — because the conventions they describe change at exactly the speed of your project, and updating documentation is the task everyone postpones.

This is where the agent can earn its keep. When a session discovers a convention changed — "we moved from vitest to jest" — the agent that hit the new reality is the one best positioned to record it, in the file's existing style, in the same session. Making that easy (the file lives somewhere the agent can update it directly, not just read it) is what turns CLAUDE.md from a snapshot into a living document.

Some teams take this further and stop keeping the file in a single repo at all: the canonical CLAUDE.md lives in a shared markdown store, the agent pulls it via HTTP at session start, and every machine and teammate gets identical context. Same file, no copy-paste drift, versioned.

There's a quiet problem with CLAUDE.md files shared across a team: everyone's copy diverges, and the version in your head is never the one in the repo. A simple pattern is to keep the file somewhere it can be read, edited, and handed to the agent over HTTP:

  • Store the canonical CLAUDE.md in an MD Vessel workspace
  • Your agent reads it via the API at the start of a session — same file, every session, no copy-paste
  • When the team's conventions change, the file updates in one place and every session picks it up

Frequently Asked Questions

Is a CLAUDE.md file required? No — Claude Code works without one. But the file is how you stop repeating the same context ("we use pnpm, tests are in /tests", "don't touch /legacy") in every session.

What if CLAUDE.md conflicts with what I write in my prompt? Session instructions generally take precedence — treat the file as the baseline and the prompt as the override.

Does Cursor or other tools read CLAUDE.md? Claude Code reads it natively. Other tools have their own conventions — many now support the cross-agent AGENTS.md file instead, and some read both.

How big should it be? Short. If you need more than ~100 lines, put the detail in a linked doc and keep the file a pointer plus the essentials.

Should CLAUDE.md be committed to git? Yes. It's project documentation and belongs in the repo — that's how the whole team (and their agents) stay on the same page.

Can a CLAUDE.md file be global instead of per-project? Claude Code supports user-level configuration, but the project file is the one that carries repo-specific commands and conventions. Most teams keep both: personal preferences globally, project rules in the repo.


The Bottom Line

CLAUDE.md converts a stateless visitor into a developer who knows the project. The file is small, cheap, and — when written as commands and rules instead of prose — dramatically changes what the agent gets done in the first hour of every session.

Write one, keep it short, review it in PRs, and let it evolve with the project.


Related