A Scientific Approach to ESLint Governance in Legacy Projects
An effective and practical approach to ESLint governance.
Background
There are always those legacy projects where, when the boss asks you to jump in and develop a feature, you get a sinking feeling — afraid that once you push your changes to production, everything will crash. Yet you nervously start developing, hoping to get in and out as quickly as possible. Beyond the band-aid style business logic, what truly undermines your confidence is the lack of ESLint in the project. One careless mistake becomes a low-level syntax error causing a crash. Even worse is when ESLint is configured but nobody follows it. Imagine an editor screen full of red errors and yellow warnings — at that point, you’ve become desensitized to the errors and end up going with the flow. There’s a criminology theory that applies perfectly to software engineering: the “Broken Windows Theory”:
This theory suggests that if signs of disorder in an environment are left unaddressed, they encourage people to imitate and even escalate the behavior. Take a building with a few broken windows: if those windows aren’t repaired, vandals may break more windows. Eventually they may even break into the building, and if they find it unoccupied, they might squat there or set it on fire. A wall with some graffiti that isn’t cleaned will quickly become covered with messy, unsightly marks. A sidewalk with a few pieces of litter will soon accumulate more trash, and eventually people will see it as perfectly normal to toss their garbage on the ground.
As time passes, such projects become increasingly difficult to maintain. Of course, this difficulty isn’t solely an eslint issue — it involves a whole range of conventions and standards. Defining conventions and standards is easy; the challenge is ensuring they’re actually followed. This article focuses on eslint governance, using a project that’s still actively maintained as an example to illustrate how to govern such legacy projects.
Current State
The existing eslint error and warning counts:

Of these, 5,697 errors and 65 warnings could be auto-fixed, leaving 6,468 remaining after auto-fix. Investigation revealed that the project was using strict rule sets like Airbnb. Because the rules were so strict and there was no reliable mechanism to prevent non-compliant code from being committed, developers were even less willing to comply, and the error count kept growing. Even after auto-fixing, there were still 6,000+ errors. Therefore, choosing and defining a rule set that everyone can actually follow is crucial. Avoid falling into the trap of “stricter is better” — always remember that the goal is to ensure code meets a reasonable standard to prevent low-level errors.
Solution
After research and discussion, we adopted the following rule set:
1 | extends: [ |
We integrated prettier and lint-staged. The former ensures that any given piece of code produces exactly one deterministic format. The latter prevents new eslint errors from being introduced by enforcing validation on modified files, gradually reducing the error count over time.
Results
ESLint’s default output only supports file-level statistics, which is unsuitable for projects with massive error counts where nearly every file has a significant number of errors. Here we use the tool eslint-formatter-stats to analyze errors by rule type. The results are as follows:
ESLint Results After Integration (Before Fixes)

10,959 errors and warnings
ESLint Results After Integration and Fixes

837 errors and warnings
Analysis
Error Count
After integration and fixes, the error count was only 800+. The boss said, well, if we lower our standards a bit, our ESLint situation is actually pretty good.
Investigation
Most of the top-ranking errors by count don’t affect program functionality, and to ensure production stability, this round of governance avoided changing anything beyond auto-fixes. Therefore, we decided to focus on several high-risk errors that do or could cause real impact:
no-undef— using undefined variables. This type of error is very likely to cause a crash. Currently 13 instances.import-no-unresolved— importing non-existent modules. Currently 6 instances.react-no-key— array elements without akeyprop. This can cause performance issues. Currently 4 instances.react-native-no-unused-styles— unused styles that increase app bundle size. Currently 45 instances.no-dupe-keysandno-duplicate-case— duplicate object keys or switch cases that introduce uncertainty. Currently 7 instances.react/no-direct-mutation-state— directly modifyingthis.state, which may cause state updates to not take effect. Currently 21 instances.
Additionally, errors like non-camelCase variable names and loose equality checks (==), if present in large numbers, should be downgraded to warnings or turned off entirely — they’re ultimately harmless. After the above fixes, the remaining cleanup can be left to lint-staged.
A Scientific Approach to ESLint Governance in Legacy Projects
http://quanru.github.io/2020/09/28/A Scientific Approach to ESLint Governance in Legacy Projects

