# Claude Code hooks: why "just tell it not to" doesn't hold up

> Source: <https://dev.to/vincentchabran/claude-code-hooks-why-just-tell-it-not-to-doesnt-hold-up-4d9b>
> Published: 2026-08-02 23:45:52+00:00

If you've spent time customizing Claude Code, you've probably written a line like this in your `CLAUDE.md`

: "always run the formatter after editing a file" or "never touch `.env`

or any `.pem`

/`.key`

file." It works — until a long session, a big diff, or a context window full of other instructions makes that one line easy to deprioritize. The model isn't being careless; a system prompt is advisory. Every instruction in it competes with everything else in context for attention, and instructions written early tend to fade as the conversation grows.

That's a structural limit, not a prompting mistake. And it means anything you actually need to happen every single time — not "usually," not "when the model remembers to" — doesn't belong in a prompt at all.

Claude Code hooks are shell commands wired to specific points in the tool's lifecycle: after a file edit, before a tool runs, when Claude finishes responding, when it needs your permission, at the start of a session. They execute as code, deterministically, regardless of what's in the conversation or what the model "decided" to prioritize that turn. The model doesn't get a vote — the hook just runs.

That distinction matters more than it sounds. A CLAUDE.md rule is a request you're hoping gets honored. A hook is a guarantee, because it's not the model doing the enforcing.

Not everything belongs in a hook. The useful split is:

Getting this backwards is the common failure mode: people write increasingly elaborate CLAUDE.md instructions trying to force deterministic behavior out of a probabilistic system, when a five-line shell hook would have made the question moot.

A statusline doesn't enforce anything — it's just a line under your prompt showing which model, which directory, which git branch you're currently in. It matters for a much smaller reason: once you're running more than one Claude Code session in parallel (a common outcome of subagents and worktrees), "which one is this again" becomes a real source of mistakes. Cheap to add, easy to forget you need until you're context-switching between four terminals.

Before adding another paragraph to your CLAUDE.md, ask whether what you actually want is a rule the model should weigh, or a guarantee that shouldn't depend on it weighing anything at all. If it's the latter, write a hook instead.

*(Written with AI assistance.)*

A working set of these — auto-format on edit, a secret-file guard that blocks writes to `.env`

/`*.pem`

/`*.key`

before they happen, run-tests-on-stop, desktop notifications, and session logging — plus 12 slash commands, 6 subagents, and a git-aware statusline, is packaged as the **Claude Code Power Pack** (copy-paste into `.claude/`

, €29): [https://vincentdu2a.gumroad.com/l/bqndfi](https://vincentdu2a.gumroad.com/l/bqndfi). It's an independent, unofficial project — not affiliated with, endorsed by, or sponsored by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic.
