How do Claude Code hooks work?

Updated 2026-07-15Asked across Reddit, Quora & Google· Claude Code
Short answer

Hooks are shell commands Claude Code runs automatically before or after its actions—like auto-formatting after every file edit or running lint before a commit. You define them in settings.json under events such as PreToolUse or PostToolUse, with a matcher for which tool triggers them. A hook can also filter or block an action, giving you deterministic control.

Why — the first-principles explanation

An AI is probabilistic—it usually does what you want, but not always. Hooks make certain steps deterministic. Instead of hoping Claude remembers to format your code, you attach a hook that runs the formatter every single time, guaranteed, because it's a plain shell command the harness executes, not a suggestion the model might skip.

Hooks fire on events in Claude Code's loop. The main ones are PreToolUse (before Claude runs a tool like Bash or Edit) and PostToolUse (after). Each hook has a matcher that says which tool it applies to—for example, only run before `Bash` commands. When the event fires and the matcher matches, Claude Code runs your command, passing the action's details as JSON on standard input.

The powerful part is that a hook can change the outcome. A PreToolUse hook can inspect the command Claude is about to run and rewrite it, allow it, or block it by returning a small JSON decision. That's how you enforce policy—say, filtering a test command to show only failures, or refusing edits to protected files. Because it's just a script, a hook can do anything your shell can: format, lint, log, notify, or gate. You're wiring guaranteed behavior into Claude's workflow.

An example that makes it click

Think of a factory conveyor belt with sensors. Every time a box (Claude's action) passes a checkpoint, a sensor (the hook) does its job automatically—one stamps the box, another weighs it and rejects any that are too heavy. Claude doesn't have to remember to stamp; the sensor always fires. A PreToolUse hook is the sensor before the box moves; PostToolUse is the one right after. And the reject arm—that's a hook blocking an action it doesn't like.

How to do it

  1. Open your settings file (`~/.claude/settings.json` for global, or project settings).
  2. Add a `hooks` section with an event key such as `PreToolUse` or `PostToolUse`.
  3. Set a `matcher` (e.g. `"Bash"` or `"Edit"`) to choose which tool triggers the hook.
  4. Under `hooks`, add a `command` entry pointing to your script or inline shell command.
  5. Make any script executable (`chmod +x`), then test by running an action that matches the trigger.
  6. For gating, have the hook return JSON with a permission decision (allow/deny) or an updated input.

Key facts

Infographic: How do Claude Code hooks work — short answer and key facts
Visual summary — How do Claude Code hooks work?
CC
Try Claude Code by Anthropic

Anthropic's agentic coding tool that works in your terminal.

Affiliate link — we may earn a commission at no cost to you.
Visit Claude Code ↗
▶ The 60-second explainer (script)

How do Claude Code hooks work? Hooks are shell commands that run automatically before or after Claude's actions—and they solve a real problem. An AI usually does what you ask, but not always. Hooks make certain steps guaranteed, because they're plain scripts the system runs, not suggestions the model might forget. They fire on events. The two big ones are PreToolUse—before Claude runs a tool like Bash or Edit—and PostToolUse, right after. Each hook has a matcher that picks which tool triggers it. So you can auto-format code after every edit, or run lint before every commit, every single time. The really powerful part: a PreToolUse hook can inspect what Claude's about to do and allow it, block it, or rewrite it—by returning a little JSON decision. That's how you enforce rules, like refusing edits to protected files or trimming test output to just the failures. You set them up in settings dot json, with an event, a matcher, and a command. Because it's just a script, a hook can do anything your shell can.

What authoritative sources say

Claude Code Docs — Overviewofficial — Hooks let you run shell commands before or after Claude Code actions, like auto-formatting after an edit or running lint before a commit. source ↗
Claude Code Docs — Manage costs (hooks example)official — A PreToolUse hook configured in settings.json with a matcher can allow or rewrite a command by returning a JSON permission decision. source ↗

People also ask

What can I do with a Claude Code hook?

Auto-format after edits, run lint before commits, filter noisy output, log actions, send notifications, or block risky actions.

Where do I configure hooks?

In your settings.json (global at ~/.claude/settings.json or per project), under a `hooks` section keyed by event.

What are PreToolUse and PostToolUse?

Events that fire before and after Claude runs a tool. PreToolUse can also allow, block, or rewrite the action.

Can a hook stop Claude from doing something?

Yes. A PreToolUse hook can return a JSON decision that denies the action or replaces its input.

Related questions