---
title: "Hooks and Scripts: Automating Your Workflow"
description: "Automate quality gates and routine steps with lifecycle hooks and scripts so they run without you thinking about them"
type: "lesson"
locale: "en"
course: "Claude Code Mastery - Becoming a Power User"
number: "2.3"
canonical: "https://agenticschool.dev/courses/claude-code-mastery/hooks-and-scripts-automating-your-workflow"
datePublished: "2026-06-12"
dateModified: "2026-06-12"
---

# Hooks and Scripts: Automating Your Workflow

- Course: Claude Code Mastery - Becoming a Power User
- Lesson: 2.3
- Duration: 24 min
- Level: einsteiger
- Status: published
- Canonical URL: https://agenticschool.dev/courses/claude-code-mastery/hooks-and-scripts-automating-your-workflow
- Locale: en

> Automate quality gates and routine steps with lifecycle hooks and scripts so they run without you thinking about them

## Summary

Hooks let you run your own scripts automatically at key moments in the agent lifecycle - before a tool runs, after a file is edited, when the agent finishes, before a push. This is how you enforce quality gates like tests, linting and type checks so nothing broken ever leaves your machine, without relying on memory or discipline. This lesson shows the real settings.json that wires it up.

## What you learn

- What lifecycle hooks are and the events you can attach scripts to
- Building a pre-push quality gate that runs lint, typecheck and tests automatically
- The difference between agent hooks and Git hooks, and letting automation enforce standards

## Summary

Hooks run scripts automatically at defined moments, so the right thing happens whether or not anyone remembers to do it. Claude Code has its own lifecycle hooks that fire around the agent's actions, and Git has hooks that fire around commits and pushes. The classic, highest-value use is a quality gate that runs your linter, type checker and tests before code can leave your machine, so a regression physically cannot reach your repo or production. This lesson wires up both with real, runnable config.

## What you will learn

You will learn what a hook is, the lifecycle events Claude Code lets you hook into, how to configure a hook in settings.json, how that differs from a Git pre-push hook, and how to assemble a quality gate that protects your project automatically. You will leave with a working settings.json snippet and a working Git hook you can adapt.

## Prerequisites

A version-controlled project from Course 1 and at least one check you can run from the command line, such as a lint or test script. The CLAUDE.md from lesson one helps too, since your rules file should already name the quality gate command that your hooks will enforce. The deep dive on what belongs in the gate is Course 5.

## The problem

You know you should run the tests before pushing. You usually do. But it is Friday, the change is small, you are sure it is fine, and you skip it. That is the push that breaks production. Relying on human discipline for routine checks fails eventually, for everyone, because attention is finite and the boring check is the first thing to go when you are tired or rushed. The fix is not more discipline. It is removing the human from the loop entirely so the check runs every single time, automatically, with no decision involved.

## What a hook is

A hook is a command that runs automatically when a specific event fires. You decide the event and the command, and if the command exits with a failure, the action can be blocked. Claude Code exposes lifecycle hooks around the agent's work: before a tool runs (PreToolUse), after a tool runs (PostToolUse), when the agent finishes responding (Stop), and others. You can use PostToolUse to auto-format a file the moment the agent edits it, or PreToolUse to block a dangerous command. These hooks are deterministic - they are the harness running your script, not the model deciding to.

- PreToolUse: runs before a tool call. Use it to validate or block an action before it happens.
- PostToolUse: runs after a tool call. Use it to auto-format or lint a file right after an edit.
- Stop: runs when the agent finishes responding. Use it to run a final check or notify you.
- Hooks are deterministic harness behaviour, so they fire reliably - unlike asking the model nicely to remember.

## Wiring a hook in settings.json

