Skip to main content

Rule Configuration

Rules are the core building block of ESLint. This page explains how to configure rule severity, options, and when rules are applied.

Rule Severity Levels

Each rule has a severity level that controls how ESLint enforces it:

Off

"off" or 0Rule is completely disabled

Warn

"warn" or 1Reports violations as warnings (doesn’t affect exit code)

Error

"error" or 2Reports violations as errors (exit code 1 when triggered)

Choosing Severity Levels

Use for Critical IssuesSet rules to "error" when:
  • Code would cause runtime errors
  • Violations break critical conventions
  • Used in CI/CD pipelines
  • Pre-commit hooks
{
  rules: {
    "no-undef": "error",          // Undefined variables
    "no-unused-vars": "error",    // Unused variables
    "semi": "error"                // Missing semicolons
  }
}

Configuration Methods

Configuration Files

The primary way to configure rules is in your eslint.config.js file:
eslint.config.js
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    rules: {
      // String format
      "semi": "error",
      "quotes": "warn",
      "no-console": "off",
      
      // Numeric format
      "eqeqeq": 2,
      "curly": 1,
      "no-alert": 0
    }
  }
]);
String format ("error", "warn", "off") is recommended for better readability.

Configuration Comments

You can also configure rules using inline comments:
/* eslint eqeqeq: "off", curly: "error" */

// Or with numeric values
/* eslint eqeqeq: 0, curly: 2 */
Configuration comments have the highest priority and override all configuration file settings.

Rule Options

Many rules accept additional options to customize their behavior:

Basic Syntax

{
  rules: {
    // Severity only
    "semi": "error",
    
    // Severity with options (array format)
    "semi": ["error", "always"],
    "quotes": ["error", "double"],
    "comma-dangle": ["error", "never"]
  }
}
The first element in the array is always the severity level. All subsequent elements are options for the rule.

Object Options

Some rules accept object options:
{
  rules: {
    "no-unused-vars": ["error", {
      "vars": "all",
      "args": "after-used",
      "ignoreRestSiblings": true,
      "argsIgnorePattern": "^_"
    }],
    
    "prefer-const": ["error", {
      "destructuring": "any",
      "ignoreReadBeforeAssign": true
    }]
  }
}

Multiple Options

Rules can accept multiple option values:
{
  rules: {
    "quotes": ["error", "double", {
      "avoidEscape": true,
      "allowTemplateLiterals": true
    }],
    
    "indent": ["error", 2, {
      "SwitchCase": 1,
      "VariableDeclarator": "first"
    }]
  }
}

Common Rule Examples

{
  rules: {
    // Always require semicolons
    "semi": ["error", "always"],
    
    // Never allow semicolons
    "semi": ["error", "never"],
    
    // With options
    "semi": ["error", "never", {
      "beforeStatementContinuationChars": "always"
    }]
  }
}
Examples:
// "always"
const x = 5;  // ✅
const y = 10  // ❌

// "never"
const x = 5;  // ❌
const y = 10  // ✅
{
  rules: {
    // Double quotes
    "quotes": ["error", "double"],
    
    // Single quotes
    "quotes": ["error", "single"],
    
    // Backticks
    "quotes": ["error", "backtick"],
    
    // With options
    "quotes": ["error", "double", {
      "avoidEscape": true,
      "allowTemplateLiterals": true
    }]
  }
}
Examples:
// "double"
const msg = "hello";  // ✅
const msg = 'hello';  // ❌

// "single"
const msg = 'hello';  // ✅
const msg = "hello";  // ❌
{
  rules: {
    "no-unused-vars": ["error", {
      "vars": "all",           // Check all variables
      "args": "after-used",     // Check args after last used
      "ignoreRestSiblings": true,
      "argsIgnorePattern": "^_", // Ignore args starting with _
      "varsIgnorePattern": "^_",  // Ignore vars starting with _
      "caughtErrors": "all"
    }]
  }
}
Examples:
// Error: x is defined but never used
const x = 5;

// OK: _x starts with underscore (ignored)
const _x = 5;

