AI Hub
ENES

CONCEPT · AGENTS

What Are Agent Hooks?

A hook is a command the environment runs whenever an agent lifecycle event fires, without going through the model's judgment.

3 min read · updated 2026-08

What is it

A hook is a command an agent's environment runs automatically when a lifecycle event occurs: a session opening, a prompt being submitted, a tool being used, a response finishing. It isn't an instruction the model reads and weighs — it's code that runs outside the model, every time, with or without its agreement.

The difference from a written rule is one of kind, not emphasis. A line in CLAUDE.md saying "run the tests after editing" enters the context and competes for the model's attention against everything else in there. A hook that runs the tests after every edit competes with nothing: it fires on its own. Claude Code's official documentation puts it plainly — unlike CLAUDE.md instructions, which are advisory, hooks are deterministic and guarantee the action happens.

That's why hooks are the piece you reach for when "almost always" isn't good enough.

Mental model

A "do not enter" sign and a turnstile solve the same problem through different mechanisms. The sign informs and leaves the decision to whoever reads it; the turnstile informs nothing, it simply doesn't turn. A rule in the prompt is the sign. A hook is the turnstile.

flowchart LR P[Rule written in the prompt] --> M[Model] M -->|weighs it and decides| A[Action] E[Lifecycle event] --> H[Hook] H -->|always executes| A

Both paths end at the same action, but only one passes through a decision. That's the whole difference, and it's why a serious harness combines the two rather than picking one.

How it's used

Hooks live in a settings file: ~/.claude/settings.json for all your sessions, or .claude/settings.json inside the project to share them with your team. Each event name is a key inside a single hooks object:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

The matcher filters which tools the hook applies to, and the command receives a JSON payload on stdin describing the event — hence the jq call to pull out the edited file path.

There are two families of use, with different purposes.

Automating something that should always happen: formatting after each edit, running the linter, logging activity. The hook acts after the fact and doesn't interfere with the agent's decision.

Blocking something that must not happen. A PreToolUse hook runs before the tool executes and can stop it. If the script exits with code 2, the call is blocked and whatever it wrote to stderr goes back to the agent as the reason:

#!/bin/bash
input=$(cat)
command=$(jq -r '.tool_input.command' <<<"$input")
 
if echo "$command" | grep -q 'rm -rf'; then
  echo "Blocked: rm -rf is not allowed in this project" >&2
  exit 2
fi
 
exit 0

For finer control, the same hook can exit 0 and return JSON with permissionDecision set to allow, deny, or ask, instead of the binary cut of exit code 2. That lets you escalate to a human rather than refuse outright.

The available events span most of the lifecycle: SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, PreCompact, and SessionEnd, among many others. The list grows between releases, so check the official reference before assuming an event exists.

When to use it / when not to

A hook is worth it when:

  • The action must happen every time, without exception, and skipping it once is expensive.
  • The task is mechanical and verifiable: formatting, linting, running tests, logging.
  • You need a limit that doesn't depend on the model remembering an instruction buried in thousands of tokens.
  • The whole team needs the same behavior, not just the machine of whoever configured it.

Skip it when:

  • The decision needs judgment. A deterministic command can't evaluate "does this make sense here?". Prompts, skills, or model-based hooks cover that.
  • It's a style preference whose violation breaks nothing. A hook there is pure friction.
  • You're still exploring the workflow. Freezing an unstable process into code costs more than it saves.
  • The command is slow: the hook fires mid-workflow and its latency is added to every event that triggers it.
What Are Agent Hooks? — AI Hub