Using ESLint Overrides to Tighten Rules on New Code Only
Learn how ESLint overrides let you enforce stricter rules on new or modified files while keeping legacy code tolerant, with a concrete config example and verification steps.
05 Jul 2025, 17:04 UTC

The problem: legacy var vs modern const/let
In a growing JavaScript codebase you often have older files that still use var while new features are written with const or let. Running ESLint across the whole project then produces a mix of warnings and errors: old files trigger no-var warnings, new files fail because they violate the same rule. This noise makes it hard to enforce a stricter standard for new work without blocking incremental migration.
How ESLint overrides work
ESLint lets you layer rule configurations through the overrides array in .eslintrc.json. Each override entry specifies a files glob (or array of globs) and a rule object. The base config applies first; later overrides are merged on top, so rules defined in an override replace or augment those from the base for matching files. Because merging happens per‑file, you can keep a tolerant baseline for legacy code while tightening rules for specific new directories.
Worked example: configuring overrides
Assume the following folder layout:
project/
├─ .eslintrc.json
├─ legacy/
│ └─ old.js
└─ src/
└─ new/
└─ add.js
1. Create a base config that treats no-var as a warning and does not enforce prefer-const:
{
"env": { "browser": true, "es2021": true },
"rules": {
"no-var": "warn",
"prefer-const": "off"
}
}
2. Add an override that targets only the src/new/ directory, upgrading no-var to an error and turning on prefer-const:
{
"env": { "browser": true, "es2021": true },
"rules": {
"no-var": "warn",
"prefer-const": "off"
},
"overrides": [
{
"files": ["src/new/**/*.js"],
"rules": {
"no-var": "error",
"prefer-const": "error"
}
}
]
}
3. Place a legacy file that still uses var:
// legacy/old.js
var x = 1;
4. Place a new file that also uses var (to see the override in action):
// src/new/add.js
var y = 2;
From the project root run:
eslint .– you should see a warning forlegacy/old.jsand two errors forsrc/new/add.js(one forno-var, one forprefer-const).eslint --print-config src/new/add.js– inspect the merged configuration; the output will show "no-var": "error" and "prefer-const": "error" under therulessection, confirming the override applied.
If you run the same commands on legacy/old.js, the printed config will retain the base warning level for no-var and prefer-const will stay off.
Trade‑offs and practical tips
While overrides give you granular control, they add complexity:
- Glob order matters. Overrides are processed in the order they appear; later entries win if globs overlap. To avoid surprises, keep overrides minimal and test with
eslint --print-config <file>after each change. - Performance. Many override entries increase config resolution time, especially in large monorepos. Use broad globs where possible and periodically audit the
overridesarray. - Editor integration. Some IDEs cache ESLint configurations. After modifying
.eslintrc.json, you may need to restart the language server or reload the project to see updated linting.
A practical way to verify that your overrides are working as intended is to run eslint --print-config <path> for a few representative files (both inside and outside the override glob) and compare the rule levels. If the output matches your expectations, you can be confident the linting behavior will be consistent across the team.
Next steps
Start by applying overrides to a single new directory or a set of files you control. Use the --print-config check to validate each change, then gradually expand the scope as you migrate legacy files to modern syntax. When you need to revert, simply delete or comment out the override block (or roll back the .eslintrc.json file in version control). This incremental approach lets you raise quality on new work without blocking the existing build.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.