Configure Claude Code hooks to streamline your workflow with automation.

Configure Claude Code hooks to streamline your workflow with automation.

Claude

Dec 11, 2025

A contemporary office space with expansive windows highlights professionals having discussions around a wooden table, with views of lush greenery and the city skyline.
A contemporary office space with expansive windows highlights professionals having discussions around a wooden table, with views of lush greenery and the city skyline.

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)

  1. Open the Hooks UI: run /hooks within Claude Code. Select an event (e.g., PreToolUse).

  2. Add a matcher: e.g., Edit|Write to intercept file changes, or Bash for shell command management. * matches anything.

  3. Add the hook: choose type: "command" and input your shell command (it receives JSON on stdin; use jq/Python to parse).

  4. Choose storage:

    • ~/.claude/settings.json (user),

    • .claude/settings.json (project, commit to repository),

    • .claude/settings.local.json (local only),

    • or enterprise policy (centrally enforced).

  5. Verify & test: /hooks displays 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; }"
          }
        ]
      }
    ]
  }
}

Claude Code

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'" }
        ]
      }
    ]
  }
}

Claude Code

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. stdout may be understood as JSON for structured control (e.g., "allow"|"deny"|"ask" on PreToolUse; "block" on PostToolUse/Stop; add additionalContext).

  • 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)

  1. Open the Hooks UI: run /hooks within Claude Code. Select an event (e.g., PreToolUse).

  2. Add a matcher: e.g., Edit|Write to intercept file changes, or Bash for shell command management. * matches anything.

  3. Add the hook: choose type: "command" and input your shell command (it receives JSON on stdin; use jq/Python to parse).

  4. Choose storage:

    • ~/.claude/settings.json (user),

    • .claude/settings.json (project, commit to repository),

    • .claude/settings.local.json (local only),

    • or enterprise policy (centrally enforced).

  5. Verify & test: /hooks displays 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; }"
          }
        ]
      }
    ]
  }
}

Claude Code

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'" }
        ]
      }
    ]
  }
}

Claude Code

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. stdout may be understood as JSON for structured control (e.g., "allow"|"deny"|"ask" on PreToolUse; "block" on PostToolUse/Stop; add additionalContext).

  • 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.

Are you ready to get the support your organization needs to successfully leverage AI?

Miro Solutions Partner
Asana Platinum Solutions Partner
Notion Platinum Solutions Partner
Glean Certified Partner

Ready to get the support your organization needs to successfully use AI?

Miro Solutions Partner
Asana Platinum Solutions Partner
Notion Platinum Solutions Partner
Glean Certified Partner

Generation
Digital

Canadian Office
33 Queen St,
Toronto
M5H 2N2
Canada

Canadian Office
1 University Ave,
Toronto,
ON M5J 1T1,
Canada

NAMER Office
77 Sands St,
Brooklyn,
NY 11201,
USA

Head Office
Charlemont St, Saint Kevin's, Dublin,
D02 VN88,
Ireland

Middle East Office
6994 Alsharq 3890,
An Narjis,
Riyadh 13343,
Saudi Arabia

UK Fast Growth Index UBS Logo
Financial Times FT 1000 Logo
Febe Growth 100 Logo (Background Removed)

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

Generation
Digital

Canadian Office
33 Queen St,
Toronto
M5H 2N2
Canada

Canadian Office
1 University Ave,
Toronto,
ON M5J 1T1,
Canada

NAMER Office
77 Sands St,
Brooklyn,
NY 11201,
USA

Head Office
Charlemont St, Saint Kevin's, Dublin,
D02 VN88,
Ireland

Middle East Office
6994 Alsharq 3890,
An Narjis,
Riyadh 13343,
Saudi Arabia

UK Fast Growth Index UBS Logo
Financial Times FT 1000 Logo
Febe Growth 100 Logo (Background Removed)


Business No: 256 9431 77
Terms and Conditions
Privacy Policy
© 2026