cd /news/developer-tools/what-actually-belongs-in-claude-md-a… · home topics developer-tools article
[ARTICLE · art-79566] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

What actually belongs in CLAUDE.md — and what to move to skills, hooks, or docs

A developer argues that CLAUDE.md files grow too large and lose effectiveness, proposing a sorting strategy that moves situational rules to skills, deterministic checks to hooks, and reference material to docs files. The key insight: every line in CLAUDE.md taxes every request, so only invariants that are cheap to state and expensive to violate should stay there.

read4 min views1 publishedJul 30, 2026

Your CLAUDE.md only grows. Every incident adds a rule, every preference becomes a paragraph, and six months in you have a file that reads like a wiki — and an agent that follows maybe half of it.

The uncomfortable mechanics: CLAUDE.md is loaded into context automatically, which means every line is a tax on every single request, whether it's relevant or not. And instructions are advisory — the more of them there are, the weaker each one pulls. I've watched my own rules drift off quietly in long sessions and only caught it in the diff.

So the real question isn't "what should I write in CLAUDE.md?" It's "what has earned a permanent seat in context — and where does everything else live?"

Claude Code gives you four places to put guidance, and they have very different cost models:

Destination Loaded Costs tokens Enforcement
CLAUDE.md every session, automatically always advisory
Skill body only when the task matches on demand advisory, but scoped
Hook never enters context as prose ~zero deterministic
docs/ file when the agent (or a rule) points at it on demand none — it's reference

Here's the sorting test I use, one sentence per destination.

Keep it in CLAUDE.md if it's true on every turn, cheap to state, and expensive to violate. Build commands, naming conventions, "tests live in test/

, mirrored by path", the tone your commit messages use. If you'd want the rule active even in the middle of an unrelated refactor, it's an invariant — that's what the always-loaded file is for.

Move it to a skill if it starts with "when doing X". Deploy checklists, a review rubric, the release-notes format, your migration playbook. A skill's name and description stay visible so the agent knows it exists, but the body only loads when the task actually matches. That's exactly the deal you want for situational expertise: discoverable, but not billed on every request. (Format details: how to write a SKILL.md that actually triggers.)

Move it to a hook if the sentence contains "never" or "always" and a machine could check it. Formatting before commit, protected paths, "don't touch .env

", "block pushes to main". Don't ask a language model to remember what a shell script can enforce — a hook fires deterministically whether the context is fresh or fifty files deep. (Hook config structure and matchers.)

Move it to a docs file if it's something the agent should read, not obey. Architecture overviews, API quirks, the history of why the billing module is weird. Put it in

docs/

, and leave one line in CLAUDE.md saying when to read it: "Touching billing? Read docs/billing-history.md

first." Reference material rents context only when it's relevant.Three costs stack up on the always-loaded path:

Hooks dodge all three. Skills dodge the first two. Docs dodge all three but enforce nothing. CLAUDE.md is the only slot that pays full price — spend it on the few rules that deserve it.


## Commands
- Build: `pnpm build` / Test: `pnpm test` (single file: `pnpm test path/to.test.ts`)
- Never run `pnpm deploy` directly — use the deploy skill.

## Conventions (always)
- TypeScript strict; no `any`. Errors are returned, not thrown, in `src/core`.
- Tests mirror source paths. New modules need a test file in the same PR.
- Commit messages: imperative mood, reference the issue.

## Enforced by hooks (listed so you know they exist)
- Format-on-edit, protected paths (`.env`, `migrations/`), test gate before commit.

## Where things live
- Architecture: `docs/architecture.md` (read before cross-module changes)
- Billing quirks: `docs/billing-history.md` (read before touching `src/billing`)

## When unsure
- Prefer asking over guessing on anything in `migrations/`.

That's the whole shape: commands, invariants, a pointer to what's machine-enforced, a map, and an escalation rule. One screen. The "enforced by hooks" section is deliberately redundant — the hook does the enforcing, the mention just stops the agent from being surprised.

.claude/skills/<name>/SKILL.md

with a description that names the trigger. Never-events → hooks or CI checks. Reference → docs/

, with a one-line pointer left behind.src/billing

with the word BILLING" — so you can tell at a glance whether the file is being honored at all. (One honest caveat: none of this makes prose rules reliable. Advisory is advisory. What the sort gives you is a small enough always-loaded core that the model can actually hold it, plus deterministic enforcement for the things that genuinely can't be violated. If a rule keeps breaking after all this, that's your signal it wanted to be a hook all along.

If you're not sure how your rules files get read in the first place — CLAUDE.md, AGENTS.md, and Cursor's rules all load differently — start with how each tool actually loads your project rules.

I'm Rulestack — I build and maintain drop-in rule, skill, and hook packs for Claude Code, Cursor, and Codex, at rulestack.gumroad.com. I post working AI-coding tips on Bluesky at @ai-shop.bsky.social — follow along if this was useful.

── more in #developer-tools 4 stories · sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/what-actually-belong…] indexed:0 read:4min 2026-07-30 ·