Claude Code Claude CodeAutomation

Claude Code hooks: automate format, lint, and alerts

A hook is a shell command Claude Code runs automatically on an event, before or after it uses a tool, or when it finishes. You configure hooks in settings.json to make routine checks happen without asking: validate a file the moment it is written, format code, block a risky action, or ping Slack when a long job is done. Hooks turn the QA you keep forgetting into something that runs itself.

Overview

We once shipped an enriched account list into the CRM with one column silently off by a row, so every company got the next company's employee count. Claude Code had written a clean-looking file; the break was subtle enough that nobody caught it until sales started citing numbers that made no sense on calls. The fix was not to be more careful. Careful is a hook you forgot to automate.

Hooks are how you stop relying on remembering. They run a command of yours on Claude Code's events, so the validation, the formatting, the alert, happens every single time, whether or not you were paying attention. This is the difference between a QA step that exists in your head and one that exists in the tool.

A hook is a command that runs on an event

A hook is a command that runs on an event

A hook ties one of your shell commands to something Claude Code does. When the event happens, your command runs. The classic shape: right after Claude writes a file, run a script that checks it. You did not ask; it just happened, because you wired it once.

That is the whole idea, and it is small on purpose. Claude Code is doing the work; hooks are the standing instructions that fire around the work without a prompt. Think of them as the guardrails and the reflexes: the things that should happen automatically so you never have to say them.

How a hook runs
01An event firesa tool is about to run, or just did
02Your hook runsa shell command you configured
03It actsformat, lint, test, or alert
04Claude continueswith the result in hand
Hooks run your own commands on Claude Code's events, so formatting, checks, and alerts happen without you asking.
Where hooks fire

Where hooks fire

Hooks hang off events in Claude Code's lifecycle. The ones you will use most are before a tool runs, after a tool runs, and when the session stops. Before is where you validate or block. After is where you format, check, or record. Stop is where you send the all-clear.

Matching the event to the intent is the craft. Validation that should prevent a bad write goes before the action, so it can stop it. A formatter goes after, once the file exists. A Slack ping that says the overnight lead-scoring job finished goes on stop, because that is when there is something to report.

  • Before a tool runs: validate inputs, or block an action that fails a check.
  • After a tool runs: format the file, run a linter, record what changed.
  • On stop: send an alert that an unattended job is done, with a one-line summary.
What GTM operators actually hook

What GTM operators actually hook

Forget the developer defaults for a second. In a GTM workspace, the file Claude writes is usually a CSV headed for your CRM, a list of drafts, a scored pipeline. The highest-value hook validates that file the instant it is written: right number of columns, no empty required fields, emails that look like emails, no row-shift like the one that burned us.

The second-highest-value hook is the alert. When a routine runs unattended, overnight enrichment, a Monday pipeline pass, you want to know it finished and whether anything looked off, without babysitting the terminal. A stop hook that posts a one-line summary to Slack turns an unattended job into one you actually trust.

The other quietly valuable hook is the one that records. A hook that appends a line to a log every time Claude writes to a customer-facing file gives you an audit trail for free, so when someone asks why did this account get that email, there is an answer instead of a shrug. For a regulated or just careful GTM team, that trail is worth the three lines it costs.

💡

TipYour first hook should validate data before it can reach a system of record. That is the class of mistake that is expensive to catch downstream and cheap to catch on write.

Hooks vs asking Claude to do it

Hooks vs asking Claude to do it

You could just tell Claude to validate the file after it writes it, and most of the time it will. Most of the time is the problem. A hook is deterministic: it runs every time, the same way, whether the session is fresh or forty messages deep and distracted. For anything that protects your data or your prospects, you want the guarantee, not the good intention.

So the rule I use: if forgetting it once is embarrassing, make it a hook. If it is a nice-to-have, a prompt is fine. Validation before a CRM write is a hook. Asking for a slightly nicer summary is a prompt.

There is a deeper reason too. Late in a long session, Claude is holding a full context and a stack of competing instructions, and a politely-requested check is exactly the kind of thing that slips through the cracks. A hook does not have a context window or a distracted afternoon. It is the same handful of shell every time, which is precisely what you want standing between a draft and your system of record.

Setting one up

Setting one up

Hooks are configured in settings.json, either your project's or your personal one. Each hook names the event to fire on, an optional matcher for which tool it applies to, and the command to run. It is a few lines of JSON, and because it lives in the project's settings, it travels with the repo: everyone who runs Claude Code in that folder gets the same guardrails.

The how-to below wires the two that matter most for GTM, a validator on write and a Slack alert on stop, so you can see the exact shape.

A starter library worth stealing

A starter library worth stealing

Once you have one hook, a few more pay for themselves fast. A validator on every CSV write. A formatter so every file Claude produces matches your house style. A guard that refuses a write to your production export unless a dry-run has passed. An alert on stop for anything unattended. None of these is more than a few lines, and together they are the whole difference between trusting Claude Code with real data and hovering over it like a nervous parent.

