DEV Community

Zac
Zac

Posted on

5 Claude Code hooks I use on every project

Claude Code hooks let you run scripts at key points in the agent's lifecycle: before tool use, after tool use, on stop, on error. Here are the 5 I reach for on every project.

What hooks actually do

Hooks are shell scripts (or any executable) that Claude Code calls at lifecycle events. They can:

  • Block an action (non-zero exit code stops the tool call)
  • Log what happened
  • Run side effects (format code, send a notification)
  • Inject context back into the agent

They live in .claude/settings.json under the hooks key.

Hook 1: Read before Edit enforcer

{
  "PreToolUse": [{
    "matcher": "Edit|Write",
    "hooks": [{"type": "command", "command": "bash .claude/hooks/read-before-edit.sh"}]
  }]
}
Enter fullscreen mode Exit fullscreen mode
#!/bin/bash
# read-before-edit.sh
# Warn if Edit is called without a recent Read of the same file
echo "[hook] Make sure you've read this file before editing"
exit 0  # advisory only — doesn't block
Enter fullscreen mode Exit fullscreen mode

Simple advisory hook. Reminds the agent to check current state. You can make it blocking for stricter enforcement.

Hook 2: Git safety net

#!/bin/bash
# pre-bash-git.sh — runs before any Bash tool call with git in it
# Block git add -A and git add .
if echo "$CLAUDE_TOOL_INPUT" | grep -qE 'git add (-A|\.)'; then
  echo "ERROR: Use specific file paths with git add, not -A or ."
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

This one blocks. git add -A has caused real problems for me — accidentally staging .env files, large binaries, debug files. The hook catches it before it happens.

Hook 3: Rate limit guard

#!/bin/bash
# rate-limit-check.sh
# Track last call time per API, enforce minimum delay
API=$(echo "$CLAUDE_TOOL_INPUT" | grep -oP '(?<=curl -s )https://[^/]+' | head -1)
if [ -n "$API" ]; then
  LAST_CALL_FILE="/tmp/last-api-call-$(echo $API | md5sum | cut -c1-8)"
  if [ -f "$LAST_CALL_FILE" ]; then
    LAST=$(cat "$LAST_CALL_FILE")
    NOW=$(date +%s)
    DIFF=$((NOW - LAST))
    if [ $DIFF -lt 1 ]; then
      sleep $((1 - DIFF))
    fi
  fi
  date +%s > "$LAST_CALL_FILE"
fi
Enter fullscreen mode Exit fullscreen mode

Rudimentary but effective for preventing rapid-fire API calls. Extend with per-API thresholds.

Hook 4: Context checkpoint reminder

#!/bin/bash
# context-checkpoint.sh — runs on Stop
# Remind agent to update task state before stopping
echo "Reminder: Update tasks/current-task.md with last_checkpoint before stopping"
exit 0
Enter fullscreen mode Exit fullscreen mode

Simple reminder on the Stop event. Doesn't enforce anything — just puts the reminder where the agent will see it.

Hook 5: Secret scanner

#!/bin/bash
# secret-scan.sh — runs before Write
# Block writing files that look like they contain secrets
CONTENT="$CLAUDE_TOOL_INPUT"
if echo "$CONTENT" | grep -qiE '(api_key|secret|password|token)\s*=\s*["\x27][^"\x27]{8,}'; then
  echo "ERROR: File content looks like it contains credentials. Use environment variables."
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Catches the most obvious cases: hardcoded API keys, passwords, tokens. Not foolproof, but stops the easy mistakes.

Setting them up

In .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {"matcher": "Bash", "hooks": [{"type": "command", "command": ".claude/hooks/pre-bash-git.sh"}]},
      {"matcher": "Write", "hooks": [{"type": "command", "command": ".claude/hooks/secret-scan.sh"}]}
    ],
    "Stop": [
      {"hooks": [{"type": "command", "command": ".claude/hooks/context-checkpoint.sh"}]}
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

All 5 hooks + documentation in the Agent Harness ($29), along with the CLAUDE.md templates and context management system.


Repo with templates: github.com/seankim-android/claude-md-templates

Top comments (0)