DEV Community

brian austin
brian austin

Posted on

Claude Code hooks: auto-lint, auto-test, and self-healing loops

Claude Code hooks: auto-lint, auto-test, and self-healing loops

One of Claude Code's most underused features is hooks — shell commands that run automatically before or after Claude takes actions.

Set them up once. Get clean, tested code every session.

What are Claude Code hooks?

Hooks are shell commands defined in your settings.json that Claude Code runs at specific lifecycle events:

  • PreToolUse — before Claude reads/writes a file
  • PostToolUse — after Claude writes a file
  • Stop — when Claude finishes a response

This means you can attach lint, format, and test commands to fire automatically.

Setup: where hooks live

Global hooks (all projects):

~/.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

Project hooks (this repo only):

.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

Example 1: Auto-format after every file write

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write $CLAUDE_TOOL_INPUT_PATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Every file Claude writes gets formatted. No more manual prettier runs.

Example 2: Auto-lint and fix on save

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "eslint --fix $CLAUDE_TOOL_INPUT_PATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Claude writes a file → ESLint fixes it immediately → Claude's next read sees the clean version.

Example 3: Run tests automatically after edits

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "cd $(git rev-parse --show-toplevel) && npm test -- --testPathPattern=$(basename $CLAUDE_TOOL_INPUT_PATH) 2>&1 | tail -20"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Claude edits a file → tests for that file run → output appears in Claude's context → Claude sees failures and fixes them automatically.

This is the self-healing loop.

Example 4: The full auto-pilot stack

Combine all three:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write $CLAUDE_TOOL_INPUT_PATH 2>/dev/null || true && eslint --fix $CLAUDE_TOOL_INPUT_PATH 2>/dev/null || true"
          },
          {
            "type": "command",
            "command": "cd $(git rev-parse --show-toplevel) && npm test -- --testPathPattern=$(basename $CLAUDE_TOOL_INPUT_PATH) 2>&1 | tail -20"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow:

  1. Claude writes a file
  2. Prettier formats it
  3. ESLint fixes style issues
  4. Tests run
  5. Output feeds back to Claude
  6. Claude fixes any failures
  7. Repeat until green

You watch. Code gets better.

Available hook variables

Variable Value
$CLAUDE_TOOL_INPUT_PATH The file being read/written
$CLAUDE_TOOL_NAME The tool being used (Write, Read, Bash, etc.)
$CLAUDE_SESSION_ID Current session ID

Stop hook: commit when done

Run a git commit automatically when Claude finishes:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cd $(git rev-parse --show-toplevel) && git add -A && git diff --cached --quiet || git commit -m 'Claude Code session: $(date +%Y-%m-%d-%H%M)'"
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Every completed Claude session = an automatic commit. Clean history.

Rate limits interrupt the loop

The hook loop breaks when Claude hits its rate limit mid-session.

Fix: point Claude at a proxy that removes rate limits.

export ANTHROPIC_BASE_URL=https://simplylouie.com/api/proxy
Enter fullscreen mode Exit fullscreen mode

SimplyLouie routes your Claude Code traffic for ✌️$2/month (vs $20/month for Claude Pro). Rate limit interruptions disappear. Your hook loops keep running.

7-day free trial. Card required, not charged for 7 days.

Summary

Hook type When it fires Best use
PostToolUse: Write After every file write Format, lint, test
PreToolUse: Write Before every write Validate, backup
Stop Session ends Commit, notify, summarize

Hooks turn Claude Code from a chat assistant into a fully automated dev pipeline. Set them up once.


Running Claude Code? Try the self-healing test loop above. Hit rate limits before it completes? SimplyLouie fixes that for $2/month.

Top comments (0)