Keep them in the project's settings so they travel. A teammate who clones the repo and runs Claude Code inherits your guardrails on day one, with no conversation about remembering to validate the file, because remembering is not part of it anymore. That is the quiet compounding of hooks: the standards stop living in people's heads, where they are fragile, and start living in the tool, where they are reliable.

💡

TipBuild your hook library one at a time, each one triggered by a real mistake. The best set of hooks is a scar list: every check is there because something once went wrong without it.

Hooks, CI, and routines: where each guardrail lives

Hooks, CI, and routines: where each guardrail lives

Hooks are one of three places a check can live, and knowing which to use keeps you from wiring the same guardrail in the wrong spot. A hook runs on an event inside a Claude Code session, right now, as work happens, which makes it the place for immediate, per-action checks like validating a file the instant it is written. It is the reflex.

CI runs when you propose a change, on every pull request, which makes it the place for the checks that guard the shared record: does this change still produce sane numbers, does the data validate before it can merge. And routines run on a schedule, unattended, which is where the recurring job itself lives, often with its own hooks firing inside it. Reflex, gatekeeper, schedule. Put each check where its timing belongs.

Where hooks go wrong

Where hooks go wrong

The worst hook is a slow one. Because hooks run on events, a hook that takes ten seconds adds ten seconds to every one of those events, and the tool starts to feel like wading through mud. Keep hook commands fast; if a check is heavy, run it at the end, not on every write.

The second worst is a silent failure. A validation hook that errors out quietly gives you the confidence of a guardrail with none of the protection. Make hooks loud when they fail, and test them by feeding a deliberately broken file to make sure the hook actually catches it. A guardrail you never tested is a decoration.

  • Slow hooks that tax every event. Keep them fast, or move heavy checks to the end.
  • Hooks that fail silently, giving false confidence. Make failures loud.
  • Never testing the hook against a broken input, so you do not know it works.
  • Hooking so much that the session crawls. Hook the things that matter, not everything.
The GTM version

The GTM version

Put together, hooks are what let a GTM operator trust Claude Code with real data and unattended runs. A validator on write means a malformed list never reaches the CRM. A Slack alert on stop means the overnight job reports in like a colleague, done, here is the summary, one row looked odd. You stop hovering and start delegating.

The list I never shipped again was the row-shifted one, because a five-line hook now reads every file Claude writes and refuses the ones that do not add up. What is the check you keep doing by hand that should be running itself?

How to set it up

How to set it up

Open your settings.json

Hooks live in Claude Code's settings. Use the project settings so the guardrails travel with the repo, or your personal settings for just you.

zsh
$code .claude/settings.json
$# or run /config inside Claude Code to edit settings
$

Add a validator that runs after every write

Wire a PostToolUse hook to your own check script, so any file Claude writes gets validated the moment it lands:

settings.json
{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "command": "python3 scripts/validate_csv.py" } ] } }
$
💡

TipMake the script exit non-zero and print what failed when the file is bad. A loud failure is the whole point; a silent one is worse than no hook.

Add an alert when an unattended job finishes

Add a Stop hook that posts a one-line summary to Slack, so a routine that ran overnight reports in instead of leaving you to check:

settings.json
{ "hooks": { "Stop": [ { "command": "scripts/notify_slack.sh \"lead-scoring done\"" } ] } }
$

Test it with a broken file

Feed the validator a deliberately malformed CSV and confirm the hook catches it and complains. A guardrail you have not tested against a real break is decoration, not protection.

FAQ

Frequently asked questions

What is a Claude Code hook?

A shell command you configure to run automatically on a Claude Code event, such as before or after it uses a tool, or when the session stops. It runs your own script without you having to ask each time.

Where do I configure hooks?

In settings.json, either the project's (.claude/settings.json) or your personal one. Project settings travel with the repo, so the whole team gets the same hooks.

What events can a hook fire on?

The main ones are before a tool runs, after a tool runs, and when the session stops. There are others, but those three cover validation, formatting, and alerts.

Can a hook stop Claude from doing something?

Yes. A hook on a before-tool event can block the action if a check fails, which makes it a real guardrail: a write that fails validation never happens.

Why use a hook instead of just asking Claude?

Determinism. A hook runs every time, the same way, regardless of how the conversation is going. For anything protecting your data or prospects, you want the guarantee, not a reminder Claude might follow.

What is the best first hook for a GTM workspace?

A validator that checks any file Claude writes before it can reach your CRM: column count, required fields, sane values. That is the class of error that is cheap to catch on write and expensive to catch downstream.

Will hooks slow Claude Code down?

A slow hook taxes every event it fires on, so keep hook commands fast. If a check is heavy, run it once at the end rather than on every write.

How do I know a hook actually works?

Test it against a deliberately broken input and confirm it catches the problem loudly. An untested hook gives false confidence, which is worse than no hook at all.

Sources

Sources & further reading

Claude ships fast. This page was last reviewed Aug 22, 2026; verify time-sensitive details against the official docs above before relying on them.

Get the AI-for-GTM playbook in your inbox

New Claude guides, use cases, and prompts every couple of weeks.

Subscribe →