Skip to main content
Hooks

Hooks

Deterministic automation that runs before or after Claude's tool use. Unlike CLAUDE.md (advisory), hooks are enforced every time.

Hooks vs. CLAUDE.md

This is the key distinction:

  • CLAUDE.md — Advisory. Claude reads it and tries to follow it. It may forget or misjudge.
  • Hooks — Deterministic. Your script runs automatically every time, no matter what. Claude cannot skip it.

Use CLAUDE.md for guidelines and preferences. Use hooks for rules that must never be violated.

Hook Types

  • PreToolUse — Runs before Claude executes a tool (e.g., block writes to sensitive files)
  • PostToolUse — Runs after a tool completes (e.g., auto-lint after every file write)
  • Notification — Fires on specific events (e.g., send a Slack message when a task completes)

Configuration

Hooks are defined in .claude/settings.json under the hooks key:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "write_file",
        "command": "npx eslint --fix $CLAUDE_FILE_PATH"
      }
    ]
  }
}

The matcher field specifies which tool triggers the hook. The command is a shell command that runs with environment variables set by Claude Code.

Practical Examples

Auto-Lint After Every Write

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "write_file",
        "command": "npx eslint --fix $CLAUDE_FILE_PATH"
      }
    ]
  }
}

Block Writes to Sensitive Files

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "write_file",
        "command": "echo $CLAUDE_FILE_PATH | grep -qE '(\\.env|secrets|credentials)' && exit 1 || exit 0"
      }
    ]
  }
}

If the pre-hook exits with code 1, Claude Code blocks the tool execution.

Run Tests After Changes

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "write_file",
        "command": "if echo $CLAUDE_FILE_PATH | grep -q 'src/'; then npm test -- --related $CLAUDE_FILE_PATH; fi"
      }
    ]
  }
}

Environment Variables

Claude Code sets these variables when running hooks:

  • $CLAUDE_FILE_PATH — The file being read or written
  • $CLAUDE_TOOL_NAME — The tool being used (e.g., write_file, run_command)
  • $CLAUDE_PROJECT_DIR — The project root directory

Hooks are deterministic control over an agent

The advisory vs. deterministic distinction is a core concept in agent design. Hooks give you guaranteed behavior regardless of what the LLM decides — a pattern used in all production agent systems.

Learn about Tool Use & agent control patterns

Next Steps