Hooks
Hooks let you run custom shell commands automatically in response to Claude Code tool events. They are the mechanism for injecting your own automation into Claude Code's workflow - running formatters on file writes, logging tool calls, or running tests after edits.
What Hooks Are and When They Fire
A hook is a shell command that Claude Code executes automatically when a specific event occurs. The two main hook types:
- PreToolUse: Fires before Claude Code runs a tool. Can be used to validate, log, or block the tool call. If the hook exits with a non-zero code, the tool call is blocked.
- PostToolUse: Fires after a tool completes. Used for side effects like auto-formatting, running tests, or logging results. Exit code is informational - it does not block the workflow.
Hooks can be scoped to specific tool names: Bash, Edit, Write, Read, Glob, Grep, and MCP tool names.
Configuring Hooks in settings.json
Hooks are defined in ~/.claude/settings.json (global) or .claude/settings.json in your project directory (project-scoped):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "prettier --write "$CLAUDE_TOOL_INPUT_FILE_PATH""
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo "[HOOK] Bash command: $CLAUDE_TOOL_INPUT_COMMAND" >> /tmp/claude-audit.log"
}
]
}
]
}
}The matcher field is a regex matched against the tool name. Hook commands receive context via environment variables set by Claude Code.
Hook Environment Variables
Claude Code sets these environment variables for hooks:
CLAUDE_TOOL_NAME- the name of the tool being called (e.g.,Edit)CLAUDE_TOOL_INPUT_FILE_PATH- for file tools: the path being read/writtenCLAUDE_TOOL_INPUT_COMMAND- for Bash tool: the command being runCLAUDE_TOOL_OUTPUT- for PostToolUse: the tool's output (PostToolUse only)
Common Use Cases
Auto-format on write
PostToolUse on Edit/Write โ run prettier --write or black on the modified file. Ensures all Claude-generated code matches your project's formatting standards without manual formatting steps.
Run tests after edit
PostToolUse on Edit โ run the test file corresponding to the edited source file. Gives Claude immediate feedback on whether its changes break tests, enabling automatic fix-retry loops.
Audit log of shell commands
PreToolUse on Bash โ append the command to an audit log file. Provides a record of every shell command Claude Code ran in a session - useful for security review and debugging.
Block dangerous commands
PreToolUse on Bash โ check if the command matches a blocklist (e.g., rm -rf, DROP TABLE) and exit non-zero to block it. A last-resort safety net for agentic sessions with broad permissions.
Security Considerations
Hooks run as shell commands with the same permissions as your Claude Code process. This means:
- Hooks can read and write files, make network requests, and execute arbitrary code
- A malicious MCP server could theoretically influence hook execution via tool names or outputs - keep hooks simple and explicit
- Be careful with hooks that pass
$CLAUDE_TOOL_INPUT_COMMANDdirectly to a shell - this creates a command injection risk. Quote variables carefully or avoid passing them to shell interpreters. - Test hooks thoroughly before enabling them in agentic sessions - a misconfigured PreToolUse hook that always exits non-zero will block all matching tool calls