CLAUDE.md is a plain-text file Claude Code reads automatically at the start of every session in that project — which makes it easy to treat as a place to dump generic best-practices advice. The problem is that generic advice gets skimmed less carefully than specific facts, and specific facts are the entire reason the file is worth having in the first place.
"Write clean, readable code. Follow best practices. Use meaningful variable names. Test your changes before committing. Be consistent with the existing style."
"Run npm run test:unit before any commit — the CI pipeline blocks on it anyway. Components go in src/features/<name>, not src/components. Don't touch legacy/billing.js — that's a separate, unstarted refactor."
Notice the "after" version couldn't have been guessed — it's information specific to this project that Claude has no way to know otherwise. The "before" version is true of almost every codebase, which is exactly why it doesn't help: it's not adding anything Claude wouldn't already default to.
A single global CLAUDE.md that tries to cover every client project inevitably either goes generic (to stay true across all of them) or contradicts itself (client A wants tabs, client B wants spaces). Keeping one file per project means every line in it can be specific to that project without needing to hedge for the others.
Generic software-engineering advice, anything that's true of every project regardless of context, and — importantly — anything that must never be violated under any circumstance. That last category belongs in a hook, not CLAUDE.md, because CLAUDE.md is a prompt the model interprets; a hard rule needs to be enforced as code instead of hoped for as an instruction.
CLAUDE.md, hooks, subagents, and MCP all solve different problems — the free guide covers the fundamentals first if you're still getting oriented.
Get the Free Guide →One per project, especially for client work. A global file's generic advice gets skimmed less carefully than a short, project-specific one, and different clients often have genuinely conflicting conventions that don't belong in the same file.
As short as it can be while still being specific. A bloated file with generic best-practices advice gets skimmed less carefully than a tight one with only what's actually project-specific — length isn't the goal, specificity is.
Writing generic advice that would apply to any project ("write clean code," "follow best practices") instead of the specific, real facts about this project that Claude couldn't otherwise know — the actual test command, the actual folder convention, the actual thing not to touch.
No — CLAUDE.md is a prompt the model interprets, so it's right for judgment calls and context, not for a rule that must never be broken. A hard rule belongs in a hook, which runs as real code rather than relying on the model remembering to apply an instruction.