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
Place the configuration file in the root directory of your project and export an array of configuration objects:
import { defineConfig } from "eslint/config" ;
export default defineConfig ([
{
rules: {
semi: "error" ,
"prefer-const" : "error" ,
} ,
},
]) ;
import { defineConfig } from "eslint/config" ;
export default defineConfig ([
{
rules: {
semi: "error" ,
"prefer-const" : "error" ,
} ,
},
]) ;
const { defineConfig } = require ( "eslint/config" );
module . exports = 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:
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/"
// Acts as non-global (has other keys)
export default defineConfig ([
{
ignores: [ ".config/**" , "dir1/script1.js" ] ,
rules: { /* ... */ }
}
]) ;
Only applies to this configuration object
Can only match files or files within directories
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. import js from "@eslint/js" ;
import { defineConfig } from "eslint/config" ;
export default defineConfig ([
{
files: [ "**/*.js" ] ,
plugins: { js } ,
extends: [ "js/all" ]
}
]) ;
Enables ALL built-in rules. Not recommended for production - changes with every minor/major version.
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:
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.
Create TypeScript config
Create a config file with .ts, .mts, or .cts extension: import { defineConfig } from "eslint/config" ;
export default defineConfig ([
{
rules: {
semi: "error"
}
}
]) ;
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
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