Claude Code Hooks
A prompt asks Claude Code to do something, and Claude Code usually complies. Hooks work differently. A hook is a command your computer runs automatically at a chosen moment, every single time. Hooks turn good intentions into guaranteed behavior.
The Doorbell Idea
A doorbell rings whenever someone presses the button, with no decision involved. Hooks follow the same pattern. An event occurs, such as Claude Code finishing a file edit, and your saved command fires immediately.
EVENT HAPPENS YOUR COMMAND RUNS ------------- ----------------- File edited → Format the file Prompt submitted → Log the request Task finished → Send a desktop alert
Why Hooks Matter
Instructions in CLAUDE.md guide Claude Code, and the assistant may miss one occasionally. A hook never forgets because the computer runs it, not the model. Teams use hooks for formatting, safety checks, and notifications.
Common Hook Events
| Event | Fires When | Typical Use |
|---|---|---|
| PreToolUse | Before Claude Code uses a tool | Block risky actions |
| PostToolUse | After a tool finishes | Format code, run linters |
| UserPromptSubmit | When you send a prompt | Add context or log requests |
| Notification | When Claude Code needs your attention | Play a sound |
| Stop | When Claude Code finishes responding | Run final checks |
| SessionStart | When a session begins | Load project details |
Writing a Hook
Hooks live in a settings file. Each hook names an event, a matcher that selects tools, and a command.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "./scripts/format.sh" }
]
}
]
}
}
This hook runs the script format.sh after every edit or file creation. Code stays neatly formatted without a single reminder.
Blocking Dangerous Actions
A PreToolUse hook can stop an action before it happens. Claude Code sends details about the planned action to your script. The script inspects them and returns a blocking result when a rule breaks.
Claude Code plans to edit .env
↓
[ PreToolUse hook ]
↓
Script sees ".env" → returns "blocked"
↓
Claude Code receives the reason and adjusts
Exit code 2 from a script signals a block, and the script's error message travels back to Claude Code as feedback.
Managing Hooks
- Run
/hooksto view the hooks active in a session. - Store project hooks in
.claude/settings.jsonfor team sharing. - Store personal hooks in
.claude/settings.local.jsonor the home settings file. - Test each script by hand before connecting it.
Safety Reminders
Hooks run with your own user permissions. A careless script can delete files or leak data. Read every hook command before saving it, and review hooks copied from outside sources with extra care. Keep scripts short and focused on one job.
Three Starter Hooks
Begin with simple wins. A formatting hook keeps every edited file tidy. A notification hook plays a sound when Claude Code needs input, so you can work in another window. A protection hook blocks edits to secret files. Each hook solves one clear problem and takes minutes to build. Add more only when a real need appears, because every hook adds behavior you must maintain.
Debugging a Hook
A hook that fails quietly confuses everyone. Run the script by hand in the terminal and read its output. Confirm the file has permission to run. Verify that the matcher names the right tools, since a typo means the hook never fires. Print short messages from the script to trace its path. Patient testing solves most hook problems within minutes.
Key Points
- Hooks run your commands automatically at chosen events.
- The computer executes hooks, so they never get skipped.
- PreToolUse blocks actions; PostToolUse reacts after them.
- Settings files store hooks at project or personal level.
- Review hook scripts carefully because they run with your permissions.
