Skip to main content

What Are Hooks?

Hooks are scripts that execute at specific points in Claude Code’s lifecycle:
  • Before and after tool use (PreToolUse, PostToolUse)
  • On user interactions (UserPromptSubmit, PermissionRequest)
  • Session lifecycle (SessionStart, SessionEnd)
  • Agent lifecycle (SubagentStart, SubagentStop)
  • System events (PreCompact, ConfigChange)
Hooks run outside the agentic loop — they’re deterministic scripts, not AI reasoning.
Hooks are configured in .claude/settings.json under the hooks key, or in agent/skill frontmatter.

Why Hooks Matter

Hooks enable deterministic automation:
  • Validation: Block dangerous commands before execution
  • Notifications: Sound alerts when agents complete tasks
  • Logging: Audit all tool usage and decisions
  • Integration: Trigger external systems (CI/CD, monitoring, Slack)
  • Context injection: Add dynamic data to prompts
  • Decision control: Approve/deny actions programmatically
Hooks are powerful but should be used carefully. They can block Claude Code’s execution or modify behavior in ways that affect all sessions.

Hook Events (18 Total)

Claude Code provides 18 hook events:

Hook Types

Claude Code supports three hook types:

Command Hooks

Most commonRuns a shell command. Receives JSON input via stdin, returns via stdout/exit code.

Prompt Hooks

AI-poweredSends a prompt to Claude for single-turn evaluation. Returns {"ok": true/false}.

Agent Hooks

Multi-turnSpawns a subagent with tool access for complex verification.

Configuration

Settings-Based Hooks

Defined in .claude/settings.json:

Agent/Skill Frontmatter Hooks

Scoped to specific agents or skills:
Agent hooks support 6 events: PreToolUse, PostToolUse, PermissionRequest, PostToolUseFailure, Stop (converted to SubagentStop at runtime), SubagentStop.

Hook Properties

string
required
Hook type: command, prompt, or agent
string
Shell command to execute (for type: "command").Supports environment variables like ${CLAUDE_PROJECT_DIR}.
string
LLM prompt for evaluation (for type: "prompt" or type: "agent").
number
default:"60000"
Timeout in milliseconds. Hook is killed if it exceeds this duration.
boolean
default:"false"
Run hook in background without blocking Claude Code.Use for: Logging, notifications, side effects.
boolean
default:"false"
Run only once per session.Use for: SessionStart, SessionEnd, Setup.
string
Regex pattern to filter events.Examples:
  • "Bash" — Only Bash tool
  • "Edit|Write" — Edit or Write tools
  • "mcp__.*" — All MCP tools
  • ".*" — All events (default)
string
Model for prompt-based hooks.Accepted values: haiku, sonnet, opus

Real Example: Voice Hook System

From the reference repository at .claude/hooks/: Structure:
Configuration in .claude/settings.json:
Key Features:
  • Cross-platform sound playback (macOS: afplay, Linux: paplay, Windows: winsound)
  • Configurable per-hook enable/disable via hooks-config.json
  • Special handling: git commits trigger pretooluse-git-committing sound
  • Agent-specific sounds in separate folders

Voice Hook Repository

Complete voice notification system with sound files and cross-platform support

Environment Variables

Available to hook scripts: JSON Input (via stdin): All hooks receive JSON on stdin:

Hook Matchers

Some hooks support matchers to filter events: No matcher support: UserPromptSubmit, Stop, TeammateIdle, TaskCompleted, WorktreeCreate, WorktreeRemove, Setup

Decision Control

Hooks can block operations or modify behavior:

PreToolUse (Block Tool Calls)

Values: allow, deny, ask

Stop / SubagentStop (Block Continuation)

UserPromptSubmit (Modify Prompt)

Best Practices

Logging, notifications, and analytics should run async:
This prevents hooks from slowing down Claude Code.
In .claude/settings.local.json:
Or disable individual hooks in hooks-config.json.
Only fire hooks for relevant events:
Exit codes:
  • 0 — Success, continue
  • 1 — Error (logged, continues)
  • 2 — Block the operation
Always validate input JSON and handle missing fields.
SessionStart, SessionEnd, and Setup should only run once:

Disabling Hooks

Disable All Hooks

In .claude/settings.local.json:

Disable Individual Hooks

In .claude/hooks/config/hooks-config.json:
Local Overrides: Create .claude/hooks/config/hooks-config.local.json (git-ignored) for personal preferences.

Hooks Management

View, add, and delete hooks without editing JSON. Hooks are labeled by source: [User], [Project], [Local], [Plugin].

Settings

Configure hooks in settings.json

Subagents

Add lifecycle hooks to agents

Voice Hooks Example

Complete voice notification system

Settings Best Practice

Full hook configuration reference

Further Reading