Loading...
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/auto-code-formatter-hook.sh",
"matchers": [
"write",
"edit",
"multiedit"
]
}
}
},
"scriptContent": "#!/usr/bin/env bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Get file extension\nEXT=\"${FILE_PATH##*.}\"\n\n# Format based on file type\ncase \"$EXT\" in\n js|jsx|ts|tsx|json|md|mdx|css|scss|html|vue|yaml|yml)\n # JavaScript/TypeScript/Web files - use Prettier\n if command -v prettier &> /dev/null; then\n prettier --write \"$FILE_PATH\" 2>/dev/null\n echo \"✅ Formatted $FILE_PATH with Prettier\" >&2\n fi\n ;;\n \n py)\n # Python files - use Black\n if command -v black &> /dev/null; then\n black \"$FILE_PATH\" 2>/dev/null\n echo \"✅ Formatted $FILE_PATH with Black\" >&2\n elif command -v ruff &> /dev/null; then\n ruff format \"$FILE_PATH\" 2>/dev/null\n echo \"✅ Formatted $FILE_PATH with Ruff\" >&2\n fi\n ;;\n \n go)\n # Go files - use gofmt\n if command -v gofmt &> /dev/null; then\n gofmt -w \"$FILE_PATH\" 2>/dev/null\n echo \"✅ Formatted $FILE_PATH with gofmt\" >&2\n fi\n ;;\n \n rs)\n # Rust files - use rustfmt\n if command -v rustfmt &> /dev/null; then\n rustfmt \"$FILE_PATH\" 2>/dev/null\n echo \"✅ Formatted $FILE_PATH with rustfmt\" >&2\n fi\n ;;\nesac\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/auto-code-formatter-hook.sh",
"matchers": [
"write",
"edit",
"multiedit"
]
}
}
}#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Get file extension
EXT="${FILE_PATH##*.}"
# Format based on file type
case "$EXT" in
js|jsx|ts|tsx|json|md|mdx|css|scss|html|vue|yaml|yml)
# JavaScript/TypeScript/Web files - use Prettier
if command -v prettier &> /dev/null; then
prettier --write "$FILE_PATH" 2>/dev/null
echo "✅ Formatted $FILE_PATH with Prettier" >&2
fi
;;
py)
# Python files - use Black
if command -v black &> /dev/null; then
black "$FILE_PATH" 2>/dev/null
echo "✅ Formatted $FILE_PATH with Black" >&2
elif command -v ruff &> /dev/null; then
ruff format "$FILE_PATH" 2>/dev/null
echo "✅ Formatted $FILE_PATH with Ruff" >&2
fi
;;
go)
# Go files - use gofmt
if command -v gofmt &> /dev/null; then
gofmt -w "$FILE_PATH" 2>/dev/null
echo "✅ Formatted $FILE_PATH with gofmt" >&2
fi
;;
rs)
# Rust files - use rustfmt
if command -v rustfmt &> /dev/null; then
rustfmt "$FILE_PATH" 2>/dev/null
echo "✅ Formatted $FILE_PATH with rustfmt" >&2
fi
;;
esac
exit 0Formatter runs but changes get overwritten immediately
Check for competing hooks or watchers. Verify PostToolUse timing - runs after file write completes. Add debouncing if multiple formatters conflict. Review hook execution order.
Prettier config ignored and default settings applied
Verify .prettierrc exists in project root or ancestor directories. Check config search path: prettier --find-config-path file.js. Set explicit config: prettier --config path.
Hook matches multiedit but only formats first file
Check if FILE_PATH is array in multiedit context. Parse all paths: jq -r '.tool_input.edits[].file_path'. Loop through each file for formatting.
Formatter executable found but exits with permission denied
Verify formatter binary permissions: ls -la $(which prettier). Install locally: npm i -D prettier. Use npx to ensure correct binary: npx prettier --write file.
Silent failures with no feedback on format errors
Remove 2>/dev/null to expose stderr. Capture exit codes: prettier --write file || echo "Failed: $?" >&2. Add --loglevel debug for verbose output.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically creates timestamped backups of files before modification to prevent data loss