ESLint --fix: A Mechanical Editor, Not a Code-Quality Fix
ESLint --fix can clear formatting noise in seconds, but it won't fix unused variables or logic bugs. Here's a safe workflow and the limits to know.
03 Oct 2025, 18:36 UTC

You open a pull request and the diff is 400 lines of semicolons, quote swaps, and indentation. The actual bug — a missing await — is buried on line 312. This is the problem ESLint's --fix flag was built to reduce.
The thesis here is simple: treat --fix as a mechanical editor. It applies deterministic, rule-defined rewrites to your source files. It is not a substitute for reading the code, and it will not fix logic errors, unused variables, or missing imports.
What --fix can and cannot change
ESLint rules are either fixable or not. A fixable rule has a defined transformation that ESLint can apply without understanding your program's runtime behavior. A non-fixable rule reports a problem but leaves the edit to you.
| Rule | Auto-fixable? | What --fix does |
|---|---|---|
semi | Yes | Adds or removes semicolons |
quotes | Yes | Rewrites string literals to the configured style |
indent | Yes | Re-indents lines to the configured width |
no-unused-vars | No | Reports unused variables; you remove them |
no-undef | No | Reports undefined references; you resolve them |
That table is not exhaustive, and the exact set of fixable rules depends on your ESLint version and installed plugins. Check a rule's documentation for the wrench icon, or run npx eslint --print-config path/to/file.js to see which rules are active in your configuration.
A safe workflow for applying --fix
Run these commands from your project root. You need a local ESLint installation and a configuration file. You do not need elevated permissions — only write access to the files being changed.
- Preview the changes.
npx eslint --fix-dry-run "src/**/*.js"prints what would be fixed without writing to disk. The quoted glob lets ESLint expand the pattern rather than your shell. - Apply the fixes.
npx eslint --fix "src/**/*.js"writes the changes. ESLint exits with code 0 if no errors remain, and non-zero if some problems are not auto-fixable. - Review the diff.
git diffshows exactly what changed. Look for anything that alters behavior, not just formatting. - Run your tests. A clean lint run is not a passing test suite. Confirm the code still works.
If the diff is wrong, roll back before committing: git restore . discards unstaged changes in the working tree. If you already staged the changes, use git restore --staged . followed by git restore ..
One useful flag for limiting scope is --fix-type. For example, npx eslint --fix --fix-type layout "src/**/*.js" applies only formatting fixes, leaving problem and suggestion fixes untouched. That separation is helpful when you want a formatting-only commit.
Where --fix stops helping
The limitation is not a bug; it is the boundary of what a linter can know. --fix cannot resolve a race condition, a missing await, or a variable that is assigned but never read. Over-reliance on auto-fix can mask those problems: a repository with zero lint errors can still be broken.
Context-sensitive fixes also deserve a human eye. A rule that rewrites let to const may be correct in most cases, but if your configuration is wrong or a plugin misbehaves, the fix can change behavior. Reviewing the diff is the check that catches this.
For CI, prefer enforcement over silent rewriting. Running npx eslint "src/**/*.js" without --fix fails the build when violations exist. If you do run --fix in CI, use --fix-dry-run and fail on a non-empty diff, or run it in a separate formatting job that does not touch logic.
What to do next
Start small. Pick one directory, run --fix-dry-run, and read the proposed changes. If they are purely mechanical, apply them and commit separately from any logic changes. Add --fix to a pre-commit hook only after you trust the rule set in your configuration.
Keep non-fixable rules — no-unused-vars, no-undef, and anything from your framework's plugin — in your manual review pile. That is where the real bugs live.
Version note: ESLint v8 and v9 both support --fix and --fix-dry-run. ESLint v9 defaults to flat config (eslint.config.js), while v8 projects often use .eslintrc.*. Verify flag behavior against your installed version with npx eslint --help before applying fixes across a large codebase.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.