Hooks Reference
Hooks are automated scripts that execute at specific events during Claude Code sessions. They enable validation, permission management, and context injection.
Hook Types
Command Hooks
Execute bash scripts with structured JSON input via stdin.
- Fast and rule-based
- Deterministic validation
- Local operations
Prompt Hooks
Leverage an LLM (Haiku) for context-aware decisions.
- Intelligent decisions
- Context-aware
- Supported events:
Stop,SubagentStop,UserPromptSubmit,PreToolUse,PermissionRequest
Configuration
Add hooks to your Claude Code settings:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/path/to/validate-edit.sh",
"timeout": 60
}
]
}
]
}
}Matcher Patterns
| Pattern | Matches |
|---|---|
Edit | Edit tool only |
Edit|Write | Edit or Write tools |
* | All tools |
mcp__memory__.* | All memory server tools |
Supported Events
| Event | Purpose | Matcher |
|---|---|---|
PreToolUse | Before tool execution | Yes |
PostToolUse | After tool completes | Yes |
PermissionRequest | Permission dialogs | Yes |
Notification | System notifications | Yes |
UserPromptSubmit | User prompt validation | No |
Stop | Main agent completion | No |
SubagentStop | Subagent completion | No |
PreCompact | Before context compacting | Yes |
SessionStart | Session initialization | Yes |
SessionEnd | Session cleanup | No |
Hook Input
All hooks receive JSON via stdin:
json
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.json",
"cwd": "/current/directory",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Edit",
"tool_input": { "file_path": "..." }
}Hook Output
Exit Codes
| Code | Meaning |
|---|---|
0 | Success (stdout processed) |
2 | Blocking error (stderr shown) |
| Other | Non-blocking error |
JSON Response
json
{
"decision": "approve",
"reason": "File path is safe",
"continue": true,
"systemMessage": "Validation passed",
"suppressOutput": false
}Common Use Cases
File Protection
Block writes to sensitive paths:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "bash -c 'read input; echo $input | jq -e \".tool_input.file_path | test(\\\".env|secrets\\\") | not\" || (echo \"Blocked: sensitive file\" >&2; exit 2)'"
}]
}
]
}
}Code Quality
Run linting after edits:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "npm run lint"
}]
}
]
}
}Context Injection
Add project context at session start:
json
{
"hooks": {
"SessionStart": [
{
"hooks": [{
"type": "command",
"command": "cat project-context.md"
}]
}
]
}
}Environment Variables
| Variable | Purpose |
|---|---|
CLAUDE_PROJECT_DIR | Absolute project path |
CLAUDE_ENV_FILE | Environment file for SessionStart |
CLAUDE_CODE_REMOTE | "true" for remote execution |
Debugging
Enable detailed logging:
bash
claude --debugView registered hooks during session:
/hooksSecurity Best Practices
WARNING
Hooks execute arbitrary shell commands. You're responsible for hook safety.
- Validate and sanitize all inputs
- Use absolute paths for scripts
- Quote shell variables:
"$VAR" - Block path traversal attempts
- Avoid sensitive files (
.env,.git)
Next Steps
- MCP Integration - Connect external tools
- Slash Commands - Custom commands
- Tool Permissions - Permission management