Claude Code hooks

A Claude Code hook is a shell command that you set to run at a fixed point in a session, such as right after Claude edits a file. Hooks always run. The model does not get to choose. You add one by putting a hooks block in a settings file, as the example below shows.

What can a hook do?

Hooks are for jobs that must happen every time. Common uses from the docs are formatting files after edits, blocking edits to protected files and sending a desktop alert when Claude needs your input. A hook can also run a Claude model to judge a condition, through a prompt or agent hook.

Which events can a hook run on?

Each hook is tied to an event. These are the ones most people start with:

EventWhen it fires
SessionStartWhen a session begins or resumes
UserPromptSubmitWhen you submit a prompt, before Claude processes it
PreToolUseBefore a tool call runs, and it can block the call
PostToolUseAfter a tool call succeeds
NotificationWhen Claude Code sends a notification
StopWhen Claude finishes responding
SubagentStopWhen a subagent finishes
SessionEndWhen a session ends

The hooks reference lists every event. Tool events take a matcher, and the matcher is the tool name, such as Edit|Write or Bash.

How do I set up a hook?

This hook runs Prettier on every file that Claude edits. Add it to .claude/settings.json in your project root:

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

Type /hooks at the Claude Code prompt to check it. The hooks browser groups every hook you have by event.

How does a hook block an action?

Use a PreToolUse hook. If its command exits with code 2, Claude Code blocks the tool call, and the text your script writes to stderr goes back to Claude as the reason. Exit code 0 means no objection, and the normal permission check still applies. A PostToolUse hook runs after the tool call, so it cannot undo the action.

Where do hooks live?

LocationApplies to
~/.claude/settings.jsonAll of your projects, on your machine only
.claude/settings.jsonOne project, and you can commit it
.claude/settings.local.jsonOne project, kept out of git
A plugin's hooks/hooks.jsonAny session where the plugin is on
A skill's frontmatterThe rest of the session after the skill runs
A subagent's frontmatterOnly while that subagent runs

To turn every hook off, set "disableAllHooks": true in your settings.

FAQ

Are hooks the same as skills?

They are not. A skill gives Claude instructions that it chooses to follow. A hook is a command that runs every time its event fires.

Can a skill bring its own hooks?

A skill can define hooks in its frontmatter, and they stay on for the rest of the session once the skill is invoked.

Do hooks only run shell commands?

Command hooks are the main type. The docs also list http, mcp_tool, prompt and agent hooks, and they mark agent hooks as experimental.

Ad Sponsor this spot. Reach developers who pick skills