Hook: Insert Your Own Logic Beyond the Rules

What is a Hook? Think of Claude Code's execution as an assembly line: user input → Claude thinking → tool execution → result returned. A Hook is a pre-drilled socket at a specific point on that line — you plug in your own logic, and it fires automatically at that moment.

Concrete example: the PreToolUse Hook lets you attach a script that routes every Bash command Claude is about to run through your security audit system. If the check fails, the script returns "block" and Claude won't execute that command. The assembly line needs no modification; you simply "hang a hook" at the key spot.

Hooks are the most flexible part of the security mechanism. They let users and enterprises insert custom logic at any key lifecycle point in Claude's operations.

All Hook Events

// src/entrypoints/sdk/coreTypes.ts
const HOOK_EVENTS = [
  'PreToolUse',         // Before tool execution
  'PostToolUse',        // After tool execution (success)
  'PostToolUseFailure', // After tool execution (failure)
  'UserPromptSubmit',   // When user submits a message
  'SessionStart',       // Session starts
  'SessionEnd',         // Session ends
  'Stop',               // Claude finishes a reply
  'StopFailure',        // Claude reply fails
  'SubagentStart',      // Sub-agent starts
  'SubagentStop',       // Sub-agent ends
  'PreCompact',         // Before context compression
  'PostCompact',        // After context compression
  'PermissionRequest',  // When permission is requested
  'PermissionDenied',   // When permission is denied
  'WorktreeCreate',     // Git worktree created
  'WorktreeRemove',     // Git worktree removed
  'FileChanged',        // File changed
  // ...and more
]

Four Hook Types

TypeWhat it doesTypical use
commandRuns a shell scriptAuto-format on save, lint before commit
promptHas Claude process a promptAI reviews whether an upcoming operation is reasonable
agentSpawns a sub-agentComplex automated review logic
httpSends an HTTP requestNotify external systems, write to audit logs

Hook Sources and Priority

policySettings   ← Enterprise enforcement (when allowManagedHooksOnly, user hooks are all ignored)
userSettings     ← User global (~/.claude/settings.json)
projectSettings  ← Project-level (.claude/settings.json)
localSettings    ← Local private (.claude/settings.local.json)
pluginHook       ← Plugin-registered hooks (lowest priority)
sessionHook      ← Current-session temporary hooks

Enterprise control: When allowManagedHooksOnly = true, all user-configured hooks are ignored — only admin-pushed hooks execute. This is the key capability for enterprise compliance scenarios.

Real Example

Scenario: prevent Claude from modifying production config files

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "FileEdit",
      "hooks": [{
        "type": "command",
        "command": "if [[ '$CLAUDE_TOOL_INPUT_PATH' == *'/prod/'* ]]; then echo 'Blocked: production files are read-only'; exit 2; fi"
      }]
    }]
  }
}

When Claude tries to edit any file under /prod/, this Hook intercepts and returns an error; Claude receives the error and adjusts its plan.