Skip to content
Helped by a Nerd

AI Tools

Claude Code Hooks: Automate Your AI Coding Workflow

Published on Reading time: 9 min

  • #claude-code
Contents

Most people treat Claude Code like a very smart autocomplete: you ask, it edits, you move on. But the moment you start relying on it for real work, you hit a wall. The AI forgets to run your formatter. It edits a file you wanted left alone. It runs a shell command you would never have approved. You end up babysitting every step, which defeats the whole point of an agentic assistant. Claude Code hooks are the way out of that loop.

Hooks are the fix. They let you wire your own shell commands into specific moments of a Claude Code session — before a tool runs, after a file is written, when you submit a prompt — so the behavior you care about happens automatically and deterministically, every single time. This guide walks through what hooks are, the events you can hook into, how to set one up, real-world examples, and how to do it all without handing your machine to an automated process unsupervised.


What are Claude Code hooks?

Claude Code hooks are shell commands that run automatically at defined points in a session, giving you deterministic control over an otherwise probabilistic AI.

A normal AI workflow is “soft”: you can ask Claude in your instructions to always run tests after editing, but a language model may or may not follow that on any given turn. Hooks are “hard”: they are configuration, not a polite request. When the matching event fires, your command runs — no exceptions, no forgetting.

The mechanism is simple. When an event triggers, Claude Code passes a small block of JSON describing what just happened (which tool, which file, what input) into your hook command via standard input. Your command does its job and signals back with an exit code: success means “proceed,” while a specific failure code can block the action entirely. That feedback loop is what makes hooks powerful — they don’t just observe, they can intervene.

If you are brand new to the tool, it helps to read our Claude Code overview first, since hooks assume you already know how the agentic loop edits files and runs commands on your behalf.


Which hook types are there?

Claude Code exposes a set of lifecycle events, and the two you will use most are PreToolUse (before a tool runs) and PostToolUse (after it finishes).

The events fall into three natural cadences. Some fire once per session, some once per turn, and some on every single tool call inside the agentic loop. Here is the practical breakdown:

  • SessionStart / SessionEnd — fire once when a session opens or closes. Good for loading context, logging, or cleanup.
  • UserPromptSubmit — fires when you send a prompt, before Claude processes it. Useful for injecting extra context or validating input.
  • PreToolUse — fires after Claude has decided on a tool call but before it executes. This is your gatekeeper: you can allow, block, or ask for confirmation.
  • PostToolUse — fires after a tool finishes. Ideal for formatters, linters, or tests that should run on the result.
  • Stop / SubagentStop — fire when the main agent or a subagent finishes responding.
  • Notification — fires when Claude Code wants to alert you (for example, when it needs permission).

The most important distinction is timing. PreToolUse runs before the action and can stop it — that makes it the natural home for safety rules. PostToolUse runs after, so it can react to or clean up a result, but it cannot undo what already happened. Keep that asymmetry in mind: prevention belongs in PreToolUse, reaction belongs in PostToolUse.

Hooks pair naturally with other Claude Code building blocks. If you orchestrate work across Claude Code subagents, the SubagentStop event lets you act when each one finishes, and hooks complement the reusable instructions you package as Claude skills.


How do you set up a hook?

You set up a hook by adding a matcher-and-command entry to your settings file, telling Claude Code which event to listen for and what shell command to run.

Hooks live in your settings JSON — either the project-level .claude/settings.json (shared with your team) or your personal user settings. Each hook entry has three parts: the event it listens to, a matcher (a pattern against tool names), and the command to run.

Here is a minimal PostToolUse hook that runs the Prettier formatter every time Claude writes or edits a file:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATHS\""
          }
        ]
      }
    ]
  }
}

The matcher is a simple pattern matched against the tool name. "Write|Edit|MultiEdit" matches any file-writing tool; "Bash" matches only shell commands; an empty matcher matches everything. The command can be an inline one-liner or a path to a script like .claude/hooks/format.sh — a script is cleaner once your logic grows beyond a single line.

Three practical tips for getting this right:

  1. Start in a throwaway project. Hooks run real commands on your machine, so test them where mistakes are cheap.
  2. Read from stdin. Claude Code feeds your command JSON describing the event. A script that parses it (with jq, for example) is far more precise than blindly matching on tool name alone.
  3. Use exit codes deliberately. Exit 0 means success. In a PreToolUse hook, a blocking exit code stops the tool call and shows your message to Claude as the reason. Always confirm the exact codes and field names against the official docs, since the contract is what makes the behavior reliable.

For a gentler on-ramp to the editor itself before you start customizing it, our Claude Code tutorial covers the basics, and installing Claude Code walks through setup if you haven’t yet.


What are some practical hook examples?

Practical hooks usually fall into three buckets: auto-formatting after edits, enforcing tests or checks, and blocking dangerous or off-limits actions.

