Set up Claude Code hooks for formatting, tests and protected files
Add PostToolUse hooks that format and test after edits, a PreToolUse hook that blocks protected files, and a notification for long runs.

Tools used
- Claude CodeRuns the hooks at each lifecycle event
- GitShares the project settings with the team
Step navigator
A committed .claude/settings.json with hooks that run every time, whatever the model decides.
Claude Code users who keep reminding it to format, test, or stay out of certain files.
Before you start
Developers on r/ClaudeAI call hooks the feature most people skip. The setups they share are the same four: run tests after edits, format after edits, block certain files, and notify when a run finishes. Claude Code's docs give the exact config.
Step-by-step instructions
Use hooks for anything that must always happen
Instructions in CLAUDE.md are advisory; hooks are deterministic. One user on blocking a folder: "a hook that exits with an error when Claude tries to write there will stop it reliably. Much cleaner than hoping your instructions hold."

Auto-format after every edit
In .claude/settings.json, add a PostToolUse hook with matcher Edit|Write that runs Prettier on the edited file; the docs' command is jq -r '.tool_input.file_path' | xargs npx prettier --write. One user's reason: "Claude's style drifts in long sessions."
Run tests after edits so Claude sees failures
Add a fast test command as another post-edit hook. "Claude makes a change, tests run automatically, Claude sees the output and adjusts. It closes the feedback loop."
Block protected files with a PreToolUse hook
Add a script in .claude/hooks/ that reads the file path from stdin and exits with code 2 for patterns such as .env, package-lock.json or .git/, and register it as a PreToolUse hook on Edit|Write. Exit 2 blocks the action and sends your message back to Claude. "Only pre tool use can actually stop Claude."
Why this works
A blocked edit is explained to Claude so it can adjust.
Get notified when a long task finishes
Add a Notification hook (or one on Stop) that fires a desktop notification. One user includes the exit status "so I know immediately if it finished clean or hit an error."
Check with /hooks and commit the project settings
Run /hooks to confirm each hook is listed under the right event. .claude/settings.json can be committed so the team shares it; .claude/settings.local.json stays personal.
End of guide · Reviewed Oct 26, 2026
Pro tips2
- You can ask Claude to write the hook for you, e.g. "Write a hook that runs eslint after every file edit."
- Edit|Write hooks miss files changed through Bash; the docs suggest a Stop hook that scans the tree if that matters.
Common mistakes3
- Putting a must-always rule in CLAUDE.md instead of a hook.
- Running a slow full test suite on every edit.
- Using a catch-all matcher on a permission hook, which approves everything.


