CLAUDE LABJP
DEFAULT — Claude Sonnet 5 is now the default model for Free and Pro users worldwide. It's the most agentic Sonnet yet and performs close to Opus 4.8 on many tasksPRICE — Sonnet 5 launch pricing ($2 in / $10 out per million tokens) runs through August 31, then returns to $3 / $15. Worth measuring your real token costs nowFASTEND — Fast mode for Claude Opus 4.7 is removed on July 24 — three days left. If you set speed: 'fast', move those calls to fast mode on Opus 4.8MEMORY — Claude's memory now works as a set of individual, categorized entries that Claude reads and updates mid-conversation, so it's easier to see what's storedHIPAA — Enterprise and API organizations can now configure HIPAA support themselves: BAA review, guide download, and one-step enablementADMIN — The Admin API can list members, change roles, remove people, and manage groups — helpful for organizations with frequent membership changesDEFAULT — Claude Sonnet 5 is now the default model for Free and Pro users worldwide. It's the most agentic Sonnet yet and performs close to Opus 4.8 on many tasksPRICE — Sonnet 5 launch pricing ($2 in / $10 out per million tokens) runs through August 31, then returns to $3 / $15. Worth measuring your real token costs nowFASTEND — Fast mode for Claude Opus 4.7 is removed on July 24 — three days left. If you set speed: 'fast', move those calls to fast mode on Opus 4.8MEMORY — Claude's memory now works as a set of individual, categorized entries that Claude reads and updates mid-conversation, so it's easier to see what's storedHIPAA — Enterprise and API organizations can now configure HIPAA support themselves: BAA review, guide download, and one-step enablementADMIN — The Admin API can list members, change roles, remove people, and manage groups — helpful for organizations with frequent membership changes
Articles/Claude Code
Claude Code/2026-04-02Intermediate

Claude Code Hooks: Building Automated Workflows in Practice

A systematic guide to Claude Code Hooks. Learn how to use PreToolUse, PostToolUse, Stop, and Notification hooks to automate code quality checks, logging, notifications, and more.

Claude Code201Hooks6Automation39Workflow8Developer Productivity2

Claude Code Hooks give you a precise way to weave your intentions into AI-assisted coding sessions. By injecting custom scripts before and after tool calls, you can automate repetitive tasks like code quality checks, activity logging, and external notifications — turning a good development flow into a great one.

What Are Claude Code Hooks?

Claude Code Hooks let you run shell commands or scripts at specific moments during a Claude Code session — before or after any tool is executed. Instead of the traditional loop of "AI works → human reviews → move on," Hooks enable a more refined cycle: "AI works → automated verification/notification → move on."

Here are a few scenarios where Hooks really shine:

Automatic code quality checks: Run a linter or formatter every time Claude edits a file and catch issues immediately.

Change history logging: Record which files were touched and when, making debugging and audits far easier.

External service notifications: Integrate with Slack or email to automatically alert team members when key tasks are completed.

Security guardrails: Detect access to sensitive files and block the operation if needed.

The Hooks Configuration File

Hooks are configured in ~/.claude/settings.json (global) or .claude/settings.json at the project root (project-specific). Here's a basic example:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo '🔧 Pre-Bash: $CLAUDE_TOOL_INPUT' >> /tmp/claude-hooks.log"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && npx eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

Each entry specifies a matcher (the tool name to target) and a command to run. The configuration is straightforward JSON — easy to version-control and share with your team.

The Four Hook Types

Claude Code supports four distinct timing points for running scripts. Understanding each one is the foundation of effective Hooks usage.

PreToolUse: Runs Before a Tool Executes

PreToolUse fires immediately before Claude calls a tool. Its standout feature is the ability to block the tool from running based on your script's exit code: exit 0 to allow the tool to proceed, or exit non-zero to stop it.

This makes PreToolUse ideal for access control and catching dangerous operations before they happen.

#!/bin/bash
# Example: Block direct production deployments
TOOL_INPUT="$CLAUDE_TOOL_INPUT"
if echo "$TOOL_INPUT" | grep -q "production" && echo "$TOOL_INPUT" | grep -q "deploy"; then
  echo "⚠️  Production deployments require a review step."
  exit 1  # Block the tool call
fi
exit 0  # Allow normally

PostToolUse: Runs After a Tool Completes

PostToolUse fires right after a tool finishes. Since you have access to the tool's output, it's perfect for post-processing and verification.

Auto-formatting after edits is one of the most popular uses:

#!/bin/bash
# Example: Auto-run Prettier after every Edit
FILE="$CLAUDE_TOOL_INPUT_FILE_PATH"
if [[ "$FILE" =~ \.(js|ts|jsx|tsx|json|css)$ ]]; then
  npx prettier --write "$FILE" 2>/dev/null
  echo "✅ Formatted: $FILE"
fi

Stop: Fires When Claude Code Finishes a Session

The Stop hook runs exactly once when Claude Code ends a session. It's a natural fit for completion notifications and generating final summaries.

#!/bin/bash
# Example: Send a Slack notification on session end
SESSION_ID="$CLAUDE_SESSION_ID"
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H 'Content-type: application/json' \
  -d "{\"text\":\"✅ Claude Code session finished (ID: ${SESSION_ID})\"}"

Notification: Fires on Notification Events

The Notification hook runs when Claude Code emits a notification — for example, when it pauses waiting for user input. This is useful for relaying mid-session status updates to external systems during long-running tasks.

Environment Variables Available in Hooks

When a Hook script runs, Claude Code automatically sets several environment variables so your script has the context it needs:

