Hooks & Automation
Hooks let you set up automatic reactions — shell commands that run before or after Claude does something. Think of them as tripwires that trigger helpful actions without you lifting a finger.
What Are Hooks?
You’ve set up memory (CLAUDE.md), and you’ve created skills (SKILL.md). Now it’s time to add automation — things that happen without you asking.
Hooks are shell commands that run automatically at specific moments during a Claude Code session. They’re like setting up dominoes: when one thing happens, another thing happens automatically.
Here’s the analogy: imagine you have a doorbell camera. When someone approaches your door (the trigger), it automatically starts recording (the action). You don’t have to press a button — it just happens. Hooks work the same way.
Hooks are automatic reactions. You define a trigger (like “before Claude edits a file”) and an action (like “run the linter”). Claude Code executes the action at exactly the right moment. You configure hooks in your settings.json file, not in CLAUDE.md.
The Four Hook Types
There are four moments when hooks can fire:
1. PreToolUse — Runs before Claude uses a tool (like editing a file or running a command). Perfect for blocking dangerous operations.
2. PostToolUse — Runs after Claude uses a tool. Great for automatic cleanup, like running a code formatter after every file edit.
3. SessionStart — Runs when you start a new Claude Code session. Useful for setting up environment variables or checking system status.
4. Notification — Runs when Claude sends a notification (like when a long task finishes). You can use this to trigger desktop alerts or sounds.
Think of it like a timeline:
Where Hooks Live
Hooks are configured in your settings.json file. You can edit this file directly, or use the /hooks command inside Claude Code to manage them through a menu.
The settings file lives at:
~/.claude/settings.json
Here’s what a hook looks like in that file:
This hook says: “Every time Claude finishes editing a file, automatically run the Prettier code formatter on that file.” You never have to remember to format your code — it just happens.
The matcher field filters which tool triggers the hook. "Edit" means only file edits. "Bash" means only terminal commands. Leave it empty to match everything.
Blocking Dangerous Commands
One of the most powerful uses of PreToolUse hooks is blocking dangerous operations before they happen. Think of it as a safety net.
For example, you might want to prevent Claude from ever running rm -rf / (which deletes everything) or git push --force (which can destroy your team’s work):
When a PreToolUse hook exits with code 1 (an error), Claude’s action is blocked. It won’t run the dangerous command. Exit code 0 means “go ahead.”
PreToolUse hooks are guardrails. They inspect what Claude is about to do and can block it. This is especially useful in team settings where you want to prevent accidental damage, even if someone writes a careless prompt.
Auto-Lint After Every Edit
Here’s a practical PostToolUse hook that runs ESLint (a code quality checker) after Claude edits any JavaScript file:
Every time Claude edits a .js file, ESLint automatically checks and fixes it. No extra steps, no forgetting.
You can chain multiple PostToolUse hooks. For example: format with Prettier, then lint with ESLint, then run the relevant test file — all automatically after every edit.
SessionStart: Your Morning Briefing
SessionStart hooks run once when you open Claude Code. They’re perfect for setting up your environment or giving yourself a status report.
Here’s a hook that loads environment variables and checks your Git status:
You can get creative with this. Some people set up a “morning briefing” that shows:
- How many unread Slack messages they have
- What’s on their calendar today
- Which pull requests need review
- The status of their last deployment
All of that shows up automatically when they type claude.
Set up a PostToolUse hook in my settings.json that runs Prettier on any file after Claude edits it. Also add a PreToolUse hook that blocks any git push --force command.
Recurring Tasks with /loop
Sometimes you want Claude to repeat a task on a schedule — like checking a deployment every 5 minutes or monitoring a log file for errors.
The /loop command does exactly this:
> /loop 5m check the deployment status and alert me if anything is failing
This tells Claude to run that prompt every 5 minutes. It keeps going until you stop it. You can use any time interval: 30s (30 seconds), 5m (5 minutes), 1h (1 hour).
/loop 5m check the deployment at https://my-app.vercel.app and tell me if it returns any errors
/loop 2m read the last 20 lines of server.log and alert me if there are any ERROR or WARN entries
Scheduled Tasks
Beyond /loop (which runs during your session), you can set up tasks that run even when you’re not at your computer:
- Desktop scheduled tasks — Use your operating system’s built-in scheduler (cron on Mac/Linux, Task Scheduler on Windows) to run
claude -p "your prompt"at specific times - GitHub Actions — Run Claude Code in the cloud on a schedule, like checking for security vulnerabilities every night
- Cloud functions — Trigger Claude from AWS Lambda, Google Cloud Functions, or similar services
Create a GitHub Action that runs every night at midnight and uses Claude Code to scan the codebase for common security vulnerabilities. Have it open an issue if it finds anything.
Hooks run shell commands with real permissions on your system. Be careful with PreToolUse hooks that might accidentally block legitimate operations. Test your hooks with simple echo commands first before adding real logic.
Try It Yourself
Set Up Your First Hook
- Open Claude Code in any project
- Ask Claude: “Show me my current settings.json file for Claude Code. If it doesn’t exist, create one.”
- Ask Claude: “Add a PostToolUse hook that prints ‘File was modified!’ to the terminal every time you edit a file.”
- Test it by asking Claude to create a small text file — you should see the message appear automatically
- Bonus: Modify the hook to only trigger for
.jsor.pyfiles (ask Claude to help you with the matcher)