Lint on save with Claude Code hooks
Wire a PostToolUse hook to run your linter automatically after every Edit/Write.
Claude Code runs shell commands at well-defined lifecycle points via the hooks
config in ~/.claude/settings.json. The highest-leverage one is PostToolUse —
it fires after any tool completes, so you can run a formatter or linter the
moment a file is touched.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && npx --yes eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}
]
}
]
}
}
Three things to notice:
matcheris a regex over tool names — this fires only on file-mutating tools.- The
|| truemeans lint failures don't block the tool output (hooks that exit non-zero are surfaced as errors to Claude). $CLAUDE_FILE_PATHand$CLAUDE_PROJECT_DIRare injected by the harness.
Project-scoped variant: put the same JSON in .claude/settings.json at the repo
root and it applies only inside that repo.