ESLint 06 🛡️ Configuring Rules — Inline comments vs. config objects
ESLint gives you two places to configure a rule’s severity and options: the configuration file (eslint.config.js or legacy .eslintrc) and inline comments inside the source file. The two mechanisms use the same severity values (off/warn/error or 0/1/2) and the same array syntax for rule options, but they differ in scope, precedence, and intended use. The configuration file is the project-wide default; the inline comment is a local override that applies only to the file or line where it appears.
This chapter covers both mechanisms, the precedence order that determines which one wins when they conflict, and the guidelines for when an inline override is justified versus when the rule should be changed in the configuration file.
Key point: Inline configuration has the highest precedence in ESLint’s hierarchy. An inline comment overrides the configuration file for the file or line it applies to. This makes it powerful and easy to abuse. The ESLint documentation recommends using configuration files for project-wide rule handling and reserving inline disables for cases with a clear, documented reason .
Why two mechanisms exist
The project-wide problem. A rule like no-console should apply to every file in the project. Setting it in the configuration file applies it consistently, and changing it later changes it everywhere. The configuration file is the right place for decisions that are meant to be uniform across the codebase.
The local exception problem. A test file may legitimately need console.log for debugging output. A generated file may contain code that violates a rule but cannot be edited. A specific line may need an any type because the third-party library’s types are wrong. These are local exceptions, and the inline comment is the mechanism for expressing them without weakening the rule for the entire project .
The precedence problem. ESLint evaluates configuration in a defined order. Inline configuration is applied after the configuration file, which means the inline comment wins. The hierarchy from highest to lowest precedence is: /*eslint-disable*/ and /*eslint-enable*/, then /*global*/, then /*eslint*/, then /*eslint-env*/, then command-line options, then the configuration files . An inline /* eslint rule: "error" */ overrides whatever the configuration file set for that rule.
a. Configuring rules in the configuration file
In the flat config (eslint.config.js), rules are set inside the rules object of a configuration object. The key is the rule ID, and the value is the severity or an array of severity plus options.
// eslint.config.js
export default [
{
rules: {
'no-console': 'warn',
'eqeqeq': 'error',
'quotes': ['error', 'single'],
},
},
]
The no-console rule is set to warn, which means violations are reported but ESLint exits with code 0. The eqeqeq rule is set to error, which means violations cause ESLint to exit with code 1. The quotes rule is set to error with the 'single' option, which requires single quotes .
The configuration file can also use overrides to apply different rules to different file patterns. A rule can be error for source files and off for test files, all within the same configuration file.
export default [
{
rules: { 'no-console': 'error' },
},
{
files: ['**/*.test.js'],
rules: { 'no-console': 'off' },
},
]
This is the project-wide mechanism for scoping rules by file pattern. It is preferred over inline comments because the decision is visible in one place and applies consistently to every file that matches the pattern .
b. Configuring rules with inline comments
An inline comment uses the syntax /* eslint rule: severity */ or /* eslint rule: [severity, ...options] */. The comment applies to the entire file if it is at the top, or to the surrounding scope if it is placed before the code.
/* eslint eqeqeq: "off", curly: "error" */
This comment turns off eqeqeq and turns on curly as an error for the entire file. The numeric equivalents work the same way: /* eslint eqeqeq: 0, curly: 2 */ .
For a rule with options, the array syntax is the same as in the configuration file:
/* eslint quotes: ["error", "double"], curly: 2 */
The first element is the severity, and the remaining elements are the rule’s options .
The more common inline mechanism is the disable comment, which turns a rule off for a line or a range. The // eslint-disable-next-line rule-name comment disables the rule for the next line. The /* eslint-disable rule-name */ and /* eslint-enable rule-name */ pair disables and re-enables the rule for a range. The // eslint-disable-line rule-name comment disables the rule for the current line .
// eslint-disable-next-line no-console -- reason: required for CLI output
console.log('diagnostic')
The -- separator introduces a description that explains why the disable is necessary. The ESLint documentation recommends documenting the reason for every disable comment and treating them as temporary measures with follow-up tasks .
c. The precedence and the noInlineConfig option
When both a configuration file and an inline comment set the same rule, the inline comment wins. This is by design: the inline comment is the most local configuration, and the precedence order reflects that .
The noInlineConfig option in the configuration file disables all inline configuration comments. When set to true, an inline comment that tries to configure a rule is itself reported as an error. This is the mechanism for enforcing a policy that all rule configuration must go through the configuration file.
export default [
{
linterOptions: {
noInlineConfig: true,
},
},
]
The --no-inline-config CLI flag achieves the same result for a single invocation . A project that has been burned by inline disables that hid real problems can use this option to prevent them entirely.
The reportUnusedDisableDirectives option reports disable comments that do not actually suppress any violation. This catches the case where a rule was disabled for a line that no longer violates it, which is a common source of stale disable comments.
Complete Example Session
// ============================================
// PART 1: CONFIG FILE RULES
// ============================================
// eslint.config.js
export default [
{
rules: {
'no-console': 'error',
'eqeqeq': 'error',
},
},
]
// ============================================
// PART 2: INLINE RULE CONFIGURATION
// ============================================
/* eslint eqeqeq: "off", curly: "error" */
// This file turns off eqeqeq and turns on curly.
// Both override the config file for this file only.
// ============================================
// PART 3: INLINE RULE WITH OPTIONS
// ============================================
/* eslint quotes: ["error", "double"] */
// The first element is severity.
// The second is the rule option.
// ============================================
// PART 4: DISABLE NEXT LINE
// ============================================
// eslint-disable-next-line no-console -- reason: diagnostic output
console.log('debug')
// The rule is off for the next line only.
// ============================================
// PART 5: DISABLE A RANGE
// ============================================
/* eslint-disable no-console */
console.log('a')
console.log('b')
/* eslint-enable no-console */
// The rule is off between the disable and enable comments.
// ============================================
// PART 6: DISABLE A SPECIFIC LINE
// ============================================
console.log('c') // eslint-disable-line no-console
// ============================================
// PART 7: THE PRECEDENCE
// ============================================
// Config file: no-console: "error"
// Inline comment: /* eslint no-console: "off" */
// Result: no-console is off for this file.
// Inline wins.
// ============================================
// PART 8: noInlineConfig
// ============================================
// eslint.config.js
export default [
{
linterOptions: {
noInlineConfig: true,
},
},
]
// Any inline configuration comment is now an error.
// ============================================
// PART 9: reportUnusedDisableDirectives
// ============================================
export default [
{
linterOptions: {
reportUnusedDisableDirectives: 'warn',
},
},
]
// A disable comment that suppresses nothing is reported.
// ============================================
// PART 10: THE CONFIGURATION FILE ALTERNATIVE
// ============================================
export default [
{
rules: { 'no-console': 'error' },
},
{
files: ['**/*.test.js'],
rules: { 'no-console': 'off' },
},
]
// Project-wide, visible, consistent.
// Preferred over inline disables.
The ten parts covered the config file rules, inline rule configuration, inline options, disable-next-line, disable range, disable-line, precedence, noInlineConfig, reportUnusedDisableDirectives, and the configuration file alternative.
Quick Reference
Configuration mechanisms
| Mechanism | Scope | Location |
|---|---|---|
| Configuration file | Project-wide or file-pattern | eslint.config.js |
Inline /* eslint */ | File | Top of file |
eslint-disable-next-line | One line | Before the line |
eslint-disable-line | One line | On the line |
eslint-disable / eslint-enable | Range | Around the range |
Severity values
| Value | Meaning |
|---|---|
off / 0 | Rule disabled |
warn / 1 | Warning, exit code 0 |
error / 2 | Error, exit code 1 |
Precedence (highest to lowest)
| Order | Source |
|---|---|
| 1 | eslint-disable / eslint-enable |
| 2 | /*global*/ |
| 3 | /*eslint*/ |
| 4 | /*eslint-env*/ |
| 5 | CLI options |
| 6 | Configuration files |
Inline control options
| Option | Effect |
|---|---|
noInlineConfig | Disable all inline configuration |
reportUnusedDisableDirectives | Report disables that suppress nothing |
Best Practices
✅ Do This:
// Use the config file for project-wide rules
export default [{ rules: { 'no-console': 'error' } }] // ✅
// Use overrides for file-pattern-specific rules
{ files: ['**/*.test.js'], rules: { 'no-console': 'off' } } // ✅
// Document inline disables with a reason
// eslint-disable-next-line no-console -- required for CLI output // ✅
// Use noInlineConfig to enforce config-file-only policy
linterOptions: { noInlineConfig: true } // ✅
❌ Don’t Do This:
// Use inline disables as the default solution
// eslint-disable-next-line no-console // ❌
// Leave an inline disable without a reason
// eslint-disable-next-line no-explicit-any // ❌
// Disable a rule inline for the whole file
/* eslint-disable */ // at the top of every file // ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Inline disable hides a real issue | Used as a quick fix | Fix the code or move the rule change to the config file |
| Disable comment is stale | The code no longer violates the rule | Use reportUnusedDisableDirectives |
| Rule still reported despite inline disable | Wrong rule name or plugin prefix | Check the exact rule ID |
| Inline config ignored | noInlineConfig: true is set | Remove the option or use the config file |
| Precedence confusion | Inline overrides config file | Accept the behavior; move the decision to the config file if it should be uniform |
Real-World Examples
1. Config file rule
export default [{ rules: { 'no-console': 'error' } }]
2. Inline rule override
/* eslint eqeqeq: "off" */
3. Inline rule with options
/* eslint quotes: ["error", "double"] */
4. Disable next line
// eslint-disable-next-line no-console
5. Disable range
/* eslint-disable no-console */
/* eslint-enable no-console */
6. Disable line
console.log('x') // eslint-disable-line no-console
7. Disable with reason
// eslint-disable-next-line no-console -- diagnostic output
8. Override by file pattern
{ files: ['**/*.test.js'], rules: { 'no-console': 'off' } }
9. noInlineConfig
linterOptions: { noInlineConfig: true }
10. reportUnusedDisableDirectives
linterOptions: { reportUnusedDisableDirectives: 'warn' }
Visual
The two mechanisms
┌─────────────────────────────────────────────────────────────┐
│ CONFIGURATION FILE │
│ eslint.config.js │
│ rules: { 'no-console': 'error' } │
│ → applies to every file │
│ │
│ INLINE COMMENT │
│ /* eslint no-console: "off" */ │
│ → applies to this file only │
│ │
│ Inline wins for the file where it appears. │
└─────────────────────────────────────────────────────────────┘
Precedence
┌─────────────────────────────────────────────────────────────┐
│ Highest: eslint-disable / eslint-enable │
│ /*global*/ │
│ /*eslint*/ │
│ /*eslint-env*/ │
│ CLI options │
│ Lowest: Configuration files │
└─────────────────────────────────────────────────────────────┘
The recommended split
┌─────────────────────────────────────────────────────────────┐
│ PROJECT-WIDE DECISIONS LOCAL EXCEPTIONS │
│ │
│ Configuration file Inline disable with reason │
│ Overrides by file pattern Documented, temporary │
│ Visible in one place Visible at the line │
└─────────────────────────────────────────────────────────────┘
noInlineConfig
┌─────────────────────────────────────────────────────────────┐
│ linterOptions: { noInlineConfig: true } │
│ │
│ /* eslint no-console: "off" */ → reported as an error │
│ │
│ All rule configuration must go through the config file. │
└─────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Configuration file | eslint.config.js, rules object |
| Inline rule config | /* eslint rule: severity */ |
| Inline disable | eslint-disable-next-line, eslint-disable-line, range |
| Precedence | Inline > CLI > config file |
| Disable reason | -- separator after the rule name |
| Disable all inline | noInlineConfig: true |
| Report stale disables | reportUnusedDisableDirectives |
| Recommended default | Configuration file for project-wide rules |
Key takeaways:
- The configuration file is the default; inline comments are the exception. Project-wide rule decisions belong in
eslint.config.js, where they are visible and consistent. Inline comments should be reserved for documented, local exceptions . - Inline configuration has the highest precedence. An inline
/* eslint rule: "off" */overrides the configuration file for the file it appears in. This is why an inline disable can hide a rule that the team thought was enforced . - Disable comments should have a documented reason. The ESLint documentation recommends the
--separator followed by an explanation. A disable without a reason is a future maintenance problem . noInlineConfigenforces a config-file-only policy. When set, inline configuration comments are reported as errors. This is the option for teams that have decided all rule configuration must go through the configuration file .reportUnusedDisableDirectivescatches stale disables. A disable comment that suppresses nothing is a leftover from a previous version of the code. Reporting it makes the cleanup visible.- Overrides are the configuration-file mechanism for file-pattern scoping. A rule can be
errorfor source files andofffor test files within the same configuration file. This is preferred over inline disables because the decision is visible in one place .
Remember: ESLint gives you two places to configure a rule because there are two kinds of decisions. The configuration file is for decisions that apply to the project or to a class of files. The inline comment is for exceptions that apply to one file or one line. The inline comment wins, which makes it powerful and easy to misuse. Use the configuration file by default, use inline disables sparingly and with a reason, and consider noInlineConfig if the team needs a hard rule that all configuration is centralized.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!