Skip to main content

Configuration

You can configure ESLint using a configuration file that specifies built-in rules, plugins, custom rules, shareable configurations, and more.

Configuration File

The ESLint configuration file can be named any of the following:

eslint.config.js

CommonJS or ESM

eslint.config.mjs

ESM only

eslint.config.cjs

CommonJS only

eslint.config.ts

TypeScript

eslint.config.mts

TypeScript ESM

eslint.config.cts

TypeScript CJS
TypeScript configuration files require additional setup (see TypeScript Configuration below).
Place the configuration file in the root directory of your project and export an array of configuration objects:
eslint.config.js
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    rules: {
      semi: "error",
      "prefer-const": "error",
    },
  },
]);
eslint.config.js
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    rules: {
      semi: "error",
      "prefer-const": "error",
    },
  },
]);
If your project does not specify "type":"module" in package.json, then eslint.config.js must be in CommonJS format.

Configuration Objects

Each configuration object contains all the information ESLint needs to execute on a set of files. Configuration objects are made up of these properties:
A name for the configuration object. Used in error messages and config inspector.
{
  name: "my-config/recommended",
  rules: { /* ... */ }
}
Array of glob patterns indicating which files the configuration applies to.
{
  files: ["**/*.js", "**/*.mjs"],
  rules: { /* ... */ }
}
Array of glob patterns indicating files to exclude.
{
  files: ["src/**/*.js"],
  ignores: ["**/*.config.js"],
  rules: { /* ... */ }
}
Settings for how JavaScript is configured for linting.
{
  languageOptions: {
    ecmaVersion: 2024,
    sourceType: "module",
    globals: {
      myCustomGlobal: "readonly"
    },
    parser: customParser,
    parserOptions: { /* ... */ }
  }
}
Properties:
  • ecmaVersion - ECMAScript version (year or version number, or "latest")
  • sourceType - "script", "module", or "commonjs"
  • globals - Additional global variables
  • parser - Custom parser object
  • parserOptions - Options for the parser
Settings for the linting process.
{
  linterOptions: {
    noInlineConfig: true,
    reportUnusedDisableDirectives: "error",
    reportUnusedInlineConfigs: "warn"
  }
}
Processor for extracting JavaScript from other file types.
{
  processor: "pluginName/processorName"
}
Plugins to load (name-value mapping).
import examplePlugin from "eslint-plugin-example";

export default [
  {
    plugins: {
      example: examplePlugin
    }
  }
];
Configured rules.
{
  rules: {
    semi: "error",
    "no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
    "prefer-const": "warn"
  }
}
Shared settings available to all rules.
{
  settings: {
    sharedData: "Hello"
  }
}

Files and Patterns

Specify Files

Use the files property to specify which files a configuration applies to:
export default defineConfig([
  {
    // Matches all .js files
    files: ["**/*.js"],
    rules: {
      semi: "error"
    }
  },
  {
    // Matches TypeScript files
    files: ["**/*.ts", "**/*.tsx"],
    rules: {
      "@typescript-eslint/no-explicit-any": "warn"
    }
  }
]);
Patterns use minimatch syntax and are evaluated relative to the eslint.config.js file location.

Files Without Extensions

Match files without extensions using the !(*.*) pattern:
{
  files: ["**/!(*.*)"]
}

Multiple Pattern Matching (AND)

Match files against multiple patterns:
{
  // Matches files that are BOTH in src/ AND end with .js
  files: [["src/*", "**/*.js"]]
}

Exclude Files with Ignores

Limit which files a configuration applies to:
export default defineConfig([
  {
    files: ["src/**/*.js"],
    ignores: ["**/*.config.js"],
    rules: {
      semi: "error"
    }
  }
]);
Use negation patterns to re-include files:
{
  files: ["src/**/*.js"],
  ignores: ["**/*.config.js", "!**/eslint.config.js"],
  rules: { semi: "error" }
}

Global Ignores

Ignore files across all configurations using globalIgnores():
import { defineConfig, globalIgnores } from "eslint/config";

export default defineConfig([
  globalIgnores([".config/", "dist/", "tsconfig.json"]),
  {
    rules: { /* ... */ }
  }
]);
Default ignore patterns are ["**/node_modules/", ".git/"].

Global vs Non-Global Ignores

// Acts as global ignores (no other keys)
export default defineConfig([
  globalIgnores([".config/", "dist/"]),
  { rules: { /* ... */ } }
]);
  • Applies to every configuration object
  • Can match directories: "dir/"

Cascading Configuration

When multiple configuration objects match a file, they are merged with later objects overriding previous ones:
export default defineConfig([
  {
    files: ["**/*.js"],
    languageOptions: {
      globals: {
        MY_CUSTOM_GLOBAL: "readonly"
      }
    }
  },
  {
    files: ["tests/**/*.js"],
    languageOptions: {
      globals: {
        it: "readonly",
        describe: "readonly"
      }
    }
  }
]);
For test files, both configurations apply, merging the globals together.

