Everyone says keep CLAUDE.md short. Nobody says what earns a spot. A section-by-section breakdown of what belongs, what's filler — plus a real lint of my own file and a composite before/after.
I wrote a linter that counts instructions in `CLAUDE.md` files, and running it against my own projects taught me something uncomfortable: the problem was never that my files were too short. Every single one had plenty of content. The problem was that most of that content was doing nothing — or worse, actively crowding out the ten lines that mattered.
"Keep it short" is the advice everyone repeats now, and it's correct. Anthropic's own [best-practices doc](https://code.claude.com/docs/en/best-practices) says to keep it concise and human-readable, target under 200 lines, and warns that longer files consume more context and reduce adherence. HumanLayer, whose engineering blog has one of the better write-ups on this, [keeps their root CLAUDE.md under 60 lines](https://www.humanlayer.dev/blog/writing-a-good-claude-md).
But "short" is a constraint, not a plan. The real question is: *which* lines earn a spot in the file, and which ones are paying rent they can't afford?
Here's the test I now apply to every line: **would a competent new hire need this on day one, and would they be unable to infer it from the code?** If either answer is no, the line goes.
That test sorts everything in a CLAUDE.md into two piles.
---
The single highest-value content in any CLAUDE.md. Claude cannot infer that your test runner needs a flag, or that `npm test` is broken and everyone actually runs `npm run test:fast`.
## Commands - Build: `pnpm build` (NOT npm — lockfile is pnpm) - Test single file: `pnpm vitest run path/to/file.test.ts` - Typecheck: `pnpm tsc --noEmit` — run after every change - DB migrations: `pnpm drizzle-kit push` (dev only, never in prod)
Four lines. Notice each one carries a *non-obvious* detail. `pnpm build` alone is inferable from the lockfile; "NOT npm" prevents a real failure mode.
Three to six lines that answer "where do I look?" — not a directory listing (Claude can run `ls`), but the parts that carry intent:
## Layout - `src/core/` — pure business logic, no I/O, no framework imports - `src/adapters/` — all external calls (DB, APIs) live here, nowhere else - `legacy/` — frozen. Read for reference, never modify. - Generated: `src/gen/**` — never edit by hand, run `pnpm codegen`
The `legacy/` and `src/gen/` lines are boundary markers. In my experience these prevent more damage than any style rule in the file — an agent that edits a generated file produces a change that silently reverts on the next codegen run, which is a genuinely miserable bug to trace.
This is where most files go wrong in both directions. The rule of thumb from the official guidance is right: never duplicate what a linter already enforces. If ESLint or Prettier will catch it, the line is pure waste — Claude Code sees the lint failure and fixes it anyway.
What be