| | |

ESLint 06 🛡️ Configuring Rules — Inline comments vs. config objects

⏱️ Estimated read: 10 min | |

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

MechanismScopeLocation
Configuration fileProject-wide or file-patterneslint.config.js
Inline /* eslint */FileTop of file
eslint-disable-next-lineOne lineBefore the line
eslint-disable-lineOne lineOn the line
eslint-disable / eslint-enableRangeAround the range

Severity values

ValueMeaning
off / 0Rule disabled
warn / 1Warning, exit code 0
error / 2Error, exit code 1

Precedence (highest to lowest)

OrderSource
1eslint-disable / eslint-enable
2/*global*/
3/*eslint*/
4/*eslint-env*/
5CLI options
6Configuration files

Inline control options

OptionEffect
noInlineConfigDisable all inline configuration
reportUnusedDisableDirectivesReport 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

PitfallWhy It HappensFix
Inline disable hides a real issueUsed as a quick fixFix the code or move the rule change to the config file
Disable comment is staleThe code no longer violates the ruleUse reportUnusedDisableDirectives
Rule still reported despite inline disableWrong rule name or plugin prefixCheck the exact rule ID
Inline config ignorednoInlineConfig: true is setRemove the option or use the config file
Precedence confusionInline overrides config fileAccept 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

ItemValue
Configuration fileeslint.config.js, rules object
Inline rule config/* eslint rule: severity */
Inline disableeslint-disable-next-line, eslint-disable-line, range
PrecedenceInline > CLI > config file
Disable reason-- separator after the rule name
Disable all inlinenoInlineConfig: true
Report stale disablesreportUnusedDisableDirectives
Recommended defaultConfiguration 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 .
  • noInlineConfig enforces 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 .
  • reportUnusedDisableDirectives catches 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 error for source files and off for 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.

Was this helpful?


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!