What hooks are
A hook is a shell command, HTTP request, LLM prompt, or agentic verifier attached to a hook event (such asPreToolUse) and optionally filtered by a matcher (such as "Bash"). When the event fires, Claude Code runs all matching hooks in the order they appear in your settings.
Hooks are configured under the hooks key in any settings.json file — user, project, or local. See Settings for file locations.
Hook events
The following hook events are available:Tool lifecycle
Tool lifecycle
| Event | When it fires |
|---|---|
PreToolUse | Before a tool call is sent to Claude |
PostToolUse | After a tool call completes successfully |
PostToolUseFailure | After a tool call fails |
Session lifecycle
Session lifecycle
| Event | When it fires |
|---|---|
SessionStart | When a new session begins |
SessionEnd | When a session ends |
Setup | Early in session setup |
Stop | When Claude stops generating |
StopFailure | When a stop fails |
UserPromptSubmit | When the user submits a prompt |
Subagents and compaction
Subagents and compaction
| Event | When it fires |
|---|---|
SubagentStart | When a subagent session starts |
SubagentStop | When a subagent session stops |
PreCompact | Before context compaction |
PostCompact | After context compaction |
Permissions and notifications
Permissions and notifications
| Event | When it fires |
|---|---|
PermissionRequest | When Claude requests permission for a tool |
PermissionDenied | When a permission request is denied |
Notification | When a notification is emitted |
File and workspace changes
File and workspace changes
| Event | When it fires |
|---|---|
FileChanged | When a file changes on disk |
CwdChanged | When the working directory changes |
InstructionsLoaded | When CLAUDE.md instructions are loaded |
ConfigChange | When settings change |
WorktreeCreate | When a git worktree is created |
WorktreeRemove | When a git worktree is removed |
Hook types
Each hook entry specifies atype field that determines how it runs.
- command
- http
- prompt
- agent
Runs a shell command. The most common hook type.
| Field | Type | Description |
|---|---|---|
command | string | Shell command to execute |
shell | "bash" | "powershell" | Shell interpreter (default: bash) |
timeout | number | Timeout in seconds for this command |
statusMessage | string | Custom spinner message while the hook runs |
async | boolean | Run in background without blocking (default: false) |
asyncRewake | boolean | Background hook that wakes the model on exit code 2 |
once | boolean | Run once and remove after execution |
if | string | Permission-rule syntax to conditionally run (e.g. "Bash(git *)") |
Configuration in settings.json
Hooks are nested under thehooks key. Each top-level key is a hook event; its value is an array of matcher objects:
| Field | Type | Description |
|---|---|---|
matcher | string | Tool name or pattern to match (e.g. "Bash", "Write"). Omit to match all tools |
hooks | object[] | One or more hook definitions to run when the matcher matches |
Hook execution flow
PreToolUse hooks run
All matching
PreToolUse hooks execute in order. Hook receives the tool name and input as JSON via environment variables.Hook environment
Forcommand hooks, the following environment variables are available:
| Variable | Value |
|---|---|
CLAUDE_TOOL_NAME | Name of the tool being called (e.g. Bash) |
CLAUDE_TOOL_INPUT | Full JSON input to the tool |
CLAUDE_HOOK_EVENT | Event name (e.g. PreToolUse) |
Blocking a tool call
APreToolUse hook can block a tool call by exiting with a non-zero exit code. Claude receives an error and does not execute the tool.
Example hooks
Log all tool calls
Log all tool calls
Block dangerous bash patterns
Block dangerous bash patterns
Post to webhook on session end
Post to webhook on session end
LLM-based safety check
LLM-based safety check
Hook sources
Hooks can come from multiple sources, resolved in priority order:| Source | Location |
|---|---|
| User settings | ~/.claude/settings.json |
| Project settings | .claude/settings.json |
| Local settings | .claude/settings.local.json |
| Plugin hooks | ~/.claude/plugins/*/hooks/hooks.json |
| Session hooks | In-memory, temporary |
| Built-in hooks | Registered internally by Claude Code |
When
allowManagedHooksOnly: true is set in managed settings, only hooks from the managed policy file run. User, project, and local hooks are ignored.Disabling hooks
To disable all hooks and status line execution for a session or globally:--bare CLI flag or CLAUDE_CODE_SIMPLE=1) to skip hooks entirely along with other non-essential features.