Claude & Claude Hooks: The AI Development Superpower You Are Not Using
A deep dive into Claude Code, the hooks system, and how to build autonomous AI workflows that run your dev pipeline while you sleep.
Claude Isn't Just a Chatbot Anymore
Most developers still use Claude like a smarter Stack Overflow — paste a question, get an answer, copy some code. This is fine. It's also leaving 90% of Claude's power untouched.
With Claude Code and the hooks system, you can wire Claude into your entire development lifecycle. We're talking about an AI that watches your git commits, runs before your tests, auto-formats code, enforces security policies, and stops you from pushing secrets to production — all without you typing a single prompt.
Let's go deep.
Claude Code: The Terminal-First AI Agent
Claude Code (claude CLI) is Anthropic's agentic coding tool. Unlike browser-based Claude, it runs in your terminal with direct access to your:
- File system (reads and writes files)
- Shell (runs commands, tests, builds)
- Git (branches, diffs, commits)
- Editor (integrates with VS Code and Cursor)
Installation
npm install -g @anthropic-ai/claude-code
claude login
Basic Usage
# Start Claude in your project
cd my-project
claude
# Ask it to do real work
> Implement a rate limiter middleware for Express using Redis.
> Write tests for it. Run them. Fix any failures.
Claude doesn't just write code — it runs it, sees the test output, and fixes failures autonomously. This is the paradigm shift.
What Are Claude Hooks?
Claude Hooks are lifecycle event handlers that run shell commands at specific points during a Claude session. They let you intercept Claude's actions and:
- Validate what Claude is about to do
- Block unsafe actions automatically
- Enhance Claude's output with additional processing
- Notify you or your team about what happened
Think of them as git hooks, but for your AI agent.
Hook Events
| Event | When It Fires | Common Use |
|---|---|---|
PreToolUse |
Before Claude uses any tool | Validate, block risky ops |
PostToolUse |
After Claude uses a tool | Log, format, notify |
Notification |
When Claude sends a notification | Custom alerts |
Stop |
When Claude finishes | Run post-processing, tests |
SubagentStop |
When a subagent completes | Aggregate results |
Setting Up Claude Hooks
Hooks are configured in ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/validate-bash.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/lint-on-write.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/run-tests.sh"
}
]
}
]
}
}
Real-World Hook Examples
1. Block Production Database Writes
Never accidentally let Claude modify production data:
#!/bin/bash
# ~/.claude/hooks/validate-bash.sh
# Read the command Claude wants to run from STDIN
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# Block any command targeting production
if echo "$COMMAND" | grep -qiE "(prod|production|--env=prod)"; then
echo '{"decision": "block", "reason": "Production commands are blocked. Use staging."}'
exit 0
fi
# Allow everything else
echo '{"decision": "allow"}'
2. Auto-Run Linter After Every File Write
#!/bin/bash
# ~/.claude/hooks/lint-on-write.sh
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
# Only lint TypeScript/JavaScript files
if [[ "$FILE" =~ \.(ts|tsx|js|jsx)$ ]]; then
npx eslint "$FILE" --fix 2>&1
# Log results
echo "Linted: $FILE" >> ~/.claude/logs/lint.log
fi
3. Secrets Scanner — Block Leaking API Keys
#!/bin/bash
# ~/.claude/hooks/scan-secrets.sh
INPUT=$(cat)
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // ""')
# Check for common secret patterns
PATTERNS=(
"sk-[a-zA-Z0-9]{48}" # OpenAI key
"AKIA[0-9A-Z]{16}" # AWS access key
"ghp_[a-zA-Z0-9]{36}" # GitHub personal access token
"xoxb-[0-9]+-[a-zA-Z0-9]+" # Slack bot token
)
for PATTERN in "${PATTERNS[@]}"; do
if echo "$CONTENT" | grep -qE "$PATTERN"; then
echo '{"decision": "block", "reason": "Potential secret detected. Use environment variables instead."}'
exit 0
fi
done
echo '{"decision": "allow"}'
4. Notify on Completion (Desktop Notification)
#!/bin/bash
# ~/.claude/hooks/notify-done.sh
# macOS notification when Claude finishes a long task
osascript -e 'display notification "Claude finished the task!" with title "Claude Code" sound name "Glass"'
# Also log session summary
echo "[$(date)] Session completed" >> ~/.claude/logs/sessions.log
The Hook Decision Protocol
Your hook script communicates with Claude via stdout JSON:
// Allow the action
{"decision": "allow"}
// Block with a reason (Claude sees this and tries again differently)
{"decision": "block", "reason": "Explain why this was blocked"}
// Allow but add context (Claude can read this)
{
"decision": "allow",
"context": "Note: This file has 200 tests, make sure they still pass"
}
This is powerful: when you block an action, Claude receives your reason and can course-correct. You're not just stopping bad behavior — you're teaching Claude your guardrails.
The CLAUDE.md File: Teaching Claude Your Codebase
One of the highest-leverage things you can do is create a CLAUDE.md in your repo root. Claude reads this file at the start of every session.
# CLAUDE.md
## Project: Acme Payment Platform
### Stack
- SvelteKit (frontend)
- Node.js + Express (API)
- PostgreSQL (database)
- Redis (caching + rate limiting)
### Conventions
- All API routes live in /src/routes/api/
- Database queries go through /src/lib/server/db.ts
- NEVER write raw SQL; use the query builder in db.ts
- All user-facing errors must be logged to Sentry
### Testing
- Run tests: npm test
- Integration tests require local PostgreSQL running
- Always run `npm run type-check` before committing
### Security Rules
- NEVER log user PII (passwords, SSNs, credit cards)
- All financial transactions must be idempotent
- Use parameterized queries — no string interpolation in SQL
### When You're Stuck
1. Check the existing patterns in /src/lib/
2. Read the ADRs in /docs/decisions/
3. Ask me before making architectural changes
This single file can replace dozens of clarifying questions per session.
Multi-Agent Workflows with Claude
Claude Code supports subagents — you can spawn parallel Claude instances to work on different parts of a problem simultaneously.
# In a Claude session prompt:
> I need to build a user authentication system.
> Spawn 3 subagents:
> 1. Write the database schema and migrations
> 2. Write the API endpoints and validation
> 3. Write the frontend components and forms
> Coordinate their output and merge when all complete.
This is the Ralph Wiggum pattern at scale (more on that in the next post).
Student Project: Build a Personal Dev Assistant
Here's a weekend project that will level up your understanding:
Goal: Build a Claude-powered CLI that helps you manage your projects.
# What it should do:
claude-assistant new-feature "user login with Google OAuth"
# → Creates a spec, writes the code, runs tests, opens a PR
claude-assistant review
# → Reviews your latest uncommitted changes, flags issues
claude-assistant daily-standup
# → Reads your git history from yesterday, writes a standup update
Tech stack:
- Node.js or Python CLI
@anthropic-ai/sdkfor Claude APIsimple-gitfor git operations- Claude hooks for safety rails
This project alone will make you 10x more hireable — you'll have built a real agentic AI tool and can demo it in interviews.
Advanced: Claude in CI/CD
Add Claude to your GitHub Actions pipeline:
# .github/workflows/ai-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
ai-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get PR diff
run: git diff origin/main...HEAD > /tmp/pr.diff
- name: Claude Security Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
npx @anthropic-ai/claude-code \
--print \
"Review this diff for security vulnerabilities, race conditions,
and breaking API changes. Be specific. $(cat /tmp/pr.diff)" \
> review.txt
- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const review = require('fs').readFileSync('review.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🤖 AI Security Review\n\n${review}`
});
Now every PR gets an automatic AI security review before a human looks at it.
The Mental Model: Claude as a Junior Dev on Autopilot
The best way to think about Claude Code + Hooks:
Hooks are your company's engineering standards, automated as code.
When you join a real company, there are rules: don't push to main, always write tests, no secrets in code, follow the naming conventions. Hooks are how you enforce those rules for your AI developer — turning your judgment into repeatable, automated guardrails.
Combined with a great CLAUDE.md, you're essentially onboarding Claude to your team the same way you'd onboard a junior engineer. Except this junior engineer works 24/7, never complains, and can ship a feature from scratch in 20 minutes.