Here are patterns people reach for repeatedly:

  • Auto-format on save. A PostToolUse hook matching Write|Edit|MultiEdit runs Prettier, Black, gofmt, or your formatter of choice on every file Claude touches. Your code stays consistent without anyone remembering to run it.
  • Lint and type-check after changes. Chain ESLint or a type checker into the same PostToolUse hook. If something breaks, the failure is surfaced immediately instead of three commits later.
  • Run a focused test suite. After edits to a module, trigger the relevant tests. You catch regressions in the same turn Claude introduces them.
  • Protect sensitive files. A PreToolUse hook on Edit|Write can inspect the target path and block any write to .env, production config, or a secrets/ directory — returning a clear reason so Claude knows why.
  • Guard the shell. A PreToolUse hook on Bash can scan the proposed command and refuse obviously destructive patterns like recursive force-deletes before they ever execute.
  • Desktop notifications. A Notification or Stop hook can ping you (a sound, a system notification) when Claude finishes a long task, so you can step away without watching the terminal.

These mechanical, deterministic chores are exactly what hooks are built for, and they slot neatly into broader Claude Code workflows — the repeatable, multi-step routines that turn the tool from a chat box into a teammate.


How do you keep hooks safe?

Hooks execute arbitrary shell commands automatically with your permissions, so the core safety rule is to treat every hook as code you are responsible for — review it, scope it tightly, and never run a hook you don’t understand.

This is the part people skip, and it matters most. A hook is not a sandboxed plugin; it is a command running on your machine with your user’s access. A careless or malicious hook can delete files, leak secrets, or run anything you could run yourself. A few rules keep you out of trouble:

  • Read before you trust. If you copy a hook from a blog post or a repo, read every line first. The same caution you’d apply to any script from the internet applies here — doubly so because it runs automatically.
  • Scope matchers narrowly. A hook matching only Bash is easier to reason about than one matching everything. Tight matchers reduce the surface area for surprises.
  • Quote and validate paths. Always quote variables in your commands and validate input parsed from stdin. Unquoted paths with spaces or odd characters are a classic source of bugs.
  • Prefer blocking over cleanup for risk. Stopping a dangerous action in PreToolUse is safer than trying to repair the damage in PostToolUse, because by then the action has already run.
  • Keep team hooks in version control. Storing hooks in .claude/settings.json means changes get reviewed in pull requests instead of appearing silently in someone’s local setup.

The broader principle is the same one that governs any automated agent: deterministic automation is a force multiplier in both directions. The mindset overlaps heavily with the vibe coding risks discussion — convenience is great until an unattended process does something you didn’t intend.


FAQ

What are hooks in Claude Code used for?

Hooks are used to run your own shell commands automatically at specific points in a Claude Code session. The most common uses are auto-formatting and linting code after edits, running tests, sending notifications, and blocking risky actions like edits to protected files. They turn “please remember to do this” instructions into guaranteed, deterministic behavior.

What is the difference between PreToolUse and PostToolUse?

PreToolUse fires before a tool runs and can stop the action, making it the right place for safety checks and permission gates. PostToolUse fires after the tool finishes and is used to react to the result — running a formatter, linter, or test. The key difference is that PreToolUse can prevent something from happening, while PostToolUse can only respond once it already has.

Are Claude Code hooks safe to use?

Hooks are safe when you write or carefully review them, but they run arbitrary commands with your permissions, so they are not safe to use blindly. Never enable a hook you copied without reading it, scope your matchers narrowly, and keep team hooks in version control so changes get reviewed. Treat a hook with the same caution you’d give any script downloaded from the internet.

How are hooks different from skills and MCP servers?

Hooks fire deterministically at lifecycle events to run shell commands, whereas Claude skills are reusable instruction sets the model chooses to invoke, and MCP servers expose external tools and data. They solve different problems: hooks enforce mechanical rules, skills package know-how, and MCP connects Claude to outside systems. Our skills vs MCP vs subagents breakdown explains where each one fits.

Do I need to know how to code to use hooks?

You need basic comfort with the command line and shell commands to use hooks effectively, since a hook is fundamentally a shell command. That said, simple hooks like an auto-format one-liner are approachable for beginners. If you’re easing into the tool from a non-developer background, Claude Code for non-coders is a friendlier starting point before you customize hooks.


Conclusion

Hooks are what separate using Claude Code as a chat assistant from running it as a dependable part of your workflow. By wiring shell commands into events like PreToolUse and PostToolUse, you replace fragile “please remember to” instructions with rules that fire every time — formatting your code, running your tests, and blocking the actions you never want an AI to take.

Start small: add one PostToolUse formatter hook in a test project, confirm it behaves, then layer on a PreToolUse guard for a file you want protected. Because hooks run real commands with your permissions, review every one before you trust it, scope your matchers tightly, and check the exact event contract against the official Claude Code docs. Get those habits right and hooks become one of the highest-leverage features the tool offers.

More on this topic

Newsletter

Never miss an AI update

New tools, guides and deals – once a week, straight to your inbox.

100% free, cancel anytime.