Configure Claude Code hooks to streamline your workflow with automation.
Configure Claude Code hooks to streamline your workflow with automation.
Claude
Dec 11, 2025


Not sure what to do next with AI?
Assess readiness, risk, and priorities in under an hour.
Not sure what to do next with AI?
Assess readiness, risk, and priorities in under an hour.
➔ Schedule a Consultation
Claude Code hooks are predictable triggers that execute your shell commands at specific points in the lifecycle of Claude Code. Use them to automatically format files after edits, enforce project guidelines, prevent risky operations, add context at the start of a session, or notify you when input is required—without relying on the model to "remember."
Why hooks are crucial
Prompts are great for suggestions; hooks are guarantees. They activate every time the corresponding event happens (e.g., before a tool operates, post-edit, when a session begins/ends). This ensures consistent formatting, policy enforcement, and protective barriers across your team—no extra prompting needed.
Capabilities of Claude Code hooks
Prevent risky actions: Restrict writes to
.env, production settings, or/.git. (Use PreToolUse with exit-code control.)Automatically apply standards: Execute
prettier,gofmt, or your linter post-edit/write actions (PostToolUse).Add context automatically: During SessionStart, load recent tickets or a coding checklist into the dialogue.
Notify without clicks: Desktop alerts when Claude requires approval (Notification).
Control prompts/tools: Approve, deny, or ask for confirmation via PreToolUse / PermissionRequest decision management.
Hooks are set up in user, project, or local project settings—and can also be applied through enterprise policy settings. Claude Code
The hook events you'll actually utilize
PreToolUse / PermissionRequest / PostToolUse — wrap tool calls (Bash, Edit, Write, Read, Grep, WebFetch, Task/subagents). Allow, deny or ask; modify inputs; or provide feedback afterwards.
UserPromptSubmit — validate or enrich prompts before Claude processes them; inject text or structured context.
SessionStart / SessionEnd — set up the environment, load context, and clean up/log at session conclusion.
Notification, Stop, SubagentStop, PreCompact — alerts, end-of-response control, and compaction hooks.
A quick and safe setup (5 steps)
Open the Hooks UI: run
/hookswithin Claude Code. Select an event (e.g., PreToolUse).Add a matcher: e.g.,
Edit|Writeto intercept file changes, orBashfor shell command management.*matches anything.Add the hook: choose
type: "command"and input your shell command (it receives JSON on stdin; usejq/Python to parse).Choose storage:
~/.claude/settings.json(user),.claude/settings.json(project, commit to repository),.claude/settings.local.json(local only),or enterprise policy (centrally enforced).
Verify & test:
/hooksdisplays your configuration; execute a quick command and assess your log/output.
Ready-to-copy examples
1) Log each Bash command (quick audit)
Register under PreToolUse with matcher Bash:
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt
This executes before each Bash tool call and appends a line to a log file. Claude Code
2) Auto-format TypeScript after edits/writes
PostToolUse with matcher Edit|Write:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }" } ] } ] } }
3) Secure sensitive files (block with exit code 2)
PreToolUse with matcher Edit|Write:
{ "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "python3 -c \"import json, sys; d=json.load(sys.stdin); p=d.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(x in p for x in ['.env','package-lock.json','.git/']) else 0)\"" } ] } ] } }
Exit code 2 blocks the action and displays your stderr to Claude (and/or the user) according to the event-specific rules. Claude Code
4) Receive desktop alerts when Claude requires your input
Notification hook:
{ "hooks": { "Notification": [ { "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Awaiting your input'" } ] } ] } }
5) Pre-load context at session initiation
SessionStart can inject additional guidance or a checklist:
Output plain text to stdout (exit code 0) to add context, or
Return JSON with
hookSpecificOutput.additionalContext.
Advanced control: exit codes & JSON judgments
0: success.
stdoutmay be understood as JSON for structured control (e.g.,"allow"|"deny"|"ask"on PreToolUse;"block"on PostToolUse/Stop; addadditionalContext).2: blocking error. Skips JSON; utilizes stderr as the message and blocks per-event rules (e.g., deny a PreToolUse).
Other non-zero: non-blocking; reveals stderr in verbose mode.
CI and non-interactive usage (bonus)
Integrate hooks with headless mode to run Claude Code in CI, build scripts, or pre-commit style jobs: claude -p "<prompt>" --output-format stream-json. Headless mode is per session, so activate it with each run. Anthropic
Security & governance essentials
Hooks execute automatically with your user credentials; review scripts meticulously and adhere to Security Best Practices (quote variables, validate inputs, avoid sensitive paths, use absolute paths).
Configuration changes don’t hot-apply: Claude captures hook snapshots at session start and requests you review changes in
/hooks—a safeguard against unauthorized modifications.Enterprises can enforce policy hooks organization-wide for consistency.
FAQs
What are Claude Code hooks?
User-defined shell commands that execute at specific lifecycle events in Claude Code (e.g., PreToolUse, PostToolUse, SessionStart) to enforce rules, automate tasks, or add context. Claude Code
Where do I configure them?
In ~/.claude/settings.json, .claude/settings.json, .claude/settings.local.json, or through enterprise policy settings; /hooks offers an interactive editor. Claude Code
How do I prevent dangerous actions?
Return exit code 2 from a PreToolUse/PermissionRequest hook to deny the action and send your error message back to Claude; or use JSON decision control to "deny/ask/allow." Claude Code
Can I inject context automatically?
Yes—UserPromptSubmit and SessionStart are capable of adding text or structured additionalContext into the dialogue before Claude proceeds. Claude Code
Do hooks work with plugins/MCP tools?
Yes—plugins can supply hooks, and you can target MCP tools via matchers; multiple hooks can run simultaneously for a single event. Claude Code
Claude Code hooks are predictable triggers that execute your shell commands at specific points in the lifecycle of Claude Code. Use them to automatically format files after edits, enforce project guidelines, prevent risky operations, add context at the start of a session, or notify you when input is required—without relying on the model to "remember."
Why hooks are crucial
Prompts are great for suggestions; hooks are guarantees. They activate every time the corresponding event happens (e.g., before a tool operates, post-edit, when a session begins/ends). This ensures consistent formatting, policy enforcement, and protective barriers across your team—no extra prompting needed.
Capabilities of Claude Code hooks
Prevent risky actions: Restrict writes to
.env, production settings, or/.git. (Use PreToolUse with exit-code control.)Automatically apply standards: Execute
prettier,gofmt, or your linter post-edit/write actions (PostToolUse).Add context automatically: During SessionStart, load recent tickets or a coding checklist into the dialogue.
Notify without clicks: Desktop alerts when Claude requires approval (Notification).
Control prompts/tools: Approve, deny, or ask for confirmation via PreToolUse / PermissionRequest decision management.
Hooks are set up in user, project, or local project settings—and can also be applied through enterprise policy settings. Claude Code
The hook events you'll actually utilize
PreToolUse / PermissionRequest / PostToolUse — wrap tool calls (Bash, Edit, Write, Read, Grep, WebFetch, Task/subagents). Allow, deny or ask; modify inputs; or provide feedback afterwards.
UserPromptSubmit — validate or enrich prompts before Claude processes them; inject text or structured context.
SessionStart / SessionEnd — set up the environment, load context, and clean up/log at session conclusion.
Notification, Stop, SubagentStop, PreCompact — alerts, end-of-response control, and compaction hooks.
A quick and safe setup (5 steps)
Open the Hooks UI: run
/hookswithin Claude Code. Select an event (e.g., PreToolUse).Add a matcher: e.g.,
Edit|Writeto intercept file changes, orBashfor shell command management.*matches anything.Add the hook: choose
type: "command"and input your shell command (it receives JSON on stdin; usejq/Python to parse).Choose storage:
~/.claude/settings.json(user),.claude/settings.json(project, commit to repository),.claude/settings.local.json(local only),or enterprise policy (centrally enforced).
Verify & test:
/hooksdisplays your configuration; execute a quick command and assess your log/output.
Ready-to-copy examples
1) Log each Bash command (quick audit)
Register under PreToolUse with matcher Bash:
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt
This executes before each Bash tool call and appends a line to a log file. Claude Code
2) Auto-format TypeScript after edits/writes
PostToolUse with matcher Edit|Write:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }" } ] } ] } }
3) Secure sensitive files (block with exit code 2)
PreToolUse with matcher Edit|Write:
{ "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "python3 -c \"import json, sys; d=json.load(sys.stdin); p=d.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(x in p for x in ['.env','package-lock.json','.git/']) else 0)\"" } ] } ] } }
Exit code 2 blocks the action and displays your stderr to Claude (and/or the user) according to the event-specific rules. Claude Code
4) Receive desktop alerts when Claude requires your input
Notification hook:
{ "hooks": { "Notification": [ { "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Awaiting your input'" } ] } ] } }
5) Pre-load context at session initiation
SessionStart can inject additional guidance or a checklist:
Output plain text to stdout (exit code 0) to add context, or
Return JSON with
hookSpecificOutput.additionalContext.
Advanced control: exit codes & JSON judgments
0: success.
stdoutmay be understood as JSON for structured control (e.g.,"allow"|"deny"|"ask"on PreToolUse;"block"on PostToolUse/Stop; addadditionalContext).2: blocking error. Skips JSON; utilizes stderr as the message and blocks per-event rules (e.g., deny a PreToolUse).
Other non-zero: non-blocking; reveals stderr in verbose mode.
CI and non-interactive usage (bonus)
Integrate hooks with headless mode to run Claude Code in CI, build scripts, or pre-commit style jobs: claude -p "<prompt>" --output-format stream-json. Headless mode is per session, so activate it with each run. Anthropic
Security & governance essentials
Hooks execute automatically with your user credentials; review scripts meticulously and adhere to Security Best Practices (quote variables, validate inputs, avoid sensitive paths, use absolute paths).
Configuration changes don’t hot-apply: Claude captures hook snapshots at session start and requests you review changes in
/hooks—a safeguard against unauthorized modifications.Enterprises can enforce policy hooks organization-wide for consistency.
FAQs
What are Claude Code hooks?
User-defined shell commands that execute at specific lifecycle events in Claude Code (e.g., PreToolUse, PostToolUse, SessionStart) to enforce rules, automate tasks, or add context. Claude Code
Where do I configure them?
In ~/.claude/settings.json, .claude/settings.json, .claude/settings.local.json, or through enterprise policy settings; /hooks offers an interactive editor. Claude Code
How do I prevent dangerous actions?
Return exit code 2 from a PreToolUse/PermissionRequest hook to deny the action and send your error message back to Claude; or use JSON decision control to "deny/ask/allow." Claude Code
Can I inject context automatically?
Yes—UserPromptSubmit and SessionStart are capable of adding text or structured additionalContext into the dialogue before Claude proceeds. Claude Code
Do hooks work with plugins/MCP tools?
Yes—plugins can supply hooks, and you can target MCP tools via matchers; multiple hooks can run simultaneously for a single event. Claude Code
Receive practical advice directly in your inbox
By subscribing, you agree to allow Generation Digital to store and process your information according to our privacy policy. You can review the full policy at gend.co/privacy.
Generation
Digital

Business Number: 256 9431 77 | Copyright 2026 | Terms and Conditions | Privacy Policy
Generation
Digital