Claude Code hooks are configured in settings.json, in your project at .claude/settings.json or in your user config. Each hook matches an event and a tool pattern and runs a shell command. Here is a real PostToolUse hook that formats and lints any TypeScript file the moment the agent edits or writes it, so the codebase is never left in a messy state between turns.

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bun run prettier --write \"$CLAUDE_FILE_PATHS\" && bun run eslint --fix \"$CLAUDE_FILE_PATHS\""
          }
        ]
      }
    ]
  }
}
```
.claude/settings.json - auto-format and lint after every edit

The matcher targets the Edit and Write tools, and the command runs against the files the agent just touched. Now formatting is never a thing you or the agent has to remember, because the harness does it after every change. Check the official hooks docs for the exact environment variables and matcher syntax, since these are refined over time.

## The pre-push quality gate

The single highest-value automation is a gate that runs your full check suite before code can leave your machine. The most robust place for this is a Git pre-push hook, because it protects the repo regardless of which agent or human is pushing. A Git hook is just an executable script in the .git/hooks folder, or better, managed by a tool like Husky so it is committed and shared. If any check fails, the script exits non-zero and the push is refused. Broken code cannot reach your repo, full stop.

```bash
#!/usr/bin/env bash
# .husky/pre-push - blocks the push if any check fails

set -e  # stop at the first failing command

echo "Running quality gate before push..."
bun run lint
bun run typecheck
bun run test

echo "All checks passed. Pushing."
```
A pre-push Git hook that runs the full quality gate

With set -e, the first failing check aborts the script and the push never happens. This one gate prevents the most common way teams ship regressions: someone skipping the tests on a "small" change. It costs you a minute on each push and saves you the afternoon a broken deploy would have cost.

## Agent hooks versus Git hooks

These two systems complement each other, and knowing which to use matters. Claude Code hooks fire around the agent's actions and are great for keeping each edit clean - format on write, block a forbidden command, notify you when a long task finishes. Git hooks fire around version-control events and are the right place for the hard quality gate, because they guard the repo no matter who or what initiates the push. The pattern most serious builders use: agent hooks for tidy-as-you-go, Git hooks for the final gate that nothing gets past. Belt and braces.

## Typical mistakes

The frequent ones: putting your only quality gate inside an agent hook, so a manual push from the terminal sails straight past it; writing a hook that is so slow every push becomes painful and you start bypassing it; forgetting set -e so a failing check is ignored and the push proceeds anyway; and not committing your Git hooks (use Husky) so they only protect your machine and not your teammates. A gate only works if it is fast, shared, and genuinely blocking.

## Business ROI

Automation beats discipline every time, and the math is brutal in its favour. A pre-push gate that takes a minute prevents the broken deploy that costs an afternoon of firefighting plus the trust hit of a customer-facing bug. Encoding the check as a hook means it runs for everyone, every time, with zero ongoing attention. For a founder, this converts "I hope everyone remembers to test" into "broken code cannot ship" - a guarantee rather than a wish. Good automation makes the right thing the default thing, and the default thing is what actually happens at 6pm on a Friday.

## Checklist

You are ready to move on when each of these is true. The gate you build here is the backbone of the quality work in Course 5.

- You can name three Claude Code lifecycle events and what each is good for.
- You have a PostToolUse hook that formats or lints after edits.
- You have a pre-push Git hook that runs lint, typecheck and test and blocks on failure.
- Your Git hooks are committed and shared, not just on your machine.

## Resources

Bookmark the official Claude Code hooks documentation for the current event names, matchers and environment variables. Husky is the standard tool for committed, shared Git hooks - its docs walk you through setup in a couple of commands. The testing lesson in Course 5 covers exactly what to put inside the gate so it catches real bugs without being slow.

## Your task

Add a pre-push Git hook to a real project that runs your lint, typecheck and test commands and blocks the push if any fail. Deliberately break a test, try to push, and watch it get refused. Then add a Claude Code PostToolUse hook that formats files after edits. You now have automation enforcing your standards instead of your memory.

## Next lesson

Your agent now follows rules, runs packaged workflows, and enforces gates automatically. The next lesson connects it to the world beyond your files: MCP, the Model Context Protocol, which gives your agent access to databases, design tools, services and data sources through one standard plug.

## Transcript

This lesson is a written, text-first guide. Hooks let you run your own scripts automatically at key moments in the agent lifecycle - before a tool runs, after a file is edited, when the agent finishes, before a push. This is how you enforce quality gates like tests, linting and type checks so nothing broken ever leaves your machine, without relying on memory or discipline. This lesson shows the real settings.json that wires it up. You will automate quality gates and routine steps with lifecycle hooks and scripts so they run without you thinking about them. Work through the sections in order, try the task at the end in a real project, and move on once it works for you. There is no video required - everything you need is in the written steps above.
