What are Hooks?
Hooks are scripts that run automatically when specific events occur:- Session lifecycle events - When sessions start or stop
- Tool execution - Before or after tools are used
- Git worktree operations - When worktrees are created or removed
- Configuration changes - When settings are modified
- Agent operations - When agents become idle or tasks complete
Hook Types
Lifecycle Hooks
- SessionStart
- Stop
- Setup
- WorktreeCreate
- WorktreeRemove
Tool Hooks
- PreToolUse
- PostToolUse
Configuration Hooks
- ConfigChange
Agent Hooks
- TeammateIdle
- TaskCompleted
- SubagentStop
Hook Configuration
Hooks are configured inhooks.json files:
hooks.json
Hook Locations
Hooks can be defined at multiple levels:Managed hooks have the highest priority and cannot be disabled by users when
allowManagedHooksOnly is set.Hook Input/Output
Input Format
Hooks receive JSON input via stdin:Output Format
Hooks can output JSON to control behavior:Exit Codes
Tool execution proceeds normally.
Shows stderr to the user but not to Claude. Tool execution proceeds.
Blocks tool execution and shows stderr to Claude. Claude can see the error and adjust.
Generic error. Tool execution may be blocked.
Hook Types Explained
Command Hooks
Execute shell commands:${CLAUDE_PLUGIN_ROOT}- Plugin directory path${CLAUDE_SESSION_ID}- Current session ID- Environment variables from the session
HTTP Hooks
POST JSON to a URL and receive JSON response:Tool Matchers
Control which tools trigger hooks:Exact Match
Multiple Tools
All Tools
Use Cases
Security Validation
Security Validation
Validate commands before execution:
Audit Logging
Audit Logging
Log all tool usage for compliance:
Command Transformation
Command Transformation
Transform commands before execution:
Environment Setup
Environment Setup
Configure environment on session start:
Cleanup Operations
Cleanup Operations
Clean up resources on session end:
Security Considerations
Enterprise Controls
Organizations can enforce hook policies:settings.json
- Users cannot define custom hooks
- Only managed hooks execute
- Provides centralized control
Hook Trust
When installing plugins with hooks:- Review hook code before accepting
- Check hook permissions and scope
- Understand what data hooks can access
- Monitor hook execution in logs
Performance
Hook Execution Time
Hooks run synchronously and block tool execution:- Keep hooks fast (< 100ms recommended)
- Use background processes for slow operations
- Cache results when possible
- Avoid network calls in hot paths
Optimization Tips
Hook Development Workflow
-
Plan the hook
- Identify the lifecycle event
- Determine input/output requirements
- Choose command or HTTP hook type
-
Implement the hook
- Write the hook script
- Handle JSON input/output
- Implement error handling
-
Configure hooks.json
- Set up matchers
- Configure hook execution
- Add description
-
Test the hook
- Test with various inputs
- Verify exit codes
- Check error messages
-
Deploy
- Add to
.claude/hooks/ - Or package in a plugin
- Document behavior
- Add to
Debugging Hooks
Enable Debug Logging
Check Hook Execution
Hook execution is logged in Claude Code’s debug logs:Common Issues
Hook not executing
Hook not executing
- Verify
hooks.jsonis valid JSON - Check matcher pattern matches tool name
- Ensure hook script has execute permissions
- Check hook path is correct
Hook blocking when it shouldn't
Hook blocking when it shouldn't
- Check exit code (should be 0 to allow)
- Verify no stderr output
- Check for unhandled exceptions
Hook input not available
Hook input not available
- Ensure reading from stdin
- Parse JSON correctly
- Check for required fields in input
Next Steps
Lifecycle Events
Learn about all available lifecycle events
Hook Examples
See real-world hook implementations