Auto Lint On Save
Production-ready hook that handles automatically, linting, tools, after. Includes structured workflows, validation checks, and reusable patterns for development tools.
Auto Lint On Save
Automatically runs language-specific linting tools after every file modification, fixing issues in-place where possible.
When to Use This Hook
Attach this hook when you need to:
- Ensure every file modification passes linting rules immediately after editing, catching style violations and potential bugs in real-time
- Automatically apply lint fixes like import sorting, whitespace normalization, and style corrections without manual intervention
- Maintain consistent code quality across all file edits during Claude Code sessions regardless of which tool made the change
Consider alternatives when:
- Your editor or IDE already runs linters on save and the duplicate linting would create conflicts or performance issues
- You prefer to batch lint checks at commit time rather than after every individual edit to reduce overhead
Quick Start
Configuration
name: auto-lint-on-save type: hook trigger: PostToolUse category: development-tools
Example Trigger
# Claude edits src/components/Button.tsx via Edit tool # Hook fires: # Running ESLint on src/components/Button.tsx...
Example Output
Auto Lint: src/components/Button.tsx
Linter: ESLint (detected from file extension .tsx)
Issues Found: 2
- Line 5: 'useState' is defined but never used (auto-fixed)
- Line 12: Missing semicolon (auto-fixed)
Issues Fixed: 2
Remaining Issues: 0
Status: CLEAN (all issues auto-fixed)
Core Concepts
Language Detection Overview
| Aspect | Details |
|---|---|
| JavaScript/TypeScript | ESLint via npx eslint --fix for .js, .ts, .jsx, .tsx files |
| Python | Pylint via pylint for .py files (reports issues, no auto-fix) |
| Ruby | RuboCop via rubocop --auto-correct for .rb files |
| Trigger Tools | Edit and MultiEdit operations that modify source files |
| Fix Mode | Auto-fix enabled where the linter supports it |
| Failure Handling | Linter errors are reported but do not block the workflow |
Lint Execution Workflow
PostToolUse (Edit/MultiEdit)
|
v
[Read $CLAUDE_TOOL_FILE_PATH]
|
v
[Detect file extension]
|
+--- .js/.ts/.jsx/.tsx --> [npx eslint --fix "$FILE"]
|
+--- .py --> [pylint "$FILE"]
|
+--- .rb --> [rubocop --auto-correct "$FILE"]
|
+--- Other --> [Skip - no linter configured]
|
v
[Report: issues found, fixed, remaining]
|
v
[Exit 0 (non-blocking)]
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
matcher | string | Edit|MultiEdit | Tool types that trigger the lint operation |
eslint_args | string | --fix | Additional arguments passed to ESLint for JS/TS files |
pylint_args | string | (none) | Additional arguments passed to Pylint for Python files |
rubocop_args | string | --auto-correct | Additional arguments passed to RuboCop for Ruby files |
fail_on_error | boolean | false | Whether to return a non-zero exit code when lint errors remain after auto-fix |
Best Practices
-
Ensure ESLint is configured in your project - The hook uses
npx eslintwhich requires ESLint to be installed as a project dependency. Runnpm install --save-dev eslintand create an.eslintrcconfiguration file before enabling this hook to avoid "configuration not found" errors. -
Use auto-fix judiciously with Pylint - Unlike ESLint, Pylint does not auto-fix issues by default. Consider using
autopep8orblackalongside Pylint for Python auto-formatting. The hook can be extended to run a formatter before the linter for a complete workflow. -
Test lint configuration with existing code first - Before enabling the hook, run the linter manually on your codebase to understand the current issue count. Enabling auto-lint on a project with many existing violations will generate excessive output during every edit.
-
Add language support incrementally - The default hook covers JavaScript, TypeScript, Python, and Ruby. Add support for additional languages like Go (gofmt), Rust (clippy), or PHP (php-cs-fixer) by extending the file extension detection logic in the hook command.
-
Coordinate with Prettier for formatting - If you use Prettier for formatting and ESLint for logic, ensure they do not conflict. Configure ESLint to defer formatting rules to Prettier using
eslint-config-prettierto prevent the two tools from fighting over style.
Common Issues
-
ESLint reports "No ESLint configuration found" - The project does not have an ESLint configuration file. Create one with
npx eslint --initor add a.eslintrc.jsonfile to the project root with your preferred rules. Without configuration, ESLint cannot lint files. -
Pylint exits with non-zero code despite no errors - Pylint returns exit codes based on message categories, including conventions and refactoring suggestions. A non-zero exit does not necessarily mean errors. The hook suppresses this with
|| trueto prevent false workflow blocks. -
Auto-fix creates unexpected changes - ESLint auto-fix may modify code in ways that change behavior, particularly with rules that restructure expressions. Review auto-fix rules in your ESLint configuration and disable auto-fix for rules where automatic changes could introduce bugs.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Pre-Commit Security Scanner
Pre-commit hook that scans staged files for hardcoded secrets, API keys, passwords, and sensitive data patterns before allowing commits.
Agents Md Watcher
Streamline your workflow with this automatically, loads, agents, configuration. Includes structured workflows, validation checks, and reusable patterns for automation.
Automated Build Inspector
Boost productivity using this automatically, trigger, build, processes. Includes structured workflows, validation checks, and reusable patterns for automation.