A hook is a small command you register that fires automatically at set moments in a Claude Code session โ formatting files, blocking risky commands, or sending you a ping โ without depending on the model to choose to do it.
Pick how you want to use this. You can switch any time from the top bar.
Claude Code can edit your files and run terminal commands on its own. Often you want something to happen every single time โ reformat each file it touches, refuse to run destructive commands, ping you when it needs input.
You could just ask in your instructions: "always format after editing." But that's a suggestion the model might forget. A hook is a rule wired into the tool itself, so it runs deterministically โ not when the model feels like it.
A Claude Code turn moves through stages, like a track. Hooks attach to specific points on that track. The orange points below are the moments most people hook into first.
The two you'll use constantly: PreToolUse fires before Claude runs a tool and can block it; PostToolUse fires after a tool succeeds. (In the Explore tab you can click each point.)
Every hook is just three answers: when, which, and what.
The lifecycle moment โ e.g. PostToolUse.
Filter by tool name โ e.g. Edit|Write. Leave empty to fire on all.
The command to run โ usually a shell command.
When a hook fires, Claude Code hands it a JSON description of what's happening โ on standard input. The hook does its work, then replies with an exit code.
No objection. The action proceeds normally. (On a few events, anything printed to stdout is added to Claude's context.)
Block it. Whatever you write to stderr is fed back to Claude as the reason, so it can adjust.
Need finer control than block-or-allow? Exit 0 and print a JSON object instead โ for a PreToolUse hook you can set permissionDecision to "allow", "deny", or "ask".
Here's a guardrail hook: "on any Bash command, block it if it contains rm -rf." Trace what happens when Claude tries to delete a folder.
PreToolUse fires โ matcher Bash matches โ script sees rm -rf โ exits 2 โ Claude Code cancels the command and shows Claude the reason. Try the full interactive version in Explore โ Simulator.
Hooks are defined in plain JSON settings files. Where you put one decides its scope. To browse what's active, run /hooks inside Claude Code (it's read-only โ you edit the files directly, or just ask Claude to add the hook for you).
| File | Scope | Shareable? |
|---|---|---|
| ~/.claude/settings.json | All your projects | No โ local to your machine |
| .claude/settings.json | One project | Yes โ commit it to the repo |
| .claude/settings.local.json | One project | No โ gitignored |
A hook's type doesn't have to be a shell command. There are five, and the last two let a model make the call when a rule needs judgment, not just pattern-matching.
Run a shell command. The default and most common.
POST the event JSON to a URL โ e.g. a shared team audit service.
Call a tool on an already-connected MCP server.
Ask a Claude model (Haiku by default) for a yes/no decision.
Spawn a subagent that can read files and run commands to verify, then decide. Experimental.
When several hooks match the same event, they all run in parallel. For permission decisions the most restrictive answer wins: deny beats ask beats allow.
Hooks are powerful precisely because they run automatically โ which is also why a few things deserve care.
/hooks.That's the whole mental model. Head to Explore to poke at the lifecycle and run the simulator.
Each orange point is an event you can hook. Click one to see when it fires and whether it can block an action.
Pick something for Claude to attempt, toggle which guard hooks are active, then run it and watch the pipeline decide.
The events worth knowing, green for the everyday set and amber for intermediate. Click for detail.