Back to Blog

I Made Claude Code Run Custom Scripts on Every Edit — Hooks Tutorial (2026)

By Ayyaz Zafar
Claude Code Hooks tutorial thumbnail — run custom scripts on every edit

Claude Code just edited a file, and a script formatted it automatically. Then Claude tried to touch a secret file, and a guard blocked it. Both ran without me lifting a finger.

This is Hooks. 5 minutes to wire up.

What Are Hooks?

Hooks are scripts you tell Claude Code to run automatically at specific moments — before it edits a file, after it writes one, when it finishes a task.

  • 29 lifecycle events you can hook into
  • 5 handler types: command, http, mcp_tool, prompt, agent
  • Hooks receive JSON via stdin, parse with jq
  • $CLAUDE_PROJECT_DIR is the project-root env var
  • Exit code 2 blocks the action and sends stderr back to Claude as feedback

All hook config lives in .claude/settings.json inside your project. Scoped to that project. Can be committed to git.

Demo 1 — Auto-Format on Every Edit (PostToolUse)

Goal: when Claude finishes editing a file, run prettier on it automatically.

Step 1: Create .claude/hooks/auto-format.sh

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
[ -n "$FILE_PATH" ] && bunx prettier --write "$FILE_PATH"

Make it executable:

chmod +x .claude/hooks/auto-format.sh

Step 2: Create .claude/settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/auto-format.sh"
          }
        ]
      }
    ]
  }
}

What this does: When the event is PostToolUse (after Claude finishes a tool call) AND the tool was either Write or Edit — run prettier on the file Claude just touched.

Trigger it

Open index.html and add a class "dark-mode" to the body element. That's it.

Claude reads the file. Makes the edit. The second it finishes — the entire file is reformatted. Not just the edit. Every messy line is now perfectly indented. You didn't ask for formatting. The hook did it.

The matcher pattern can be anything. Change Edit|Write to Bash, Read, MCP tools, anything Claude calls. One line, same automation runs on whatever Claude does.

Demo 2 — Block Dangerous Edits (PreToolUse)

Goal: stop Claude from ever modifying .env files.

Step 1: Create .claude/hooks/protect-env.sh

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE_PATH" == *.env* ]]; then
  echo "BLOCKED: Cannot edit .env files. Ask the user to update them manually." >&2
  exit 2
fi
exit 0
chmod +x .claude/hooks/protect-env.sh

Step 2: Add a PreToolUse block to .claude/settings.json

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-env.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/auto-format.sh"
          }
        ]
      }
    ]
  }
}

Trigger it

Update .env.local — change DATABASE_URL to postgres://localhost:5432/focus_timer

Claude tries to edit .env.local. The PreToolUse hook fires before the edit happens. The script exits with code 2. Claude sees the stderr message and does not write the file. Visible safety, automatic.

Why Hooks Win

  • Project-scoped: hooks live in .claude/ and travel with your repo
  • Git-committable: your whole team gets the same automations the second they pull
  • Language-agnostic: shell scripts, Node, Python, anything that reads stdin
  • Composable: chain pre-flight checks (security, type-check) with post-flight actions (format, notify)

The 3 Pillars of Claude Code Customization

Hooks is the third of three customization pillars:

  • CLAUDE.md — rules for Claude (what your stack is, what's off-limits) — deep-dive
  • Skills — capabilities for Claude (slide decks, spreadsheets, custom workflows) — deep-dive
  • Hooks — automation around Claude (this video) — auto-format, security gates

If you want the decision framework for when to use which → Claude Code's 3 Customization Pillars Explained.

Resources

Final Word

Hooks turn Claude Code from an assistant into a self-correcting agent. The auto-formatter and the env-guard above cost you 5 minutes to set up and save you hours of cleanup over a project's life.

Drop the JSON in your project root. Watch Claude get smarter, safer, and more disciplined — automatically.

Subscribe to AyyazTech on YouTube — I cover every AI coding tool worth your time so you don't waste yours.

Share this article