Claude code hooks are user-defined shell commands that Claude Code runs automatically at specific points in its lifecycle — for example, before or after a tool runs, or when the assistant finishes responding. Where the model decides what to do, hooks let you decide what must happen deterministically every single time: auto-formatting edited files, blocking a dangerous command, or pinging a notification channel. If you want guardrails that don't depend on the model remembering an instruction, hooks are the feature to reach for. (Claude Drops is an independent project and is not affiliated with Anthropic; always confirm exact syntax against the official Claude Code docs.)
What are Claude code hooks?
A hook is a command that the Claude Code harness executes in response to a lifecycle event. You register hooks in your settings (a settings.json file), mapping an event to one or more commands. When that event fires, Claude Code shells out and runs your command, passing structured JSON about the event on standard input. The key insight is that hooks are executed by the harness itself, not by the model — so they fire reliably regardless of what the model chooses to do. That makes them ideal for policy you can't afford to leave to chance.
Think of it as the difference between asking a teammate to "please run the linter after you edit" and wiring the linter into a pre-commit step. The first depends on memory and goodwill; the second happens every time. Hooks bring that same determinism to an AI coding agent. For a broader tour of the vocabulary around the tool, the Claude Code glossary is a useful companion.
Why hooks matter for Claude Code automation
The whole point of Claude Code automation is to offload repetitive work — but you still want control over the parts that have to be correct. Hooks give you that control without micromanaging the model. A few high-value reasons developers reach for them:
- Deterministic guardrails. Block edits to protected paths (like
.envor a production migration directory) or reject obviously destructive shell commands before they run. - Consistent formatting. Run Prettier, gofmt, Black, or your formatter of choice immediately after a file is edited, so the codebase stays clean without the model having to remember.
- Notifications. Send a desktop alert, Slack message, or push notification when Claude finishes a long task or is waiting on your input.
- Auditing and logging. Append a record of every tool call to a log file for later review — handy in teams that need traceability.
- Context injection. Surface project-specific reminders or environment details at the right moment so the model has what it needs.
Because these behaviors are wired into the harness, they compose nicely with other features. Pair a formatting hook with custom slash commands and you get a workflow where one command kicks off a task and hooks keep the output tidy and safe automatically.
Lifecycle events you can hook into
Claude Code exposes a number of lifecycle events, and the window around a tool call is the most common place to attach behavior. The general categories look like this:
| Event category | When it fires | Typical use |
|---|---|---|
| Before a tool runs | Right before Claude executes a tool such as a file edit or a shell command | Validate or block the action; inspect arguments |
| After a tool runs | Immediately after a tool completes | Format edited files; log the result |
| On notification | When Claude needs your attention or is waiting | Send a desktop or push alert |
| On stop / finish | When the assistant finishes its response | Run a final check, summary, or cleanup |
| On session start | At the beginning of a session | Inject context or set up the environment |
Anthropic regularly refines hook events and their payloads, so it's worth watching the release notes. You can follow every change on the Claude Code changelog or read the raw source at the CHANGELOG.md on GitHub.
How to configure Claude code hooks in settings.json
Hooks live in your Claude Code settings. You can scope them at different levels — user-wide, per-project, or in a local (un-committed) override — which lets a whole team share guardrails while individuals keep personal tweaks private. The structure nests an event to a list of matcher groups, each containing the hooks to run. Conceptually it looks like the shape below; treat the exact field names as illustrative and verify them against the docs.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "prettier --write \"$file_path\" 2>/dev/null || true"
}
]
}
]
}
}The matcher targets which tools the hook applies to, so a formatting hook can fire only for file edits and ignore everything else. Your command receives event details on stdin as JSON, which you can parse with jq or a small script to read the file path, tool name, and arguments (for an edit, the path typically lives at tool_input.file_path). For hooks that can block an action, the exit code controls whether Claude Code proceeds — a blocking exit stops the tool from running.
Practical Claude code hooks examples
Here are a few patterns worth stealing. They're illustrative — adapt the event names and payload parsing to the current schema in the docs.
Auto-format on every edit
Attach a formatter to the after-tool event (the post-tool-use event), matched to edit and write tools. Now any file Claude touches comes back formatted to your project's standard, without a single reminder in your prompt.
Block edits to protected files
On the before-tool event (the pre-tool-use event), read the target path from stdin and exit with a blocking status if it matches something sensitive like a secrets file or a lockfile. This is a deterministic safety net that doesn't rely on the model honoring an instruction.
#!/usr/bin/env bash
# Reject edits to protected paths. Reads the tool-input JSON on stdin.
# In Claude Code, exit code 2 signals a blocking error on PreToolUse.
input=$(cat)
path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
case "$path" in
*.env|*/secrets/*|*pnpm-lock.yaml)
echo "Blocked: $path is protected" >&2
exit 2 ;;
esac
exit 0Notify when a task finishes
On the stop or notification event, fire a desktop notification or push so you can step away during long runs and get pulled back when Claude needs you. This pairs especially well with agent workflows where a task might run for several minutes.
Hooks vs. instructions vs. permissions
Claude Code gives you a few overlapping ways to shape behavior, and choosing the right one keeps your setup clean:
- Project instructions (CLAUDE.md): guidance the model reads and usually follows — great for style and conventions, but not guaranteed.
- Permissions / allowlists: control which tools and commands are allowed at all, prompting or denying as needed.
- Hooks: deterministic code that runs on lifecycle events — the right tool when something must happen or must not happen, every time, regardless of the model's choices.
A good mental model: use instructions for preferences, permissions for what's allowed, and hooks for what's enforced. The three layers complement each other rather than compete.
Getting started safely
- Start with a single, harmless hook — like logging tool calls to a file — to confirm the wiring works.
- Add a formatting hook scoped to edit tools and watch your diffs come back clean.
- Introduce a blocking hook only once you've tested its logic in isolation, so a bug doesn't lock you out of legitimate edits.
- Commit team-wide hooks to your project settings and keep experimental ones in your local settings file.
- Re-check the docs after each Claude Code update, since event names and payloads can change.
Hooks are one of the highest-leverage features for turning Claude Code from a smart assistant into a dependable part of your toolchain. Start small, layer in guardrails as you trust them, and let determinism handle the parts that can't be left to chance. To stay current on new hook events and other improvements, browse the Claude Code changelog — or grab the Claude Drops app from the home page to get a push notification the moment a new release ships.
Maintainer, Claude Drops
Ian builds Claude Drops and reads every Claude Code release so you don't have to. He writes plain-English guides to Claude Code's features, drawing directly from the official changelog and documentation.