A hook runs a configured action when Claude Code reaches a particular event. Start with a small, visible example: append a line to a local log after Claude successfully writes or edits a file, then prove that you can turn it off.

Before you start
- A working, signed-in terminal Claude Code installation on macOS, Linux, or WSL, using Bash or Zsh. The example command is written for these shells.
- A disposable local project folder with no existing hooks, or a project whose .claude settings you understand and have backed up.
- An editor that shows hidden folders and a harmless text file named hook-practice.txt in the project root.
- Permission to configure local hooks. Organization-managed settings may prevent personal or project hooks from running.
Want to do it yourself?
- Difficulty
- 8 out of 10
- Estimated completion time
- 1–2 hours
Skills you’ll need: Edit local configuration and a hook command, inspect logs, and prove both triggering and removal work as expected.

How this helps your brand
A tested local hook can support a consistent development habit around your project files. Knowing exactly which edits trigger it helps you use that automation without confusing it with customer-enquiry or website-form processing.
Step 1: Pick the event and the visible result
For this exercise, the event is PostToolUse and the matching tool names are Write or Edit. The action adds the sentence “Claude edited a file” to .claude/edit-log.txt. Nothing needs to connect to a service or install an extra library.
This log demonstrates that the automation ran. It is not a history of every change: edits made through a shell command or another editor do not match Write or Edit. PostToolUse also happens after the successful tool action, so this hook does not prevent or undo an edit.
Step 2: Add one local hook without replacing settings
Paste the prompt below into Claude Code. It asks Claude to merge a hook into .claude/settings.local.json, leaving any other settings in place. Local settings apply to this project; .claude/settings.json is the separate, shareable project settings file.
Inspect the resulting JSON in your editor. Under hooks, there should be a PostToolUse array containing an entry with matcher set to Write|Edit. Its hooks array should contain one command hook. The command uses printf to append the fixed sentence to the log under CLAUDE_PROJECT_DIR, the project root where the session started.
Keep the quotes around the destination path so a project folder with spaces still works. The prompt contains the exact command to compare against the saved value.
Tip: Hooks execute commands on your computer. For this first exercise, the entire action should be the single log append you inspected.
Illustrated exampleA local hook adds one safe, visible action.claude/settings.local.jsonlocal to this projectWhenPostToolUseafter a successful tool action Write|EditmatcherOne command
append fixed marker · do not overwriteprintf '%s\n' 'Claude edited a file' >> "$CLAUDE_PROJECT_DIR/.claude/edit-log.txt"Merge this entry into
hooks; preserve every other local setting.The event and matcher narrow when it runs; the command appends one fixed line under the project root. Keep the rest of your local settings intact. Step 3: Confirm that Claude loaded the hook
Start a fresh Claude Code session from the same project folder. Type /hooks and look for the PostToolUse hook and its Write|Edit matcher.
If it is missing, check for invalid JSON, including trailing commas, and confirm you edited the settings file in this project. If /hooks reports that only managed hooks run, ask your organization’s administrator about that policy before continuing.
Do not use the edits that created the settings file as proof of success. The hook was not necessarily active for those earlier actions.
Step 4: Make two deliberate edits and inspect the log
Ask Claude: Use the Edit tool to replace the text in hook-practice.txt with First hook test. Inspect the tool transcript to confirm it used Edit and the operation succeeded. If it used a shell instead, ask it to repeat a small change using Edit.
Open .claude/edit-log.txt in your editor. It should contain the marker sentence. Note the number of lines, then ask Claude to use Edit to change First hook test to Second hook test. Reopen the log and confirm it gained one line for that successful matching tool call.
If one request produces several matching tool calls, several lines are expected. Compare the log with actual tool calls, not the number of chat messages.
Illustrated exampleCount matching tool calls, then compare the logSuccessful matching tool calls 1EditReady → First hook test2EditFirst → Second hook testOne chat request can make more than one tool call.
.claude/edit-log.txt +2 lines01Claude edited a file02Claude edited a fileBash editdoes not match
+0 linesWrite|EditTwo successful Edit calls add two marker lines, even if they came from one request. A Bash edit is outside this matcher. Step 5: Investigate a missing log entry
First check whether the edit succeeded and whether the tool was exactly Write or Edit. The matcher is case-sensitive. An edit made by Bash is a useful comparison: it should not trigger this hook.
If a successful matching edit produces no marker, recheck /hooks and the quoted command. Start Claude Code with claude --debug to collect hook execution details in its debug log. A missing destination or permission error needs fixing before another test; the website edit may already have happened.
Stop the exercise if the saved command does more than append the marker. Restore your saved settings, then add only the intended entry again.
Illustrated exampleTrace a missing marker in a useful orderSTART HEREDid the edit succeed with exactly Write or Edit?Check the tool transcript. Shell edits do not match this hook.NORepeat a small edit with Edit Then compare the log with successful matching calls.
YESCheck /hooks and the saved command Confirm the hook loaded, matcher is
Still missing? → restart withWrite|Edit, and the quoted path points under$CLAUDE_PROJECT_DIR.claude --debugIf the command does more than append the marker, restore your saved settings before testing again.
Verify the tool call first, then the loaded hook and command. The file edit may already have succeeded even if the hook failed. Step 6: Remove the hook and prove it stopped
Remove only this command hook from .claude/settings.local.json, preserving other entries and valid JSON. Start another session and check /hooks again.
Note the log’s current length and ask Claude to make one more Edit change to hook-practice.txt. The log should gain no marker from this removed hook. You can now delete the practice file and log yourself.
Once this cycle is familiar, consider a formatter or another useful local script. Test that script independently before attaching it to an event, and keep its scope equally clear.
You're done when
- /hooks lists the intended PostToolUse command with the Write|Edit matcher while it is enabled.
- Two successful matching edits produce corresponding marker lines that you inspected in the log.
- You can explain why a Bash edit would not be logged by this matcher.
- After removing the entry and restarting, another matching edit adds no marker from this hook.
Your prompt
Show promptHide prompt
COPY AND PASTE
Help me configure one small Claude Code command hook in this practice project. I use [macOS, Linux, or WSL] with [Bash or Zsh]. Read existing .claude/settings.local.json first and preserve every unrelated setting and hook. If this exact hook already exists, do not duplicate it. Merge an entry under hooks.PostToolUse with matcher "Write|Edit" and one hook with type "command". Use exactly this command as its command value, with the required JSON escaping: printf '%s\n' 'Claude edited a file' >> "$CLAUDE_PROJECT_DIR/.claude/edit-log.txt" Do not add other commands or change permission settings. Make sure hook-practice.txt exists with the text Ready for hook test; do not overwrite it if it contains other work. Validate the settings as JSON and show me the saved hook entry. Do not claim it has fired yet. Tell me to restart this project session, inspect /hooks, and test a successful Edit on hook-practice.txt. Explain how to remove only this hook while preserving valid settings.
Paste into terminal Claude Code in your practice project. Replace the operating-system and shell brackets. This shell command example does not cover native Windows PowerShell or CMD.
FREE BY EMAIL
Get the full AI guide
Our complete, step-by-step guide to using AI in your business, sent straight to your inbox.