Claude Code

Keep CLAUDE.md under 200 lines: what to write, what to cut, where the rest goes

TL;DR

Put in CLAUDE.md only what Claude can't learn from the code: verification commands, misleading spots, off-repo decisions. Stay under 200 lines; move scoped rules to .claude/rules, procedures to skills and hard rules to hooks.

Many teams treat CLAUDE.md like a wiki: every convention, every process, every lesson learned, then wonder why Claude increasingly "ignores" instructions. The reason is mechanical: CLAUDE.md is loaded into every session, so every line takes a bit of Claude's attention on every task, relevant or not. The Claude Code docs recommend keeping each file under 200 lines; longer files both cost context and reduce adherence. This post covers how to write a lean CLAUDE.md and where to put everything else.

The test before adding a line

  1. Could Claude find this out by reading the code?
  2. Would it actually go looking?

If both answers are "yes", drop the line. Today's models read code very well: folder structure, test framework, naming conventions… they see it themselves. What they can't see is what never lived in the repo: decisions made in a meeting, a deploy process that exists in one person's head, environment variables the integration tests need.

What should CLAUDE.md contain?

  • How to verify: exact test, typecheck and lint commands; how to run a single test file.
  • Misleading code: old patterns that are everywhere but new code shouldn't copy; folders that look abandoned but are still in use.
  • Decisions not in the repo: the chosen error-handling helper, how to deploy, which migrations need review.
  • Things you've had to correct Claude on twice.
# Commands
- Install: pnpm install
- Run one test file: pnpm vitest run path/to/file.test.ts
- Typecheck: pnpm tsc --noEmit

# Conventions
- Use the error helpers in src/lib/errors.ts, never throw raw strings
- src/legacy/ is still live but don't copy its patterns into new code

# Gotchas
- Integration tests need DATABASE_URL set, see .env.example

Where does everything else go?

Content typePut it inWhen it loads
Rules for one part of the codebase.claude/rules/*.md with paths: frontmatterOnly when Claude works on matching files
Team processes (release, runbooks).claude/skills/<name>/SKILL.mdOnly name + description always visible; content read when needed
Personal preferences in the projectCLAUDE.local.md (add to .gitignore)Every session, only on your machine
Instructions for one subfoldersubfolder/CLAUDE.mdWhen Claude reads/edits files in that folder
Rules with no exceptionsHooks, deny rulesAlways enforced by the harness, independent of the model

An example path-scoped rule:

---
paths:
  - "src/api/**/*.ts"
---
- Validate request bodies with the zod schemas in src/api/schemas/
- Every new endpoint needs an entry in openapi.yaml, CI fails without it

A long release process inside a skill won't weigh down unrelated bug fixes the way it does inside CLAUDE.md. For skills with side effects (actually cutting a release), add disable-model-invocation: true so they only run when you type /release yourself.

Loading mechanics worth knowing

  • CLAUDE.md files in the working directory and every parent directory are loaded at startup, concatenated rather than overriding each other. If two instructions conflict, Claude may pick either.
  • Import other files with @path/to/file, up to 4 levels deep. Imports don't save tokens: imported files still go into context.
  • Auto memory (notes Claude writes itself) lives in ~/.claude/projects/<project>/memory/; each session loads only the first 200 lines or 25KB of the index file.

Cleanup tools

  • /init: generates a first version from the codebase. The next job is mostly deleting.
  • /doctor: suggests cutting what Claude can infer from the code.
  • /doctor prompt-audit: finds instructions written for older models, references to files that no longer exist, or contradictions.
  • /context: confirms the file is loaded; /memory: view and edit it.

How to apply it

  • Dev: Put personal preferences (reply tone, sandbox URLs) in CLAUDE.local.md, not in the shared file.
  • Tech Lead: Review CLAUDE.md quarterly like tech debt: delete stale lines, move processes into skills, local rules into .claude/rules/, mandatory rules into hooks.
  • PM: Product decisions that affect code (for example "don't use library X because of its licence") are exactly the kind of information worth having in CLAUDE.md.

Sources & references

  1. Best practices for Claude Code — Claude Code Docs
  2. How Claude remembers your project — Claude Code Docs