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:
| Event | When it fires |
|---|---|
| SessionStart | When a session begins or resumes |
| UserPromptSubmit | When you submit a prompt, before Claude processes it |
| PreToolUse | Before a tool call runs, and it can block the call |
| PostToolUse | After a tool call succeeds |
| Notification | When Claude Code sends a notification |
| Stop | When Claude finishes responding |
| SubagentStop | When a subagent finishes |
| SessionEnd | When 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?
| Location | Applies to |
|---|---|
~/.claude/settings.json | All of your projects, on your machine only |
.claude/settings.json | One project, and you can commit it |
.claude/settings.local.json | One project, kept out of git |
A plugin's hooks/hooks.json | Any session where the plugin is on |
| A skill's frontmatter | The rest of the session after the skill runs |
| A subagent's frontmatter | Only 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.