Configure Claude Code hooks to automate your workflow
Configure Claude Code hooks to automate your workflow
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.
➔ Download Our Free AI Readiness Pack
Claude Code hooks are deterministic triggers that run your shell commands at specific points in Claude Code’s lifecycle. Use them to auto-format files after edits, enforce project rules, block risky ops, inject context at session start, or notify you when input’s needed—without relying on the model to “remember”.
Why hooks matter
Prompts are great for suggestions; hooks are guarantees. They fire every time the matching event occurs (e.g., before a tool runs, after an edit, when a session starts/ends). That means consistent formatting, policy enforcement and guardrails across your team—no extra prompting required.
What Claude Code hooks can do
Pre-empt risky actions: Block writes to
.env, production config, or/.git. (Use PreToolUse with exit-code control.)Auto-apply standards: Run
prettier,gofmt, or your linter after every edit/write (PostToolUse).Inject context automatically: At SessionStart, load recent tickets or a coding checklist into the conversation.
Clickless notifications: Desktop pop-ups when Claude needs approval (Notification).
Gate prompts/tools: Approve, deny, or ask for confirmation via PreToolUse / PermissionRequest decision control.
Hooks are configured in user, project, or local project settings—and can also be enforced via enterprise policy settings. Claude Code
The hook events you’ll actually use
PreToolUse / PermissionRequest / PostToolUse — wrap tool calls (Bash, Edit, Write, Read, Grep, WebFetch, Task/subagents). Allow, deny or ask; modify inputs; or give feedback after.
UserPromptSubmit — validate or enrich prompts before Claude processes them; you can inject text or structured context.
SessionStart / SessionEnd — set up environment, load context, and clean up/log at the end.
Notification, Stop, SubagentStop, PreCompact — alerts, end-of-response control, and compaction hooks.
A fast, safe setup (5 steps)
Open the Hooks UI: run
/hooksinside Claude Code. Choose an event (e.g., PreToolUse).Add a matcher: e.g.,
Edit|Writeto intercept file changes, orBashto govern shell commands.*matches everything.Add the hook: choose
type: "command"and enter your shell command (it receives JSON on stdin; usejq/Python to parse).Choose storage:
~/.claude/settings.json(user),.claude/settings.json(project, commit to repo),.claude/settings.local.json(local only),or enterprise policy (centrally enforced).
Verify & test:
/hooksshows your config; run a quick command and check your log/output.
Copy-ready examples
1) Log every 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 runs 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) Protect 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 surfaces your stderr to Claude (and/or the user) according to the per-event rules. Claude Code
4) Get desktop alerts when Claude needs you
Notification hook:
{ "hooks": { "Notification": [ { "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Awaiting your input'" } ] } ] } }
5) Pre-load context at session start
SessionStart can inject extra guidance or a checklist:
Write plain text to stdout (exit code 0) to add context, or
Return JSON with
hookSpecificOutput.additionalContext.
Advanced control: exit codes & JSON decisions
0: success.
stdoutmay be parsed as JSON for structured control (e.g.,"allow"|"deny"|"ask"on PreToolUse;"block"on PostToolUse/Stop; addadditionalContext).2: blocking error. Skips JSON; uses stderr as the message and blocks per-event rules (e.g., deny a PreToolUse).
Other non-zero: non-blocking; shows stderr in verbose mode.
CI and non-interactive use (bonus)
Combine 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 trigger it each run. Anthropic
Security & governance essentials
Hooks run automatically with your user’s credentials; review scripts carefully and follow the Security Best Practices (quote variables, validate inputs, avoid sensitive paths, use absolute paths).
Config edits don’t hot-apply: Claude snapshots hooks at session start and asks you to review changes in
/hooks—a protection against malicious modifications.Enterprise can enforce policy hooks org-wide for consistency.
FAQs
What are Claude Code hooks?
User-defined shell commands that run 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 via enterprise policy settings; /hooks offers an interactive editor. Claude Code
How do I block 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 add context automatically?
Yes—UserPromptSubmit and SessionStart can inject text or structured additionalContext into the conversation before Claude proceeds. Claude Code
Do hooks work with plugins/MCP tools?
Yes—plugins can contribute hooks, and you can target MCP tools via matchers; multiple hooks can run in parallel for a single event. Claude Code
Claude Code hooks are deterministic triggers that run your shell commands at specific points in Claude Code’s lifecycle. Use them to auto-format files after edits, enforce project rules, block risky ops, inject context at session start, or notify you when input’s needed—without relying on the model to “remember”.
Why hooks matter
Prompts are great for suggestions; hooks are guarantees. They fire every time the matching event occurs (e.g., before a tool runs, after an edit, when a session starts/ends). That means consistent formatting, policy enforcement and guardrails across your team—no extra prompting required.
What Claude Code hooks can do
Pre-empt risky actions: Block writes to
.env, production config, or/.git. (Use PreToolUse with exit-code control.)Auto-apply standards: Run
prettier,gofmt, or your linter after every edit/write (PostToolUse).Inject context automatically: At SessionStart, load recent tickets or a coding checklist into the conversation.
Clickless notifications: Desktop pop-ups when Claude needs approval (Notification).
Gate prompts/tools: Approve, deny, or ask for confirmation via PreToolUse / PermissionRequest decision control.
Hooks are configured in user, project, or local project settings—and can also be enforced via enterprise policy settings. Claude Code
The hook events you’ll actually use
PreToolUse / PermissionRequest / PostToolUse — wrap tool calls (Bash, Edit, Write, Read, Grep, WebFetch, Task/subagents). Allow, deny or ask; modify inputs; or give feedback after.
UserPromptSubmit — validate or enrich prompts before Claude processes them; you can inject text or structured context.
SessionStart / SessionEnd — set up environment, load context, and clean up/log at the end.
Notification, Stop, SubagentStop, PreCompact — alerts, end-of-response control, and compaction hooks.
A fast, safe setup (5 steps)
Open the Hooks UI: run
/hooksinside Claude Code. Choose an event (e.g., PreToolUse).Add a matcher: e.g.,
Edit|Writeto intercept file changes, orBashto govern shell commands.*matches everything.Add the hook: choose
type: "command"and enter your shell command (it receives JSON on stdin; usejq/Python to parse).Choose storage:
~/.claude/settings.json(user),.claude/settings.json(project, commit to repo),.claude/settings.local.json(local only),or enterprise policy (centrally enforced).
Verify & test:
/hooksshows your config; run a quick command and check your log/output.
Copy-ready examples
1) Log every 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 runs 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) Protect 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 surfaces your stderr to Claude (and/or the user) according to the per-event rules. Claude Code
4) Get desktop alerts when Claude needs you
Notification hook:
{ "hooks": { "Notification": [ { "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Awaiting your input'" } ] } ] } }
5) Pre-load context at session start
SessionStart can inject extra guidance or a checklist:
Write plain text to stdout (exit code 0) to add context, or
Return JSON with
hookSpecificOutput.additionalContext.
Advanced control: exit codes & JSON decisions
0: success.
stdoutmay be parsed as JSON for structured control (e.g.,"allow"|"deny"|"ask"on PreToolUse;"block"on PostToolUse/Stop; addadditionalContext).2: blocking error. Skips JSON; uses stderr as the message and blocks per-event rules (e.g., deny a PreToolUse).
Other non-zero: non-blocking; shows stderr in verbose mode.
CI and non-interactive use (bonus)
Combine 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 trigger it each run. Anthropic
Security & governance essentials
Hooks run automatically with your user’s credentials; review scripts carefully and follow the Security Best Practices (quote variables, validate inputs, avoid sensitive paths, use absolute paths).
Config edits don’t hot-apply: Claude snapshots hooks at session start and asks you to review changes in
/hooks—a protection against malicious modifications.Enterprise can enforce policy hooks org-wide for consistency.
FAQs
What are Claude Code hooks?
User-defined shell commands that run 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 via enterprise policy settings; /hooks offers an interactive editor. Claude Code
How do I block 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 add context automatically?
Yes—UserPromptSubmit and SessionStart can inject text or structured additionalContext into the conversation before Claude proceeds. Claude Code
Do hooks work with plugins/MCP tools?
Yes—plugins can contribute hooks, and you can target MCP tools via matchers; multiple hooks can run in parallel for a single event. Claude Code
Get weekly AI news and advice delivered to your inbox
By subscribing you consent to Generation Digital storing and processing your details in line with our privacy policy. You can read the full policy at gend.co/privacy.
Generation
Digital

UK Office
Generation Digital Ltd
33 Queen St,
London
EC4R 1AP
United Kingdom
Canada Office
Generation Digital Americas Inc
181 Bay St., Suite 1800
Toronto, ON, M5J 2T9
Canada
USA Office
Generation Digital Americas Inc
77 Sands St,
Brooklyn, NY 11201,
United States
EU Office
Generation Digital Software
Elgee Building
Dundalk
A91 X2R3
Ireland
Middle East Office
6994 Alsharq 3890,
An Narjis,
Riyadh 13343,
Saudi Arabia
Company No: 256 9431 77 | Copyright 2026 | Terms and Conditions | Privacy Policy
Generation
Digital

UK Office
Generation Digital Ltd
33 Queen St,
London
EC4R 1AP
United Kingdom
Canada Office
Generation Digital Americas Inc
181 Bay St., Suite 1800
Toronto, ON, M5J 2T9
Canada
USA Office
Generation Digital Americas Inc
77 Sands St,
Brooklyn, NY 11201,
United States
EU Office
Generation Digital Software
Elgee Building
Dundalk
A91 X2R3
Ireland
Middle East Office
6994 Alsharq 3890,
An Narjis,
Riyadh 13343,
Saudi Arabia










