Auto-format generated Code with Claude Code Hooks

Auto-format generated Code with Claude Code Hooks
Date
Tags
Claude Code
Developer Tools
Automation

How to set up a PostToolUse hook in Claude Code to automatically run prettier after every file edit or write operation.

Claude Code is great at editing files, but it doesn’t automatically format them. If your project uses prettier, you’ll end up running it manually after every edit. That gets old fast.

The fix: a PostToolUse hook that runs prettier automatically after every Write or Edit operation - but only if the repo actually has prettier installed.

For the full hooks reference, see the Claude Code hooks documentation.

The Setup

Two files needed: a hook configuration and a bash script.

1. Add the hook to your settings

Edit ~/.claude/settings.json and add the hooks configuration:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/prettier-formatter.sh"
          }
        ]
      }
    ]
  }
}

This tells Claude Code to run the script after every successful Write or Edit tool use.

2. Create the formatter script

Create ~/.claude/hooks/prettier-formatter.sh:

#!/bin/bash
set -e

input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')

# Skip if no file path
[ -z "$file_path" ] || [ "$file_path" = "null" ] && exit 0

# Only format supported file types
echo "$file_path" | grep -qE '\.(js|jsx|ts|tsx|json|css|scss|html|md|yaml|yml|svelte)$' || exit 0

project_dir="${CLAUDE_PROJECT_DIR:-.}"

# Check if prettier is in package.json
if [ -f "$project_dir/package.json" ]; then
  grep -qE '"prettier"' "$project_dir/package.json" || exit 0
else
  exit 0
fi

# Run prettier if available
if [ -f "$project_dir/node_modules/.bin/prettier" ]; then
  "$project_dir/node_modules/.bin/prettier" --write "$file_path" 2>/dev/null || true
fi

exit 0

Make it executable:

chmod +x ~/.claude/hooks/prettier-formatter.sh

How It Works

The script receives JSON input from Claude Code containing details about the tool that just ran. It extracts the file path, then:

  1. Checks if the file type is something prettier handles
  2. Looks for prettier in the project’s package.json
  3. Runs the local prettier binary if it exists

If any check fails, it exits silently. No prettier in the repo? No problem - the hook just does nothing.

Verify It’s Working

Run /hooks in Claude Code to see your registered hooks. Then edit a file in a project with prettier installed - it should format automatically.

More Articles