Claude Code Hooks: The Missing Manual
Everyone talks about prompting. Nobody talks about hooks.
Hooks are shell commands that run in response to Claude Code events — before a tool executes, after a tool completes, or when a session starts. They're the programmable layer between you and the agent.
Why hooks matter
The default Claude Code experience is good. But hooks make it yours. They're how you:
- Prevent mistakes before they happen
- Enforce project conventions automatically
- Inject context at the right moment
- Build guardrails that don't slow you down
A simple example
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "echo 'Use python3, not python' && [[ \"$TOOL_INPUT\" != *'python '* ]]"
}
]
}
}
This one line saves me from a mistake I make weekly on macOS where python doesn't exist.
The patterns that matter
After months of daily usage, three hook patterns emerged as genuinely useful:
- Safety nets — Block destructive commands (
rm -rf,git push --force) - Context injection — Feed project state into the session at startup
- Convention enforcement — Ensure output matches your standards
Everything else is over-engineering. Start with these three.
What's next
I'll do a deep dive on each pattern with real examples from my workflow. The key insight: hooks are most powerful when they're invisible. The best hook is one you forget exists because it just works.