"You Don't Need a CLAUDE.md" — A Rebuttal
There is a small but loud school of thought that says CLAUDE.md is unnecessary. The argument runs: if your code is well-written, the agent can figure out the conventions on its own. If your tooling is well-configured, the agent will pick up the rules from the linter and the CI. If your project structure is clear, the agent doesn't need a separate file telling it where things go. CLAUDE.md, in this view, is a workaround for badly-organized projects, and the right move is to fix the project rather than write a file describing how broken it is.
It is a real argument. It is also wrong, and the way it is wrong is worth understanding, because the correct response is not "you're stupid, write a CLAUDE.md." The correct response is to look at what CLAUDE.md actually does and notice that the alternative the rebuttal proposes does not exist.
What the rebuttal gets right
Start with what is true. A messy CLAUDE.md is often a symptom of a messy project. If your CLAUDE.md needs a 60-line section explaining how to run the dev server, your dev server setup is too complicated. If your CLAUDE.md has fifteen rules about how to format imports, your linter is not configured. If your CLAUDE.md describes a layered architecture you wish you had, that is fiction, not documentation.
The rebuttal correctly identifies that a lot of CLAUDE.md content is compensation for tooling gaps. Lint rules belong in the linter. Test conventions belong in the test runner config. Build commands belong in package.json scripts. If you find yourself writing prose where a config file would do, the prose is the wrong tool, and writing more of it just hides the problem.
The rebuttal also correctly notices that agents are getting better at picking up conventions from context. A 2024 agent needed to be told everything; a 2026 agent will read package.json, look at three files in src/, and infer most of the project conventions before you ask. So the marginal value of CLAUDE.md as "convention documentation" is genuinely lower than it used to be.
What the rebuttal gets wrong
But the rebuttal collapses CLAUDE.md to "convention documentation," and that is only one of three things the file does. It also encodes decisions the project has explicitly made that are not visible in the code, and it provides a stable boot sequence the agent reads at session start before it has touched the code at all. Neither of those is replaceable by good code or good tooling.
Decisions invisible in the code are the load-bearing case. The rule "we tried Redux, then Zustand, then settled on Jotai — do not propose moving to Valtio" is not in the code. The code uses Jotai. An agent reading the code learns that Jotai is in use. An agent reading CLAUDE.md learns that Jotai was a deliberate choice and that proposing to move state libraries again is off the table. Without the rule, the agent will eventually look at the project, decide Valtio is more idiomatic, and write a careful proposal for migration. The migration is not what you wanted. The proposal still cost you a session.
Similarly: "this codebase looks like a microservices project but is intentionally a monolith — do not propose splitting." Or: "we use feature flags from LaunchDarkly, not Statsig — both are present in old code, only the LaunchDarkly path is current." Or: "the audit log is required for every database write — do not optimize it away." None of these are deducible from the code. All of them save you sessions where the agent confidently proposes the wrong thing.
The session-boot case is even harder to replace. When an agent starts a new session, it has zero context about your project. It can read files, sure — but reading every file to figure out the conventions costs context budget that you wanted to spend on the actual task. CLAUDE.md is the cheap pre-commit briefing. Replacing CLAUDE.md with "let the agent figure it out" means every session pays the cost of figuring it out, and the figuring-out happens in your context window.
The "but the agent can read the linter" line
A common counterargument: the linter encodes the conventions, so the agent can read the linter config instead of CLAUDE.md. Sometimes this works. Often it does not.
Linter configs encode a subset of conventions that fit linter ergonomics. A linter can enforce "no any in TypeScript." A linter cannot enforce "if you find yourself reaching for any, propose a discriminated union before adding the cast." The first is a rule; the second is the reasoning behind the rule. Agents need both — the rule to follow and the reasoning to apply when an edge case shows up.
Linter configs also have terrible signal-to-noise ratio for an agent reading them cold. A typical eslint config is hundreds of lines of plugin extensions, rule overrides, and ignore patterns. The agent has to parse the entire thing to find the three rules that matter for the current task. A line in CLAUDE.md saying "TypeScript strict, no any, no implicit JSX returns" is about ten times faster to read.
And linters cover a narrow slice. Process rules (PR policy, commit conventions, testing requirements) are not in the linter. Operational notes (this path is a symlink, this CI step is flaky on Tuesdays) are not in the linter. Principles (don't add error handling for cases that can't happen) are not in the linter. The "linter config is enough" claim only holds if your project's rules happen to fit cleanly into linter format, which most don't.
The "but my project is small" line
Another version of the rebuttal: "my project is small enough that the agent can figure it out without help." This is a real edge case — for a 200-file repo with three contributors, the marginal value of CLAUDE.md is genuinely low. But notice the conditions: small, recent, single-language, single-stack, single-team. Most projects break at least two of those conditions within their first year, and the moment they do, the agent's "figure it out from context" approach starts failing in ways that are subtle and hard to debug.
The right policy is not "skip CLAUDE.md until you regret it." It is "write a 50-line CLAUDE.md from day one and grow it as patterns emerge." A 50-line file costs nothing to maintain and pays back the first time someone joins the project or the first time the agent needs to make a decision the code doesn't reveal.
What a CLAUDE.md skeptic should still do
If you are convinced CLAUDE.md is unnecessary, here is the minimal version even you should ship: one paragraph naming the project, three to five hard rules (no direct pushes, lockfile editing policy, test requirement), and one section listing decisions the team has explicitly made that aren't visible in the code. That is a 30-line file. It is not zero, and it is meaningfully different from no file at all.
What it gets you, even at 30 lines, is a place where future explicit decisions can land. The first time someone says "we decided not to use feature X — make sure the agent knows," there is a file to add the rule to. Without the file, the decision lives in someone's head and stays there until the agent proposes feature X six months later and surprises everyone.
The honest assessment
CLAUDE.md, badly done, is worse than no CLAUDE.md. A bloated, contradictory, stale file actively trains the agent to ignore the file. The rebuttal is correctly observing that many CLAUDE.md files in the wild are bad enough to be net-negative. The correct response is not to delete the file — it is to make the file good. Short, correct, machine-checkable, load-bearing.
A good CLAUDE.md is not a workaround for a badly-organized project. It is the explicit memory of a well-organized project, captured in a place the agent reads first. The alternative is letting that memory live only in the team's collective mind, where it drifts faster than the code does and is invisible to every agent that joins the project mid-stream. That is a worse position to be in, and it is the position the rebuttal accidentally argues for.
Write the file. Keep it short. Run AgentLint against it so it stays correct. The argument that you don't need it is, in practice, an argument that you don't need explicit institutional memory — and projects that try to operate without explicit memory always pay for it eventually.