VariableDescription
CLAUDE_TOOL_NAMEName of the tool being called (e.g., Bash, Edit)
CLAUDE_TOOL_INPUTRaw input passed to the tool (JSON)
CLAUDE_TOOL_INPUT_FILE_PATHFile path when the Edit tool is used
CLAUDE_PROJECT_DIRRoot directory of the current project
CLAUDE_SESSION_IDUnique identifier for the session
CLAUDE_HOOK_EVENT_NAMEName of the hook event that fired

Combining these variables lets you write scripts that adapt to context — applying different logic depending on the tool, file type, or project.

Controlling Scope with the matcher Field

The matcher field determines which tools trigger a given hook. You can use exact tool names or regular expressions.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/auto-lint.sh"
          }
        ]
      }
    ]
  }
}

The example above triggers the lint script after both Edit and Write tool calls. Setting matcher to an empty string will match all tools.

Practical Recipes

Recipe 1: Automatic TypeScript Type Checking

#!/bin/bash
# auto-typecheck.sh
FILE="$CLAUDE_TOOL_INPUT_FILE_PATH"
if [[ "$FILE" =~ \.tsx?$ ]]; then
  cd "$CLAUDE_PROJECT_DIR"
  npx tsc --noEmit --skipLibCheck 2>&1 | head -20
fi
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [{ "type": "command", "command": "/path/to/auto-typecheck.sh" }]
      }
    ]
  }
}

Recipe 2: Secret Detection in Code

Prevent accidental commits of API keys, passwords, and other credentials:

#!/bin/bash
# secret-detector.sh
FILE="$CLAUDE_TOOL_INPUT_FILE_PATH"
PATTERNS="(API_KEY|SECRET|PASSWORD|TOKEN|PRIVATE_KEY)\s*=\s*['\"][^'\"]{8,}"
 
if [ -f "$FILE" ] && grep -qE "$PATTERNS" "$FILE"; then
  echo "🚨 Potential secret detected in: $FILE"
  grep -nE "$PATTERNS" "$FILE" | head -5
  exit 1  # Block the write
fi
exit 0

Recipe 3: Automatic Activity Logging

#!/bin/bash
# activity-logger.sh
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
TOOL="$CLAUDE_TOOL_NAME"
FILE="${CLAUDE_TOOL_INPUT_FILE_PATH:-N/A}"
LOG_FILE="$HOME/.claude/activity.log"
 
echo "[$TIMESTAMP] $TOOL$FILE" >> "$LOG_FILE"

Set this as a PostToolUse hook with an empty matcher, and every Claude Code action gets recorded to ~/.claude/activity.log automatically.

Recipe 4: Automatic Test Runs

#!/bin/bash
# auto-test.sh
FILE="$CLAUDE_TOOL_INPUT_FILE_PATH"
PROJECT_DIR="$CLAUDE_PROJECT_DIR"
 
if [[ "$FILE" =~ \.(test|spec)\.(js|ts)$ ]]; then
  cd "$PROJECT_DIR"
  npx jest "$FILE" --passWithNoTests 2>&1 | tail -10
fi

Tips for Safe and Reliable Hooks

Because Hooks execute shell commands directly, a misconfiguration can have unintended consequences. Keep these practices in mind:

Handle errors gracefully: Avoid set -e indiscriminately — use || true when you intentionally want a command to fail without stopping the Hook.

Set execute permissions: Don't forget chmod +x your-script.sh. If a Hook silently does nothing, missing permissions are often the culprit.

Use debug logging: While developing your scripts, write debug output to a log file (echo "debug info" >> /tmp/hooks-debug.log). It makes diagnosing issues much faster.

Design for idempotency: Hooks may run multiple times. Make sure running the same Hook twice in a row won't cause problems — especially for scripts that create files or modify state.

Closing Thoughts: Build a Smarter Development Environment

Once configured, Claude Code Hooks quietly do their job every session — enforcing quality, recording history, and keeping you in the loop without any extra effort. Start small with a simple activity log, then layer in auto-formatting and security checks as you go.

The goal is a virtuous cycle: "AI works → quality is automatically ensured → you focus on what matters most." With the right Hooks in place, that cycle becomes your everyday reality.


🌟 Go Deeper with Premium Content

Claude Lab offers premium articles that take Hooks even further:

  • Combining MCP servers with Hooks — building advanced workflows that talk to external APIs
  • Team-wide Hooks standardization — best practices for sharing Hook configs across an organization
  • Claude Code + CI/CD integration — practical recipes for connecting Claude Code to GitHub Actions

Premium membership (from ¥280/month) gives you full access to all of these deep-dive articles. If you want to get the most out of Claude AI in your daily development work, we'd love to have you on board.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-04-27
Claude Code Hooks: A Complete Field Guide to All 8 Hook Types and How to Pick the Right One
Claude Code hooks are powerful, but most people give up before figuring out which event does what. Here's the field guide I wish I had when I started — six months of running hooks in production, distilled.
Claude Code2026-06-14
A SubagentStop Hook That Grades Subagent Output and Sends It Back to Be Redone
When a Claude Code subagent occasionally returns rule-breaking work, a SubagentStop hook can grade it automatically and ask for a redo. Here is a working setup with code and field notes.
Claude Code2026-05-05
Building a Zero-Touch Code Review Environment with Claude Code Hooks
Learn how to use Claude Code's hook system to automatically review code on every tool execution. Covers PostToolUse, Stop hooks, and the pitfalls to avoid when implementing PreToolUse blockers.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →