settings.json under the hooks key and are available at the user, project, and managed settings levels.
Quick example
Runprettier after every file write:
.claude/settings.json
Interactive configuration
Run/hooks inside Claude Code to open the hooks configuration menu. The menu lists available events, lets you add or remove matchers and hook commands, and writes changes back to the appropriate settings file.
Hook structure
A hook configuration maps event names to arrays of matcher objects. Each matcher object specifies an optional tool filter and a list of hook commands to run when the filter matches.Matcher
Thematcher field is optional. When present it uses permission rule syntax — the same patterns used in permissions.allow and permissions.deny — to filter which tool calls trigger the hook.
matcher is absent the hooks run for every tool call under that event.
Hook events
PreToolUse
PreToolUse
Fires immediately before Claude executes a tool. Use this event to validate, log, or block tool calls before they run. A non-zero exit code from a
command hook can abort the tool call.PostToolUse
PostToolUse
Fires after a tool completes successfully. Use this to run formatters, linters, or notifications based on what Claude just did.
PostToolUseFailure
PostToolUseFailure
Fires when a tool call fails. Useful for cleanup or alerting on errors.
Notification
Notification
Fires when Claude Code emits a notification (e.g. when it needs user input). Use to bridge notifications to desktop or webhook systems.
UserPromptSubmit
UserPromptSubmit
Fires when the user submits a prompt, before Claude processes it. Useful for logging, prompt augmentation, or pre-submission validation.
SessionStart
SessionStart
Fires once when a new session begins. Use for setup tasks, welcome scripts, or environment validation.
SessionEnd
SessionEnd
Fires when the session ends. Use for teardown, summaries, or syncing session data.
Stop
Stop
Fires when Claude stops (completes a turn). Useful for post-turn processing.
StopFailure
StopFailure
Fires when Claude stops due to an error.
SubagentStart / SubagentStop
SubagentStart / SubagentStop
Fire when a sub-agent (spawned by the main agent) starts or stops.
PreCompact / PostCompact
PreCompact / PostCompact
Fire before and after context compaction. Use
PreCompact to capture the full context before it is compressed; use PostCompact to run post-compaction setup.PermissionRequest / PermissionDenied
PermissionRequest / PermissionDenied
Fire when Claude requests a permission or when a permission is denied. Useful for audit logging.
Setup
Setup
Fires once at startup, before
SessionStart. Runs even in bare mode. Suitable for environment initialization.InstructionsLoaded
InstructionsLoaded
Fires after CLAUDE.md instructions have been loaded into the session context.
FileChanged
FileChanged
Fires when a file is modified (e.g. from a Write or Edit tool call). The changed path is available via
$CLAUDE_FILE_PATHS.CwdChanged
CwdChanged
Fires when the working directory changes.
WorktreeCreate / WorktreeRemove
WorktreeCreate / WorktreeRemove
Fire when a git worktree is created or removed.
Hook types
Command hook
Runs a shell command. This is the most common hook type.Must be
"command".Shell command to execute. Supports environment variable expansion.
Permission rule syntax filter applied before the hook runs (e.g.
"Bash(git *)", "Write(*.ts)"). Avoids spawning the hook process when the tool call does not match.Shell interpreter:
"bash" (uses your $SHELL, bash/zsh/sh) or "powershell" (uses pwsh). Defaults to "bash".Timeout in seconds for this specific command. Overrides the global hook timeout.
Custom message displayed in the spinner while the hook runs.
When
true, the hook runs once and is removed from the configuration after execution.When
true, the hook runs in the background without blocking Claude Code.When
true, the hook runs in the background and wakes the model if it exits with code 2 (indicating a blocking error). Implies async: true.Prompt hook
Evaluates an LLM prompt. Use this to delegate verification or enrichment to a model without spawning a sub-agent.Must be
"prompt".The prompt to send to the model. Use
$ARGUMENTS as a placeholder for the hook input JSON.Permission rule syntax filter (same as command hook).
Model to use for this prompt hook (e.g.
"claude-sonnet-4-6"). Defaults to the configured small fast model.Timeout in seconds for this prompt evaluation.
Custom status message shown in the spinner.
When
true, the hook runs once and is removed after execution.Agent hook
Spawns a full sub-agent to verify or react to a tool call. More powerful than a prompt hook — the agent can itself call tools.Must be
"agent".Prompt describing what to verify or do. Use
$ARGUMENTS as a placeholder for the hook input JSON.Permission rule syntax filter.
Model to use for the agent. Defaults to Haiku.
Timeout in seconds for agent execution. Default is 60.
Custom status message shown in the spinner.
When
true, the hook runs once and is removed after execution.HTTP hook
POSTs the hook input JSON to a URL. Useful for webhooks, audit logging services, and external integrations.Must be
"http".URL to POST the hook input JSON to. Must be a valid URL.
Permission rule syntax filter.
Timeout in seconds for the HTTP request.
Additional headers to include in the request. Values may reference environment variables using
$VAR_NAME or ${VAR_NAME} syntax. Only variables listed in allowedEnvVars will be interpolated.Explicit list of environment variable names that may be interpolated in header values. Variables not listed here are left as empty strings. Required for env var interpolation to work.
Custom status message shown in the spinner.
When
true, the hook runs once and is removed after execution.Common patterns
Format on write
Run tests after edits
Audit log every tool call
Verify git commit is clean before stopping
Enterprise controls
disableAllHooks
disableAllHooks
Set in any settings file to completely disable hook and
statusLine execution.allowManagedHooksOnly
allowManagedHooksOnly
Set in managed settings to prevent user/project/local hooks from running. Only hooks defined in
managed-settings.json will execute.allowedHttpHookUrls
allowedHttpHookUrls
Restrict which URLs HTTP hooks may POST to. Supports
* as a wildcard. Arrays merge across settings sources.httpHookAllowedEnvVars
httpHookAllowedEnvVars
Restrict which environment variable names HTTP hooks may interpolate into headers. Arrays merge across settings sources.