Claude Code git hooks: automate code review before every commit
One of the most underused Claude Code patterns I've found: combining Claude with git hooks to get automated code review on every commit. Here's the exact setup I use.
The problem
You're using Claude Code to write code, but you're still committing slop. Unreviewed edge cases, missing error handling, test coverage gaps — all landing in your repo because you forgot to ask Claude to check.
The solution: pre-commit hook + Claude
Create .git/hooks/pre-commit:
#!/bin/bash
# Get staged changes
DIFF=$(git diff --cached --unified=3)
if [ -z "$DIFF" ]; then
exit 0
fi
# Send to Claude for review
REVIEW=$(curl -s https://api.anthropic.com/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d "{
\"model\": \"claude-opus-4-5\",
\"max_tokens\": 500,
\"messages\": [{
\"role\": \"user\",
\"content\": \"Review this git diff for critical issues only (bugs, security, data loss). If clean, respond with LGTM. If issues found, list them briefly.\\n\\n$DIFF\"
}]
}" | jq -r '.content[0].text' 2>/dev/null)
echo "Claude review: $REVIEW"
# Block commit if serious issues found
if echo "$REVIEW" | grep -qi "CRITICAL\|security\|data loss\|SQL injection\|XSS"; then
echo "❌ Commit blocked by Claude review"
exit 1
fi
echo "✅ Claude review passed"
exit 0
Make it executable:
chmod +x .git/hooks/pre-commit
The cost problem with this approach
Here's the catch: if you're using the Anthropic API directly, each pre-commit review costs ~$0.003-0.015 depending on diff size. At 20+ commits/day, that's $2-9/month just for pre-commit hooks.
I solved this by routing through SimplyLouie — a flat-rate Claude API proxy at $2/month. Same claude-opus-4-5 model, same API format, just set ANTHROPIC_BASE_URL:
export ANTHROPIC_BASE_URL=https://simplylouie.com/api
export ANTHROPIC_API_KEY=your_simplylouie_key
Now the hook uses the proxy and you're not watching the meter.
Better version: reviewdog integration
If you're using reviewdog for CI, you can pipe Claude output:
#!/bin/bash
DIFF=$(git diff --cached)
curl -s https://api.anthropic.com/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d "{
\"model\": \"claude-opus-4-5\",
\"max_tokens\": 1000,
\"messages\": [{
\"role\": \"user\",
\"content\": \"Review this diff. For each issue, output in format: FILE:LINE: SEVERITY: MESSAGE. Severities: ERROR, WARNING, INFO.\\n\\n$DIFF\"
}]
}" | jq -r '.content[0].text' | reviewdog -f=golint -reporter=local
CLAUDE.md config to match
Add to your CLAUDE.md to make Claude Code aware of the hook policy:
## Git Policy
- All commits reviewed by pre-commit hook
- Hook blocks on CRITICAL/security/data loss keywords
- Run `git commit --no-verify` only for WIP commits
- Hook uses claude-opus-4-5 via ANTHROPIC_BASE_URL proxy
What Claude catches that linters miss
Linters catch syntax and style. Claude catches:
- Logic errors: "this loop will exit on the first iteration because of the break"
- Race conditions: "this isn't thread-safe if called concurrently"
- Edge cases: "what happens when the array is empty?"
- API misuse: "this Stripe charge isn't idempotent"
The pre-commit hook won't replace a full code review. But it catches the embarrassing stuff before it lands.
Complete setup script
#!/bin/bash
# setup-claude-hooks.sh
# Install dependencies
npm install -g jq 2>/dev/null || true
# Create hooks directory if needed
mkdir -p .git/hooks
# Write pre-commit hook
cat > .git/hooks/pre-commit << 'HOOK'
#!/bin/bash
DIFF=$(git diff --cached --unified=3)
[ -z "$DIFF" ] && exit 0
REVIEW=$(curl -s https://api.anthropic.com/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d "{\"model\":\"claude-opus-4-5\",\"max_tokens\":500,\"messages\":[{\"role\":\"user\",\"content\":\"Review diff for critical issues. LGTM if clean.\\n\\n$DIFF\"}]}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['content'][0]['text'])" 2>/dev/null)
echo "Claude: $REVIEW"
[[ "$REVIEW" =~ (CRITICAL|security|data.loss) ]] && { echo "❌ Blocked"; exit 1; }
echo "✅ Passed"; exit 0
HOOK
chmod +x .git/hooks/pre-commit
echo "Claude pre-commit hook installed!"
Run it:
chmod +x setup-claude-hooks.sh && ./setup-claude-hooks.sh
The flat-rate angle
This only makes sense cost-wise at flat-rate. Pay-per-token for pre-commit hooks is a bad deal. SimplyLouie at $2/month makes this economically rational — unlimited reviews, same model.
What's your current pre-commit stack? I'm curious what people are catching with automated review that linters miss.
Top comments (0)