Advanced⚙️ Code Required

Hooks

Event-based automation that encodes your judgment into executable code. Your expertise runs before Claude even responds.

What Are Hooks?

Most developers configure Claude session-by-session: "This is a client project, watch for scope creep", "Remember to run lint before commits". Every session starts from zero.

Hooks are scripts that run automatically based on Claude Code events. Instead of repeating instructions, your past decisions apply themselves.

The Core Insight

Hooks let you encode your judgment once and have it apply automatically forever. You're building a context-aware operating system where your expertise runs as executable code.

Without Hooks

  • • You: "This is a client project..."
  • • You: "Watch for scope creep..."
  • • You: "Run lint before commits..."
  • Every. Single. Session.

With Hooks

  • • Hook detects: client project
  • • Hook flags: "can we also..."
  • • Hook blocks: commit without lint
  • Automatically. Every time.

Hook Types

Claude Code supports four hook types, each triggered at different points in the workflow:

🚀

SessionStart

Runs when Claude Code starts in a directory. Perfect for detecting project type and injecting context.

💬

UserPromptSubmit

Runs before Claude processes your message. Ideal for scope creep detection and warning injection.

🔧

PreToolUse

Runs before Claude uses a specific tool. Quality gates before commits, dangerous operation checks.

Stop

Runs when Claude finishes a task. Completion checks, summaries, cleanup tasks.

Example: Scope Creep Detection

Here's a practical example: a UserPromptSubmit hook that flags scope creep phrases before Claude processes your message.

#!/usr/bin/env python3
import json, sys, re

input_data = json.load(sys.stdin)
prompt = input_data.get("prompt", "")

# Scope creep triggers
triggers = ["can we also", "while you're at it", "quick change"]
pattern = "|".join(triggers)

result = {"continue": True}
if re.search(pattern, prompt, re.IGNORECASE):
    result["systemMessage"] = "⚠️ SCOPE ALERT: Is this in scope?"

print(json.dumps(result))
Input

Reads user prompt from stdin as JSON

Output

Returns JSON with continue flag and optional systemMessage

Configuration

Hooks are configured in ~/.claude/settings.json:

{
  "hooks": {
    "SessionStart": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "python3 ~/.claude/hooks/session-start.py",
        "timeout": 5
      }]
    }],
    "UserPromptSubmit": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "python3 ~/.claude/hooks/prompt-submit.py",
        "timeout": 3
      }]
    }]
  }
}

Key fields: matcher controls which directories trigger the hook.timeout prevents slow hooks from blocking Claude.

Getting Started

  1. 1.
    Create the hooks directory
    mkdir -p ~/.claude/hooks
  2. 2.
    Create a hook script

    Python or Bash script that reads stdin (JSON) and prints JSON to stdout.

  3. 3.
    Configure settings.json

    Add your hook to the appropriate event type in ~/.claude/settings.json

  4. 4.
    Test it

    Start a new Claude Code session and trigger the hook to verify it works.

Best Practices

✓ Do's

  • Keep hooks fast (<5 seconds)
  • Always return valid JSON
  • Test scripts standalone first
  • Start simple, add complexity gradually

✗ Don'ts

  • Don't make hooks that take >10 seconds
  • Don't store secrets in hook scripts
  • Don't block everything - be selective
  • Don't over-engineer - solve real problems

⚠️ Security Note

Hooks run with your user permissions. Review hook scripts before using them, just like you would review any executable code you add to your system.

Hooks in Context

Hooks are powerful on their own, but they're part of a bigger system:

CLAUDE.md provides passive context. Skills encode reusable workflows. Hooks automate when those workflows activate. Archetypes bundle everything into coherent work modes.