Claude Code hooks · practical guide
Use hooks for behavior that must happen every time.
A useful hook is small, deterministic, and easy to trigger on purpose. Start with one repository-specific risk or repeated verification step—not a second orchestration system.
Pick the event from the guarantee you need
| Need | Hook event | Good first use |
|---|---|---|
| Inspect a tool call before it runs | PreToolUse | Block a protected path or a dangerous repository command. |
| React after a successful edit or tool call | PostToolUse | Format only the file just changed. |
| Verify work before Claude stops | Stop | Run a bounded fast-test command with a loop guard. |
| Orient a fresh or resumed session | SessionStart | Report branch and dirty-tree state. |
| Alert when attention is needed | Notification | Send a local desktop notification without interpolating model text into code. |
Anthropic’s current hooks guide documents additional events and handler types. Re-check the live reference before relying on a recently added field.
Install three tested starter hooks
The open-source Harden My Repo hooks plugin includes a narrow dangerous-command gate, a protected-path gate, and format-on-edit. Review the scripts first, then run these commands inside Claude Code:
/plugin marketplace add hardenmyrepo/claude-code-hooks
/plugin install harden-my-repo-hooks@harden-my-repo
The repository passes Claude Code’s marketplace validator and behavioral tests. The hooks make no network requests and install no dependencies. Use /hooks after installation to inspect what is enabled.
Minimal project hook wiring
Shared project hooks belong in .claude/settings.json. This example invokes one checked-in command hook before Bash calls:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.sh",
"args": [],
"timeout": 10
}
]
}
]
}
}
The command receives event data as JSON on standard input. Parse it as data. Do not paste tool input, filenames, or model text into an eval, shell command string, AppleScript source, SQL statement, or template that can execute it.
Three hooks worth considering first
1. Protected-path gate
Match Edit|Write on PreToolUse. Parse the target path, normalize it relative to the repository, and reject exact high-risk patterns such as local environment files, private keys, generated migrations, or deployment state. Keep the list repository-specific and provide the matched reason.
2. Fast verification before stop
Run one documented, bounded command—such as a changed-only test selection—when the tree is dirty. Add a loop guard so a persistent failure does not bounce forever. A full integration suite that takes twenty minutes is a poor interactive hook.
3. Formatter after an edit
Use the repository’s installed formatter on only the path reported by the hook. Skip unsupported extensions and missing tools. Never install dependencies from inside the hook.
Give every hook a trigger test
- One expected allow case.
- One expected block or failure case.
- A filename containing spaces, quotes, and shell metacharacters.
- Missing optional dependency behavior.
- A timeout or malformed-input case.
- The exact command a teammate can run to reproduce the result.
Common failure modes
- Broad matchers attached to slow commands.
- Blocking by substring when token or path-aware matching is required.
- Assuming one command spelling covers reordered flags and aliases.
- Trusting a hook because it exists without exercising its trigger.
- Using a model-based hook for a deterministic policy check.
- Forgetting that checked-in hook commands execute on teammates’ machines.
For the current event schema, matcher rules, output behavior, and troubleshooting steps, use Anthropic’s official hooks reference.
Check before adding automation
Audit the repository’s current agent setup first.
The free browser audit checks for instructions, project policy, hooks, CI, tests, ownership, documentation, dependency locking, and secret-hygiene signals without uploading repository contents.
Get 3 hooks on GitHubAudit a repo freeDownload Lite