// OK: Used in return
const y = 10;
return y;
{
  rules: {
    "prefer-const": ["error", {
      "destructuring": "any",  // "any" or "all"
      "ignoreReadBeforeAssign": false
    }]
  }
}
Examples:
// Error: Never reassigned, use const
let x = 5;
console.log(x);

// OK: Reassigned
let y = 5;
y = 10;

// OK: Use const
const z = 5;
console.log(z);
{
  rules: {
    "max-len": ["error", {
      "code": 80,
      "tabWidth": 2,
      "comments": 100,
      "ignoreUrls": true,
      "ignoreStrings": true,
      "ignoreTemplateLiterals": true,
      "ignoreRegExpLiterals": true
    }]
  }
}
{
  rules: {
    "indent": ["error", 2, {
      "SwitchCase": 1,
      "VariableDeclarator": "first",
      "FunctionDeclaration": {
        "parameters": "first",
        "body": 1
      },
      "ArrayExpression": "first",
      "ObjectExpression": "first"
    }]
  }
}
Options:
  • 2 or 4 - Number of spaces
  • "tab" - Use tabs

Inline Configuration Comments

Configure Rules Inline

Set rule configuration for a portion of a file:
/* eslint quotes: ["error", "double"], curly: 2 */

function example() {
  const msg = "hello";  // Must use double quotes
}

With Descriptions

Add descriptions to explain why configuration is needed:
/* eslint eqeqeq: "off", curly: "error" -- 
   Disable eqeqeq for legacy code compatibility */

if (x == null) { } // OK
The description must:
  • Come after the configuration
  • Be separated by two or more consecutive - characters

Disabling Rules

Disable All Rules

/* eslint-disable */

alert("foo");  // No rules apply
console.log("bar");

/* eslint-enable */

Disable Specific Rules

/* eslint-disable no-alert, no-console */

alert("foo");
console.log("bar");

/* eslint-enable no-alert, no-console */

Disable vs Turn Off

Temporary Disable
/* eslint-disable no-console */
console.log("debug");
/* eslint-enable no-console */

console.log("error");  // Rule applies again
Use for temporarily disabling rules in specific code sections.
Use disable comments with caution:
  • Document the reason with a description
  • Prefer configuration files over inline comments
  • Create follow-up tasks for temporary disables
  • Review disable comments during code reviews

Rules from Plugins

When using plugin rules, prefix the rule ID with the plugin namespace:
import reactPlugin from "eslint-plugin-react";
import typescriptPlugin from "@typescript-eslint/eslint-plugin";
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    files: ["**/*.jsx"],
    plugins: {
      react: reactPlugin
    },
    rules: {
      // Format: "plugin-namespace/rule-name"
      "react/jsx-uses-react": "error",
      "react/jsx-uses-vars": "error",
      "react/prop-types": "warn"
    }
  },
  {
    files: ["**/*.ts"],
    plugins: {
      "@typescript-eslint": typescriptPlugin
    },
    rules: {
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/explicit-function-return-type": "off"
    }
  }
]);

In Configuration Comments

/* eslint "react/jsx-uses-react": "error" */

import React from 'react';
Plugins must be loaded in the configuration file before their rules can be used in comments.

Rule Cascading

When multiple configuration objects match a file, their rules are merged:
export default [
  {
    files: ["**/*.js"],
    rules: {
      "semi": ["error", "never"],
      "quotes": ["error", "single"]
    }
  },
  {
    files: ["**/*.js"],
    rules: {
      "semi": ["warn", "always"],  // Overrides previous
      "no-console": "off"            // Adds new rule
    }
  }
];

// Final configuration for .js files:
// {
//   "semi": ["warn", "always"],
//   "quotes": ["error", "single"],
//   "no-console": "off"
// }

Partial Override

You can override just the severity while keeping options:
export default [
  {
    rules: {
      "semi": ["error", "never"]
    }
  },
  {
    rules: {
      "semi": "warn"  // Only changes severity to warn
    }
  }
];

// Result: ["warn", "never"]

Disabling Inline Configuration