Language Options

Configure how ESLint parses JavaScript:
export default defineConfig([
  {
    languageOptions: {
      // ECMAScript version
      ecmaVersion: 2024, // or "latest"
      
      // Source type
      sourceType: "module", // "script", "module", or "commonjs"
      
      // Global variables
      globals: {
        myGlobal: "readonly",
        anotherGlobal: "writable"
      },
      
      // Custom parser
      parser: await import("@typescript-eslint/parser"),
      
      // Parser options
      parserOptions: {
        ecmaFeatures: {
          jsx: true
        }
      }
    }
  }
]);
Default values:
  • ecmaVersion: "latest"
  • sourceType: "module" for .js and .mjs, "commonjs" for .cjs
  • parser: espree (built-in)

Extending Configurations

Use extends to inherit from other configurations:
import examplePlugin from "eslint-plugin-example";
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    files: ["**/*.js"],
    plugins: {
      example: examplePlugin
    },
    extends: ["example/recommended"],
    rules: {
      "no-unused-vars": "warn" // Override extended rules
    }
  }
]);

Predefined Configurations

ESLint provides two predefined configurations:
import js from "@eslint/js";
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    files: ["**/*.js"],
    plugins: { js },
    extends: ["js/recommended"],
    rules: {
      "no-unused-vars": "warn"
    }
  }
]);
Enables recommended rules to avoid potential errors.

Shareable Configurations

Use npm packages that export configurations:
import exampleConfig from "eslint-config-example";
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    files: ["**/*.js"],
    extends: [exampleConfig],
    rules: {
      "no-unused-vars": "warn"
    }
  }
]);

Base Path

Apply configuration to a specific subdirectory:
export default defineConfig([
  {
    basePath: "tests",
    rules: {
      "no-undef": "error"
    }
  },
  {
    basePath: "tests",
    files: ["**/*.spec.js"],
    languageOptions: {
      globals: {
        it: "readonly",
        describe: "readonly"
      }
    }
  }
]);

TypeScript Configuration

For TypeScript configuration files:
1

Install jiti

For Node.js, install the optional jiti dependency:
npm install --save-dev jiti
Deno and Bun support TypeScript natively and don’t require jiti.
2

Create TypeScript config

Create a config file with .ts, .mts, or .cts extension:
eslint.config.ts
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    rules: {
      semi: "error"
    }
  }
]);
3

Native Node.js Support (Experimental)

For Node.js >= 22.13.0, use the experimental native TypeScript support:
npx --node-options='--experimental-strip-types' eslint \
  --flag unstable_native_nodejs_ts_config
ESLint does not perform type checking on your configuration file and does not apply settings from tsconfig.json.

Configuration Naming

Provide names for configuration objects to help with debugging:
export default defineConfig([
  {
    name: "my-project/base",
    rules: {
      semi: "error"
    }
  },
  {
    name: "my-project/typescript",
    files: ["**/*.ts"],
    rules: {
      "@typescript-eslint/no-explicit-any": "warn"
    }
  }
]);
Use / as a separator to scope names: "plugin-name/config-name"

Complete Example

eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
import js from "@eslint/js";
import typescriptPlugin from "@typescript-eslint/eslint-plugin";
import typescriptParser from "@typescript-eslint/parser";

export default defineConfig([
  // Global ignores
  globalIgnores(["dist/", "build/", "*.config.js"]),
  
  // Base configuration for all JS files
  {
    name: "base-js",
    files: ["**/*.js", "**/*.mjs"],
    plugins: { js },
    extends: ["js/recommended"],
    languageOptions: {
      ecmaVersion: 2024,
      sourceType: "module",
      globals: {
        console: "readonly",
        process: "readonly"
      }
    },
    rules: {
      "no-unused-vars": "warn",
      "prefer-const": "error",
      semi: ["error", "always"]
    }
  },
  
  // TypeScript configuration
  {
    name: "typescript",
    files: ["**/*.ts", "**/*.tsx"],
    plugins: {
      "@typescript-eslint": typescriptPlugin
    },
    languageOptions: {
      parser: typescriptParser,
      parserOptions: {
        project: "./tsconfig.json"
      }
    },
    rules: {
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/explicit-function-return-type": "off"
    }
  },
  
  // Test files configuration
  {
    name: "tests",
    files: ["**/*.test.js", "**/*.spec.js"],
    languageOptions: {
      globals: {
        describe: "readonly",
        it: "readonly",
        expect: "readonly"
      }
    },
    rules: {
      "no-unused-expressions": "off"
    }
  }
]);

Rule Configuration

Learn how to configure individual rules

Ignoring Code

Configure files and patterns to ignore

Core Concepts

Understanding parsers, plugins, and more

Command Line

CLI options and flags