{"slug": "what-works-and-what-doesn-t-in-claude-md", "title": "What Works and What Doesn't in CLAUDE.md", "summary": "A developer who built 10 personal apps in three months shares lessons on writing effective CLAUDE.md files for AI coding assistants. The developer found that vague instructions like 'write clean code' fail, while specific, verifiable prohibitions such as 'do not use pure black' work best. The key insight is that instructions must be objectively checkable, and 'cannot do' rules are more effective than 'do' rules.", "body_md": "Writing \"Write clean code\" in `CLAUDE.md`\n\nchanges nothing.\n\nDuring the process of building 10 personal apps in three months, I rewrote `CLAUDE.md`\n\nmany times.\n\nSince it became clear what worked and what didn't, I will outline that distinction.\n\n```\n- Write clean code\n- Design for maintainability\n- Handle errors appropriately\n- Consider performance\n```\n\n**None of these work.** Because \"clean\" and \"appropriate\" cannot be objectively judged.\n\nInstructions that cannot be judged cannot even be verified by yourself as to whether they are followed.\n\nAnd the person who wrote them cannot verify later if they were followed.\n\nRules that cannot be verified are the same as non-existent.\n\n```\n- Follow the DRY principle\n- Adhere to the Single Responsibility Principle\n- Do not use magic numbers\n```\n\nThe model already knows these. Writing them adds no information.\n\n**The role of CLAUDE.md is to convey what the model does not know (project-specific circumstances).**\n\n```\n- We use Zustand for state management\n- We use Vitest for testing\n```\n\nYou can see this in `package.json`\n\n. If you write anything, it should be \"why we chose it\" or \"what not to do\".\n\n```\n- State management is Zustand. Migration to Redux was considered but rejected due to boilerplate increase. Do not suggest it.\n```\n\nThis is worth writing. You will stop receiving the same suggestions every time.\n\n```\n- Do not use pure black `#000000` or pure white `#ffffff`\n- Do not use gradient backgrounds or gradient heading text\n- Limit to 3 types of motion per screen\n```\n\nYou can verify this with `grep '#000000'`\n\n. **Because it is verifiable, you can mechanically inspect if it is followed.**\n\nThe shape of a UI belongs in a UI specification, not in `CLAUDE.md`\n\n. What goes here\n\nis the **floor beneath the specification** — the line you do not want crossed even\n\nwhen no specification exists. The principle does not change: the persona that writes\n\nthe code does not decide how it looks.\n\n\"Make the UI clean\" does not work, but \"Do not use pure black\" does. The difference lies not in the model's comprehension, but in **whether the instruction is verifiable**.\n\nThis was the most effective.\n\n```\n- Do not modify paths outside the scope described in the assigned Issue\n- If changes outside the scope are needed, stop implementation and report it\n- Only Reviewers may merge to main\n```\n\n**\"Cannot do ~\" is more effective than \"Do ~\".**\n\nInstructions that increase what you can do have a wide range of interpretation, while prohibitions are narrow.\n\nEspecially the phrase \"**stop implementation and report it**\" was effective. Without this,\n\nwhen the model hits constraints, it tries to push forward somehow.\n\nProviding an exit allows it to retreat there.\n\nWhen writing prohibitions, cases of \"but what about this exception?\" always arise. Write them in advance.\n\n```\nThings not treated as out-of-scope:\n- Automatic updates of lock files due to dependency additions\n- Test files corresponding to modified files\n```\n\nIf you don't write them, judgments will vary each time. **Inconsistent judgments hollow out the rules.**\n\n```\n- Do not start issues involving UI until the UI specification status is:done\n- Coders in the parallel execution group must be launched simultaneously within one message\n```\n\nThe second point actually worked. **Separating calls makes them serial**, so\n\nwithout explicit instruction, they will not run in parallel.\n\nFor lists of states or labels, I have the impression that tables are referenced more often than bullet points.\n\n```\n| Label | Meaning | When to assign |\n|---|---|---|\n| `status:planned` | Issue created, not started | When Architect creates the Issue |\n| `status:review` | PR created, waiting for review | When Coder creates the PR |\n```\n\nWriting \"when to assign\" is important. If you only write the meaning, you will forget to assign them\n\n(in the end, I shifted this to GitHub Actions, but that's a different story).\n\nShorter is better.\n\nI once wrote a `CLAUDE.md`\n\nthat swelled to 74KB, but **the latter half was followed less.**\n\nI haven't verified this definitively, but the experience was clear.\n\nThe one I use now is around 7KB. The breakdown is as follows:\n\n| Section | Proportion |\n|---|---|\n| Permissions by role (what can and cannot be done) | 40% |\n| Overall flow (who receives what from whom) | 30% |\n| State management (labels and when to assign them) | 20% |\n| Explicit exceptions | 10% |\n\n**It contains zero general knowledge.**\n\nThe cause of the swelling was \"just in case I write it.\" Lines written \"just in case\" tend to become unjudgable instructions. Unjudgable instructions don't work, so writing them only dilutes the file.\n\nWhether a written rule works is judged by **whether you can notice when it is broken**.\n\n`gh pr diff --name-only`\n\n`grep`\n\nThere is no verification method for the last one. That's why it doesn't work.\n\nBefore writing, asking \"can I notice if this is broken?\" helps you avoid writing ineffective lines.\n\nI have published the `CLAUDE.md`\n\nwritten with this approach and sub-agent definitions for four personas under the MIT license.\n\nI publish the configuration for splitting Claude Code into separate personas —\n\nArchitect, Coder, Reviewer, Conflict Resolver — under MIT. Copy it, run\n\n`./setup.sh`\n\n, and it works. It does not depend on your tech stack.\n\n[https://github.com/quintetkit/quartet](https://github.com/quintetkit/quartet)\n\nI built one real tool using nothing but this workflow. Every Issue, PR, review\n\nand merge is still there. **The parts that went wrong were not deleted.**\n\n[https://github.com/quintetkit/mdlinkcheck](https://github.com/quintetkit/mdlinkcheck)\n\nThe version that adds a UI Designer persona, review criteria, a per-Issue\n\nparallel execution script and a 10-chapter guide is on the\n\n[product page](https://quintetkit.github.io/index.en.html).", "url": "https://wpnews.pro/news/what-works-and-what-doesn-t-in-claude-md", "canonical_source": "https://dev.to/quintetkit/what-works-and-what-doesnt-in-claudemd-d22", "published_at": "2026-09-04 05:30:40+00:00", "updated_at": "2026-09-04 05:53:39.243833+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "large-language-models"], "entities": ["Claude"], "alternates": {"html": "https://wpnews.pro/news/what-works-and-what-doesn-t-in-claude-md", "markdown": "https://wpnews.pro/news/what-works-and-what-doesn-t-in-claude-md.md", "text": "https://wpnews.pro/news/what-works-and-what-doesn-t-in-claude-md.txt", "jsonld": "https://wpnews.pro/news/what-works-and-what-doesn-t-in-claude-md.jsonld"}}