All articles

Formatting Code Automatically with a PostToolUse Hook

One of the most satisfying hooks to set up runs your formatter every time Claude edits a file. No more reminding it, no more messy diffs. This is the classic job for PostToolUse, which fires right after a tool finishes.

The config

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

Breaking it down

The matcher "Edit|Write" uses a pipe to match either tool. Whenever Claude edits or writes a file, the hook fires afterward.

The command runs Prettier in write mode. The $CLAUDE_FILE_PATHS variable holds the paths of the files touched by the tool call, so Prettier formats exactly what changed rather than the whole project. Quoting it handles paths with spaces.

Swap in your own tools

Prettier is just an example. The same shape works for any formatter:

{ "matcher": "Edit|Write",
  "hooks": [{ "type": "command", "command": "black $CLAUDE_FILE_PATHS" }] }

Use gofmt for Go, rustfmt for Rust, or black for Python. Because it is a plain shell command, you can chain steps together or point at a script in your repo.

Why after, not before

PostToolUse runs once the edit already landed on disk, so the file exists for your formatter to rewrite. Running it before the edit would format stale content. Set this up once and every change Claude makes lands already clean, which keeps your commits focused on real changes instead of whitespace noise.

Comments

Be the first to comment.