Verified against Claude Code · 2026-08-02
Wire a PostToolUse hook that auto-formats every edit instead of nagging in review
A PostToolUse hook prompt for automatically running a formatter or linter after every Edit or Write call and feeding back only what actually changed — a mechanically distinct hook lifecycle from PreToolUse, since PostToolUse cannot block the action that already happened but can surface a correction as fresh context Claude acts on immediately in the same turn.
The prompt
Ready to copy — highlighted parts are example details you can swap.
Write a Claude Code PostToolUse hook that runs npx biome check --write automatically after every matching edit, and feeds back only what the formatter actually changed, rather than silently reformatting with no signal or blocking nothing while a style violation quietly ships. PostToolUse runs after the tool call has already executed and cannot prevent it — this hook is a feedback and auto-correction mechanism, not a guardrail, and the prompt and the script must both be built around that distinction rather than treated as a delayed PreToolUse check. WHICH TOOL CALLS THIS HOOK MATCHES Edit and Write calls only, not Bash or Read. FILE PATTERNS THIS APPLIES TO *.ts and *.tsx files only, skipping markdown and JSON files this formatter is not configured for. HOW MUCH DETAIL TO FEED BACK A short diff of just the lines the formatter touched, not the full file content. WHAT HAPPENS IF THE FORMATTER ITSELF FAILS Report the formatter’s error output distinctly, labeled as a formatter failure, not folded into the normal "formatting applied" message. PRODUCE 1. The settings.json fragment: a PostToolUse hooks entry matched to Edit and Write calls only, not Bash or Read. and scoped by *.ts and *.tsx files only, skipping markdown and JSON files this formatter is not configured for. so this does not fire on every tool call, only ones that actually touched a file this formatter applies to. 2. The hook script, which reads the tool input and result from stdin, identifies the exact file that was just edited, runs npx biome check --write against that specific file only, and compares the file's content before and after the formatter ran. 3. If the formatter changed anything, the script must report back to Claude, per A short diff of just the lines the formatter touched, not the full file content., specifically what changed — not the entire reformatted file, which would waste context repeating content that did not need to change, and not a bare 'formatting was applied' with no detail, which gives Claude nothing to actually learn from for its next edit in this same file. 4. If the formatter made no changes, the script should exit cleanly with no output — a hook that reports 'no changes needed' on every single edit adds noise to every turn for information that only matters the one time it is not true. EXIT CODE AND FEEDBACK MECHANICS Use exit code 2 with the diff on stderr when there is something for Claude to see, since that is what surfaces as additional context back to Claude in a PostToolUse hook, distinct from the blocking exit code a PreToolUse hook uses — a PostToolUse hook exiting with a blocking-style code does not undo the edit that already happened, it can only add noise without preventing anything, so confirm the exit code chosen actually does what this hook intends rather than assuming the same code means the same thing across both hook types. FAILURE HANDLING Per Report the formatter’s error output distinctly, labeled as a formatter failure, not folded into the normal "formatting applied" message., if the formatter command itself errors, such as on a syntax error the edit just introduced, report that distinctly from a normal formatting change — a formatter crash is different information than a style correction and conflating the two in the same feedback channel hides a possible real bug behind what looks like routine auto-formatting noise. OUTPUT The settings.json fragment and the hook script, followed by one example of the feedback Claude would actually see after an edit that needed reformatting, and one showing the silent case where nothing was needed.
Customize
Optional — swap in your own details for the highlighted parts above.
Why this works
PreToolUse and PostToolUse are genuinely different hook lifecycles with different available actions, and a prompt that treats PostToolUse as just a delayed version of the same blocking mechanism is asking the wrong tool to do a job it structurally cannot do — by the time a PostToolUse hook runs, the edit has already landed on disk, so there is no version of this hook that prevents a style violation from ever existing, only one that notices it immediately afterward and feeds a correction back into the same turn before the conversation moves on. This is exactly why the exit-code semantics get their own explicit section: a PreToolUse hook's blocking exit code means the call never happened, while the equivalent code from a PostToolUse hook means something different entirely, since the action already executed and the only thing exit code 2 with stderr output does here is surface that stderr content back to Claude as fresh context it can act on in its very next message — treating the two hook types as interchangeable because they share a name pattern in settings.json produces a hook that either silently does nothing useful or, worse, appears to be blocking something it has no actual power to block. Feeding back only what the formatter changed, rather than the full reformatted file, matters for the same reason a subagent's output contract matters — the point of the feedback is to give Claude exactly enough information to internalize the correction for its next edit in that file, and dumping the entire file back defeats that by drowning the one relevant piece of information in content that did not change and was never in question. Staying silent when the formatter made no changes is not a minor politeness, it is what keeps this hook actually useful over a long session — a hook that reports something on every single edit, whether or not there was anything to report, trains the exact kind of habitual disregard for its own output that a hook reporting rarely but meaningfully avoids, since a human or a model skimming past constant no-op noise is statistically much more likely to also skim past the one time the noise actually mattered. Separating a formatter crash from a routine formatting change in the feedback channel matters because the two carry very different implications — a formatter erroring on a file the edit just produced is frequently a signal that the edit introduced a real syntax problem, not merely a style issue, and collapsing that into the same generic feedback message as an ordinary auto-format hides exactly the information a session would most need to notice quickly.
Verified against
Claude Code Sonnet 4.6 · 2026-08-02
Changelog
- 2026-08-02 — Initial publish, verified against Claude Code PostToolUse hooks (Sonnet 4.6).
Building this for real?
This is a free starting point. If you'd rather have custom software built and running for your business, that's Scult's day job.
EXPLORE CUSTOM SOFTWARE