Prevent inline comments from modifying configuration:
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    linterOptions: {
      noInlineConfig: true
    },
    rules: {
      "no-unused-expressions": "error"
    }
  }
]);
With this setting, these comments are ignored:
  • /*eslint-disable*/
  • /*eslint-enable*/
  • /*global*/
  • /*eslint*/
  • // eslint-disable-line
  • // eslint-disable-next-line

Reporting Unused Directives

Unused Disable Directives

Report eslint-disable comments that don’t disable any violations:
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    linterOptions: {
      reportUnusedDisableDirectives: "error"
    }
  }
]);
// This line would not trigger no-console,
// so the disable comment is unnecessary
/* eslint-disable-next-line no-console */
const x = 5;
Default: "warn" Options: "off", "warn", "error" (or 0, 1, 2)

Unused Inline Configs

Report inline config comments that match the current configuration:
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    linterOptions: {
      reportUnusedInlineConfigs: "warn"
    },
    rules: {
      "semi": "error"
    }
  }
]);
// Unnecessary - semi is already "error" in config
/* eslint semi: "error" */
Default: "off" Options: "off", "warn", "error" (or 0, 1, 2)

File-Specific Rules

Apply different rules to different file patterns:
export default [
  // Base rules for all JS files
  {
    files: ["**/*.js"],
    rules: {
      "no-console": "error",
      "prefer-const": "error"
    }
  },
  
  // Relax rules for test files
  {
    files: ["**/*.test.js", "**/*.spec.js"],
    rules: {
      "no-console": "off",
      "no-unused-expressions": "off"
    }
  },
  
  // Strict rules for production code
  {
    files: ["src/**/*.js"],
    ignores: ["**/*.test.js"],
    rules: {
      "no-console": "error",
      "no-debugger": "error",
      "complexity": ["error", 10]
    }
  }
];

Complete Example

eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import reactPlugin from "eslint-plugin-react";

export default defineConfig([
  // Base configuration
  {
    files: ["**/*.js", "**/*.jsx"],
    plugins: { js },
    extends: ["js/recommended"],
    linterOptions: {
      reportUnusedDisableDirectives: "warn",
      reportUnusedInlineConfigs: "warn"
    },
    rules: {
      // Error level rules
      "no-unused-vars": ["error", {
        "argsIgnorePattern": "^_",
        "varsIgnorePattern": "^_"
      }],
      "semi": ["error", "always"],
      "quotes": ["error", "double"],
      
      // Warning level rules
      "no-console": "warn",
      "prefer-const": "warn",
      
      // Disabled rules
      "no-debugger": "off",
      "max-len": "off"
    }
  },
  
  // React-specific configuration
  {
    files: ["**/*.jsx"],
    plugins: {
      react: reactPlugin
    },
    rules: {
      "react/jsx-uses-react": "error",
      "react/jsx-uses-vars": "error",
      "react/prop-types": "warn"
    }
  },
  
  // Test files configuration
  {
    files: ["**/*.test.js", "**/*.spec.js"],
    rules: {
      "no-console": "off",
      "no-unused-expressions": "off",
      "max-lines-per-function": "off"
    }
  }
]);

Best Practices

Establish team conventions:
  • Error: Must fix (runtime issues, security, critical)
  • Warn: Should fix (code smells, best practices)
  • Off: Not applicable
Add comments explaining non-obvious choices:
{
  rules: {
    // Allow console in development
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
    
    // Team prefers single quotes
    "quotes": ["error", "single"],
    
    // Disabled due to false positives with TypeScript
    "no-undef": "off"
  }
}
Prefer configuration files over inline comments:
// ❌ Bad
function test() {
  /* eslint-disable no-console */
  console.log("test");
  /* eslint-enable no-console */
}

// ✅ Good - in config file
{
  files: ["**/*.test.js"],
  rules: {
    "no-console": "off"
  }
}
Regularly review and address:
  • Unused disable directives
  • Frequently disabled rules
  • Rules with many violations
  • Outdated rule configurations

Configuration

Learn about configuration files and objects

Core Concepts

Understanding rules, plugins, and more

Command Line

CLI options including —rule

Built-in Rules

Browse all available ESLint rules

Build docs developers (and LLMs) love