Mastering Claude Code Hooks: Auto-Format, Auto-Test, and More
Mastering Claude Code Hooks: Auto-Format, Auto-Test, and More. A practical guide with code examples.
What Are Hooks?
Claude Code hooks let you automatically run custom commands before or after specific actions. You can set up auto-formatting after file saves, auto-run tests after code changes, and much more.
Hooks are defined in .claude/settings.json and execute shell commands when Claude Code performs certain operations.
Hook Types
Claude Code supports hooks at the following event points:
| Hook Event | When It Fires |
|---|---|
PreToolUse | Before a tool is executed |
PostToolUse | After a tool is executed |
Notification | When a notification is sent |
Stop | When Claude Code finishes responding |
Basic Configuration
Hooks are defined in the hooks field of .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\""
}
]
}
}
Configuration Structure
- matcher: A regex pattern that matches the tool name triggering the hook
- command: The shell command to execute
Use Case 1: Auto-Formatting
Automatically run Prettier after any file edit:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\""
}
]
}
}
With this setup, every time Claude Code creates or edits a file, Prettier formats it automatically. Your team’s coding style stays consistent without any manual effort.
Use Case 2: Auto-Linting
Here’s how to integrate ESLint auto-fix:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}
]
}
}
The || true suffix prevents lint errors from causing the hook to fail, allowing Claude Code to continue processing.
Use Case 3: Auto-Testing on Change
Automatically run related tests after file edits and feed back the results:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx vitest related \"$CLAUDE_FILE_PATH\" --run 2>&1 | tail -20"
}
]
}
}
Vitest’s related option runs only the tests relevant to the changed file, giving you much faster feedback than a full test suite.
Use Case 4: Auto Type-Checking
Run TypeScript type checking after file changes:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx tsc --noEmit 2>&1 | head -30"
}
]
}
}
Use Case 5: Blocking Dangerous Commands
A PreToolUse hook that prevents execution of risky commands:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|drop table|git push.*force'; then echo 'BLOCKED: Dangerous command detected' >&2; exit 1; fi"
}
]
}
}
When the hook exits with code 1, Claude Code skips the tool execution entirely.
Use Case 6: Completion Notifications
Send a notification when Claude Code finishes a task:
{
"hooks": {
"Stop": [
{
"matcher": "",
"command": "notify-send 'Claude Code' 'Task completed' 2>/dev/null; echo 'Done'"
}
]
}
}
On macOS, you can use:
{
"hooks": {
"Stop": [
{
"matcher": "",
"command": "osascript -e 'display notification \"Task completed\" with title \"Claude Code\"'"
}
]
}
}
Combining Multiple Hooks
In real projects, combining several hooks is the most effective approach:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf /'; then exit 1; fi"
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
},
{
"matcher": "Write|Edit",
"command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}
],
"Stop": [
{
"matcher": "",
"command": "echo '✓ Task completed'"
}
]
}
}
Tips for Writing Hooks
1. Keep Execution Time Short
Hooks run synchronously, so heavy operations will slow down Claude Code’s responses. Use options like related to narrow test scope, and head or tail to trim output.
2. Handle Errors Gracefully
A hook that exits with an error can disrupt Claude Code’s workflow. Use || true and 2>/dev/null to keep things safe.
3. Use Environment Variables
Take advantage of the environment variables available in hooks. $CLAUDE_FILE_PATH gives you the path of the file being operated on.
Conclusion
Hooks let you heavily customize Claude Code’s workflow. The combination of auto-formatting and auto-testing is especially powerful for maintaining code quality. Start with Prettier auto-formatting and build from there.
Free PDF: Claude Code Cheatsheet in 5 Minutes
Just enter your email and we'll send you the single-page A4 cheatsheet right away.
We handle your data with care and never send spam.
Level up your Claude Code workflow
50 battle-tested prompt templates you can copy-paste into Claude Code right now.
About the Author
Masa
Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.
Related Posts
Safe Agent Harness Design for Claude Code and Codex: Permissions, Checks, and Rollback
Build a practical agent harness for Claude Code and Codex with policy, planning, verification, and recovery layers.
10 Powerful Subagent Patterns for Claude Code
Master Claude Code's subagent feature with 10 practical patterns. Learn how to use parallel processing, specialization, and context isolation to double your development speed.
Getting Started with Claude Code Agent SDK — Build Autonomous Agents Fast
Learn how to build autonomous AI agents with Claude Code Agent SDK. Covers setup, tool definitions, and multi-step execution with practical code examples.
Related Products
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.