All articles

What Hooks Are and Why They're Deterministic

When you ask Claude Code to "always run the formatter after editing," you are trusting the model to remember. Sometimes it will. Sometimes it won't. Hooks fix that. A hook is a shell command that Claude Code runs itself at a fixed point in the session, whether or not the model thinks to do it.

Why deterministic matters

A prompt is a request. A hook is a rule. The difference is guaranteed execution. If you tell Claude in your CLAUDE.md to format code, that instruction competes with everything else in context and can get dropped. A hook runs every single time the matching event happens, with no reasoning step in between.

That makes hooks the right tool for anything you cannot afford to skip: formatting, blocking risky commands, running tests, or loading project context.

Where hooks live

Hooks are configured in settings.json under a "hooks" key. Each entry names an event and a command to run:

{
  "hooks": {
    "PostToolUse": [
      { "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": "npx prettier --write \"$CLAUDE_FILE_PATHS\"" }] }
    ]
  }
}

That command hook receives details about the event as JSON on its standard input, so it can inspect what happened before acting.

The mental model

Think of hooks as event handlers for your coding session. Claude does the creative work; hooks enforce the guardrails around it. Because they are plain shell commands, anything you can script, you can wire in. The rest of this series walks through each event and shows real, working configurations you can drop straight into your project.

Comments

Be the first to comment.