new RegExp("\\t"); // allowed since the pattern is: \t
```
There is no difference in behavior between `new RegExp("\t")` and `new RegExp("\\t")`, and the intention to match the TAB character is clear in both cases. They are equally valid for the purpose of this rule, but it only allows `new RegExp("\\t")`.
## When Not To Use It
If you need to use control character pattern matching, then you should turn this rule off.
---
---
title: no-debugger
rule_type: problem
related_rules:
- no-alert
- no-console
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
---
The `debugger` statement is used to tell the executing JavaScript environment to stop execution and start up a debugger at the current point in the code. This has fallen out of favor as a good practice with the advent of modern debugging and development tools. Production code should definitely not contain `debugger`, as it will cause the browser to stop executing code and open an appropriate debugger.
## Rule Details
This rule disallows `debugger` statements.
Example of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-debugger: "error"*/
function isTruthy(x) {
debugger;
return Boolean(x);
}
```
:::
Example of **correct** code for this rule:
::: correct
```js
/*eslint no-debugger: "error"*/
function isTruthy(x) {
return Boolean(x); // set a breakpoint at this line
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If your code is still very much in development and don't want to worry about stripping `debugger` statements, then turn this rule off. You'll generally want to turn it back on when testing code prior to deployment.
---
---
title: no-delete-var
rule_type: suggestion
---
The purpose of the `delete` operator is to remove a property from an object. Using the `delete` operator on a variable might lead to unexpected behavior.
## Rule Details
This rule disallows the use of the `delete` operator on variables.
If ESLint parses code in strict mode, the parser (instead of this rule) reports the error.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-delete-var: "error"*/
let x;
delete x;
```
:::
## Options
This rule has no options.
---
---
title: no-div-regex
rule_type: suggestion
related_rules:
- no-control-regex
- no-regex-spaces
---
Characters `/=` at the beginning of a regular expression literal can be confused with a division assignment operator.
```js
function bar() { return /=foo/; }
```
## Rule Details
This rule forbids equal signs (`=`) after the slash (`/`) at the beginning of a regular expression literal, because the characters `/=` can be confused with a division assignment operator.
Examples of **incorrect** code for this rule:
:::incorrect
```js
/*eslint no-div-regex: "error"*/
function bar() { return /=foo/; }
```
:::
Examples of **correct** code for this rule:
:::correct
```js
/*eslint no-div-regex: "error"*/
function bar() { return /[=]foo/; }
```
:::
## Options
This rule has no options.
---
---
title: no-dupe-args
rule_type: problem
handled_by_typescript: true
---
If more than one parameter has the same name in a function definition, the last occurrence "shadows" the preceding occurrences. A duplicated name might be a typing error.
## Rule Details
This rule disallows duplicate parameter names in function declarations or expressions. It does not apply to arrow functions or class methods, because the parser reports the error.
If ESLint parses code in strict mode, the parser (instead of this rule) reports the error.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-dupe-args: "error"*/
function foo(a, b, a) {
console.log("value of the second a:", a);
}
const bar = function (a, b, a) {
console.log("value of the second a:", a);
};
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-dupe-args: "error"*/
function foo(a, b, c) {
console.log(a, b, c);
}
const bar = function (a, b, c) {
console.log(a, b, c);
};
```
:::
## Options
This rule has no options.
---
---
title: no-dupe-class-members
rule_type: problem
handled_by_typescript: true
---
If there are declarations of the same name in class members, the last declaration overwrites other declarations silently.
It can cause unexpected behaviors.
```js
class Foo {
bar() { console.log("hello"); }
bar() { console.log("goodbye"); }
}
const foo = new Foo();
foo.bar(); // goodbye
```
## Rule Details
This rule is aimed to flag the use of duplicate names in class members.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-dupe-class-members: "error"*/
class A {
bar() { }
bar() { }
}
class B {
bar() { }
get bar() { }
}
class C {
bar;
bar;
}
class D {
bar;
bar() { }
}
class E {
static bar() { }
static bar() { }
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-dupe-class-members: "error"*/
class A {
bar() { }
qux() { }
}
class B {
get bar() { }
set bar(value) { }
}
class C {
bar;
qux;
}
class D {
bar;
qux() { }
}
class E {
static bar() { }
bar() { }
}
```
:::
This rule additionally supports TypeScript type syntax. It has support for TypeScript's method overload definitions.
Examples of **correct** TypeScript code for this rule:
::: correct
```ts
/* eslint no-dupe-class-members: "error" */
class A {
foo(value: string): void;
foo(value: number): void;
foo(value: string | number) {} // ✅ This is the actual implementation.
}
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
In ES2015 (ES6) or later, if you don't want to be notified about duplicate names in class members, you can safely disable this rule.
---
---
title: no-dupe-else-if
rule_type: problem
related_rules:
- no-duplicate-case
- no-lonely-if
---
`if-else-if` chains are commonly used when there is a need to execute only one branch (or at most one branch) out of several possible branches, based on certain conditions.
```js
if (a) {
foo();
} else if (b) {
bar();
} else if (c) {
baz();
}
```
Two identical test conditions in the same chain are almost always a mistake in the code. Unless there are side effects in the expressions, a duplicate will evaluate to the same `true` or `false` value as the identical expression earlier in the chain, meaning that its branch can never execute.
```js
if (a) {
foo();
} else if (b) {
bar();
} else if (b) {
baz();
}
```
In the above example, `baz()` can never execute. Obviously, `baz()` could be executed only when `b` evaluates to `true`, but in that case `bar()` would be executed instead, since it's earlier in the chain.
## Rule Details
This rule disallows duplicate conditions in the same `if-else-if` chain.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-dupe-else-if: "error"*/
if (isSomething(x)) {
foo();
} else if (isSomething(x)) {
bar();
}
if (a) {
foo();
} else if (b) {
bar();
} else if (c && d) {
baz();
} else if (c && d) {
quux();
} else {
quuux();
}
if (n === 1) {
foo();
} else if (n === 2) {
bar();
} else if (n === 3) {
baz();
} else if (n === 2) {
quux();
} else if (n === 5) {
quuux();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-dupe-else-if: "error"*/
if (isSomething(x)) {
foo();
} else if (isSomethingElse(x)) {
bar();
}
if (a) {
foo();
} else if (b) {
bar();
} else if (c && d) {
baz();
} else if (c && e) {
quux();
} else {
quuux();
}
if (n === 1) {
foo();
} else if (n === 2) {
bar();
} else if (n === 3) {
baz();
} else if (n === 4) {
quux();
} else if (n === 5) {
quuux();
}
```
:::
This rule can also detect some cases where the conditions are not identical, but the branch can never execute due to the logic of `||` and `&&` operators.
Examples of additional **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-dupe-else-if: "error"*/
if (a || b) {
foo();
} else if (a) {
bar();
}
if (a) {
foo();
} else if (b) {
bar();
} else if (a || b) {
baz();
}
if (a) {
foo();
} else if (a && b) {
bar();
}
if (a && b) {
foo();
} else if (a && b && c) {
bar();
}
if (a || b) {
foo();
} else if (b && c) {
bar();
}
if (a) {
foo();
} else if (b && c) {
bar();
} else if (d && (c && e && b || a)) {
baz();
}
```
:::
Please note that this rule does not compare conditions from the chain with conditions inside statements, and will not warn in the cases such as follows:
```js
if (a) {
if (a) {
foo();
}
}
if (a) {
foo();
} else {
if (a) {
bar();
}
}
```
## Options
This rule has no options.
## When Not To Use It
In rare cases where you really need identical test conditions in the same chain, which necessarily means that the expressions in the chain are causing and relying on side effects, you will have to turn this rule off.
---
---
title: no-dupe-keys
rule_type: problem
handled_by_typescript: true
---
Multiple properties with the same key in object literals can cause unexpected behavior in your application.
```js
const foo = {
bar: "baz",
bar: "qux"
};
```
## Rule Details
This rule disallows duplicate keys in object literals.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-dupe-keys: "error"*/
const foo = {
bar: "baz",
bar: "qux"
};
const bar = {
"bar": "baz",
bar: "qux"
};
const baz = {
0x1: "baz",
1: "qux"
};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-dupe-keys: "error"*/
const foo = {
bar: "baz",
quxx: "qux"
};
const obj = {
"__proto__": baz, // defines object's prototype
["__proto__"]: qux // defines a property named "__proto__"
};
```
:::
## Options
This rule has no options.
---
---
title: no-duplicate-case
rule_type: problem
---
If a `switch` statement has duplicate test expressions in `case` clauses, it is likely that a programmer copied a `case` clause but forgot to change the test expression.
## Rule Details
This rule disallows duplicate test expressions in `case` clauses of `switch` statements.
Examples of **incorrect** code for this rule:
:::incorrect
```js
/*eslint no-duplicate-case: "error"*/
const a = 1,
one = 1;
switch (a) {
case 1:
break;
case 2:
break;
case 1: // duplicate test expression
break;
default:
break;
}
switch (a) {
case one:
break;
case 2:
break;
case one: // duplicate test expression
break;
default:
break;
}
switch (a) {
case "1":
break;
case "2":
break;
case "1": // duplicate test expression
break;
default:
break;
}
```
:::
Examples of **correct** code for this rule:
:::correct
```js
/*eslint no-duplicate-case: "error"*/
const a = 1,
one = 1;
switch (a) {
case 1:
break;
case 2:
break;
case 3:
break;
default:
break;
}
switch (a) {
case one:
break;
case 2:
break;
case 3:
break;
default:
break;
}
switch (a) {
case "1":
break;
case "2":
break;
case "3":
break;
default:
break;
}
```
:::
## Options
This rule has no options.
## When Not To Use It
In rare cases where identical test expressions in `case` clauses produce different values, which necessarily means that the expressions are causing and relying on side effects, you will have to disable this rule.
```js
switch (a) {
case i++:
foo();
break;
case i++: // eslint-disable-line no-duplicate-case
bar();
break;
}
```
---
---
title: no-duplicate-imports
rule_type: problem
---
Using a single `import` statement per module will make the code clearer because you can see everything being imported from that module on one line.
In the following example the `module` import on line 1 is repeated on line 3. These can be combined to make the list of imports more succinct.
```js
import { merge } from 'module';
import something from 'another-module';
import { find } from 'module';
```
## Rule Details
This rule requires that all imports from a single module that can be merged exist in a single `import` statement.
Example of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-duplicate-imports: "error"*/
import { merge } from 'module';
import something from 'another-module';
import { find } from 'module';
```
:::
Example of **correct** code for this rule:
::: correct
```js
/*eslint no-duplicate-imports: "error"*/
import { merge, find } from 'module';
import something from 'another-module';
```
:::
Example of **correct** code for this rule:
::: correct
```js
/*eslint no-duplicate-imports: "error"*/
// not mergeable
import { merge } from 'module';
import * as something from 'module';
```
:::
## Options
This rule has an object option:
* `"includeExports"`: `true` (default `false`) checks for exports in addition to imports.
* `"allowSeparateTypeImports"`: `true` (default `false`) allows a type import alongside a value import from the same module in TypeScript files.
### includeExports
If re-exporting from an imported module, you should add the imports to the `import`-statement, and export that directly, not use `export ... from`.
Example of **incorrect** code for this rule with the `{ "includeExports": true }` option:
::: incorrect
```js
/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/
import { merge } from 'module';
export { find } from 'module';
```
:::
Example of **correct** code for this rule with the `{ "includeExports": true }` option:
::: correct
```js
/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/
import { merge, find } from 'module';
export { find };
```
:::
Example of **correct** code for this rule with the `{ "includeExports": true }` option:
::: correct
```js
/*eslint no-duplicate-imports: ["error", { "includeExports": true }]*/
import { merge, find } from 'module';
// cannot be merged with the above import
export * as something from 'module';
// cannot be written differently
export * from 'module';
```
:::
### allowSeparateTypeImports
TypeScript allows importing types using `import type`. By default, this rule flags instances of `import type` that have the same specifier as `import`. The `allowSeparateTypeImports` option allows you to override this behavior.
Example of **incorrect** TypeScript code for this rule with the default `{ "allowSeparateTypeImports": false }` option:
::: incorrect
```ts
/*eslint no-duplicate-imports: ["error", { "allowSeparateTypeImports": false }]*/
import { someValue } from 'module';
import type { SomeType } from 'module';
```
:::
Example of **correct** TypeScript code for this rule with the default `{ "allowSeparateTypeImports": false }` option:
::: correct
```ts
/*eslint no-duplicate-imports: ["error", { "allowSeparateTypeImports": false }]*/
import { someValue, type SomeType } from 'module';
```
:::
Example of **incorrect** TypeScript code for this rule with the `{ "allowSeparateTypeImports": true }` option:
::: incorrect
```ts
/*eslint no-duplicate-imports: ["error", { "allowSeparateTypeImports": true }]*/
import { someValue } from 'module';
import type { SomeType } from 'module';
import type { AnotherType } from 'module';
```
:::
Example of **correct** TypeScript code for this rule with the `{ "allowSeparateTypeImports": true }` option:
::: correct
```ts
/*eslint no-duplicate-imports: ["error", { "allowSeparateTypeImports": true }]*/
import { someValue } from 'module';
import type { SomeType, AnotherType } from 'module';
```
:::
---
---
title: no-else-return
rule_type: suggestion
---
If an `if` block contains a `return` statement, the `else` block becomes unnecessary. Its contents can be placed outside of the block.
```js
function foo() {
if (x) {
return y;
} else {
return z;
}
}
```
## Rule Details
This rule is aimed at highlighting an unnecessary block of code following an `if` containing a `return` statement. As such, it will warn when it encounters an `else` following a chain of `if`s, all of them containing a `return` statement.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-else-return: "error"*/
function foo1() {
if (x) {
return y;
} else {
return z;
}
}
function foo2() {
if (x) {
return y;
} else {
const t = "foo";
}
}
function foo3() {
if (error) {
return 'It failed';
} else {
if (loading) {
return "It's still loading";
}
}
}
// Two warnings for nested occurrences
function foo4() {
if (x) {
if (y) {
return y;
} else {
return x;
}
} else {
return z;
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-else-return: "error"*/
function foo1() {
if (x) {
return y;
}
return z;
}
function foo2() {
if (x) {
return y;
}
const t = "foo";
}
function foo3() {
if (error) {
return 'It failed';
}
if (loading) {
return "It's still loading";
}
}
function foo4() {
if (x) {
if (y) {
return y;
}
return x;
}
return z;
}
function foo5() {
if (x) {
const t = "foo";
} else {
return y
}
}
```
:::
## Options
### allowElseIf
This rule has an object option:
* `allowElseIf: true` (default) - If true, allows `else if` blocks after a `return`
Examples of **correct** code for the default `{"allowElseIf": true}` option:
::: correct
```js
/*eslint no-else-return: ["error", {allowElseIf: true}]*/
function foo() {
if (error) {
return 'It failed';
} else if (loading) {
return "It's still loading";
}
}
// Using multiple `if` statements instead of `else if` is also allowed
function foo2() {
if (error) {
return 'It failed';
}
if (loading) {
return "It's still loading";
}
}
```
:::
Examples of **incorrect** code for the `{"allowElseIf": false}` option:
::: incorrect
```js
/*eslint no-else-return: ["error", {allowElseIf: false}]*/
function foo() {
if (error) {
return 'It failed';
} else if (loading) {
return "It's still loading";
}
}
```
:::
Examples of **correct** code for the `{"allowElseIf": false}` option:
::: correct
```js
/*eslint no-else-return: ["error", {allowElseIf: false}]*/
function foo() {
if (error) {
return 'It failed';
}
if (loading) {
return "It's still loading";
}
}
```
:::
---
---
title: no-empty-character-class
rule_type: problem
---
Because empty character classes in regular expressions do not match anything, they might be typing mistakes.
```js
const foo = /^abc[]/;
```
## Rule Details
This rule disallows empty character classes in regular expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty-character-class: "error"*/
/^abc[]/.test("abcdefg"); // false
"abcdefg".match(/^abc[]/); // null
/^abc[[]]/v.test("abcdefg"); // false
"abcdefg".match(/^abc[[]]/v); // null
/^abc[[]--[x]]/v.test("abcdefg"); // false
"abcdefg".match(/^abc[[]--[x]]/v); // null
/^abc[[d]&&[]]/v.test("abcdefg"); // false
"abcdefg".match(/^abc[[d]&&[]]/v); // null
const regex = /^abc[d[]]/v;
regex.test("abcdefg"); // true, the nested `[]` has no effect
"abcdefg".match(regex); // ["abcd"]
regex.test("abcefg"); // false, the nested `[]` has no effect
"abcefg".match(regex); // null
regex.test("abc"); // false, the nested `[]` has no effect
"abc".match(regex); // null
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-empty-character-class: "error"*/
/^abc/.test("abcdefg"); // true
"abcdefg".match(/^abc/); // ["abc"]
/^abc[a-z]/.test("abcdefg"); // true
"abcdefg".match(/^abc[a-z]/); // ["abcd"]
/^abc[^]/.test("abcdefg"); // true
"abcdefg".match(/^abc[^]/); // ["abcd"]
```
:::
## Options
This rule has no options.
## Known Limitations
This rule does not report empty character classes in the string argument of calls to the `RegExp` constructor.
Example of a *false negative* when this rule reports correct code:
```js
/*eslint no-empty-character-class: "error"*/
const abcNeverMatches = new RegExp("^abc[]");
```
---
---
title: no-empty-class
---
Disallows empty character classes in regular expressions.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [no-empty-character-class](no-empty-character-class) rule.
:::
Empty character classes in regular expressions do not match anything and can result in code that may not work as intended.
```js
var foo = /^abc[]/;
```
## Rule Details
This rule is aimed at highlighting possible typos and unexpected behavior in regular expressions which may arise from the use of empty character classes.
Examples of **incorrect** code for this rule:
::: incorrect
```js
var foo = /^abc[]/;
/^abc[]/.test(foo);
bar.match(/^abc[]/);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
var foo = /^abc/;
var foo = /^abc[a-z]/;
var bar = new RegExp("^abc[]");
```
:::
---
---
title: no-empty-function
rule_type: suggestion
related_rules:
- no-empty
---
Empty functions can reduce readability because readers need to guess whether it's intentional or not.
So writing a clear comment for empty functions is a good practice.
```js
function foo() {
// do nothing.
}
```
Especially, the empty block of arrow functions might be confusing developers.
It's very similar to an empty object literal.
```js
list.map(() => {}); // This is a block, would return undefined.
list.map(() => ({})); // This is an empty object.
```
## Rule Details
This rule is aimed at eliminating empty functions.
A function will not be considered a problem if it contains a comment.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty-function: "error"*/
function foo() {}
const bar = function() {};
const bar1 = () => {};
function* baz() {}
const bar2 = function*() {};
const obj = {
foo: function() {},
foo: function*() {},
foo() {},
*foo() {},
get foo() {},
set foo(value) {}
};
class A {
constructor() {}
foo() {}
*foo() {}
get foo() {}
set foo(value) {}
static foo() {}
static *foo() {}
static get foo() {}
static set foo(value) {}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-empty-function: "error"*/
function foo() {
// do nothing.
}
const baz = function() {
// any clear comments.
};
const baz1 = () => {
bar();
};
function* foobar() {
// do nothing.
}
const baz2 = function*() {
// do nothing.
};
const obj = {
foo: function() {
// do nothing.
},
foo: function*() {
// do nothing.
},
foo() {
// do nothing.
},
*foo() {
// do nothing.
},
get foo() {
// do nothing.
},
set foo(value) {
// do nothing.
}
};
class A {
constructor() {
// do nothing.
}
foo() {
// do nothing.
}
*foo() {
// do nothing.
}
get foo() {
// do nothing.
}
set foo(value) {
// do nothing.
}
static foo() {
// do nothing.
}
static *foo() {
// do nothing.
}
static get foo() {
// do nothing.
}
static set foo(value) {
// do nothing.
}
}
```
:::
## Options
This rule has an option to allow specific kinds of functions to be empty.
* `allow` (`string[]`) - A list of kind to allow empty functions. List items are some of the following strings. An empty array (`[]`) by default.
* `"functions"` - Normal functions.
* `"arrowFunctions"` - Arrow functions.
* `"generatorFunctions"` - Generator functions.
* `"methods"` - Class methods and method shorthands of object literals.
* `"generatorMethods"` - Class methods and method shorthands of object literals with generator.
* `"getters"` - Getters.
* `"setters"` - Setters.
* `"constructors"` - Class constructors.
* `"asyncFunctions"` - Async functions.
* `"asyncMethods"` - Async class methods and method shorthands of object literals.
* `"privateConstructors"` - Private class constructors. (TypeScript only)
* `"protectedConstructors"` - Protected class constructors. (TypeScript only)
* `"decoratedFunctions"` - Class methods with decorators. (TypeScript only)
* `"overrideMethods"` - Methods that use the override keyword. (TypeScript only)
### allow: functions
Examples of **correct** code for the `{ "allow": ["functions"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["functions"] }]*/
function foo() {}
const bar = function() {};
const obj = {
foo: function() {}
};
```
:::
### allow: arrowFunctions
Examples of **correct** code for the `{ "allow": ["arrowFunctions"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["arrowFunctions"] }]*/
const foo = () => {};
```
:::
### allow: generatorFunctions
Examples of **correct** code for the `{ "allow": ["generatorFunctions"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["generatorFunctions"] }]*/
function* foo() {}
const bar = function*() {};
const obj = {
foo: function*() {}
};
```
:::
### allow: methods
Examples of **correct** code for the `{ "allow": ["methods"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["methods"] }]*/
const obj = {
foo() {}
};
class A {
foo() {}
static foo() {}
}
```
:::
### allow: generatorMethods
Examples of **correct** code for the `{ "allow": ["generatorMethods"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["generatorMethods"] }]*/
const obj = {
*foo() {}
};
class A {
*foo() {}
static *foo() {}
}
```
:::
### allow: getters
Examples of **correct** code for the `{ "allow": ["getters"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["getters"] }]*/
const obj = {
get foo() {}
};
class A {
get foo() {}
static get foo() {}
}
```
:::
### allow: setters
Examples of **correct** code for the `{ "allow": ["setters"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["setters"] }]*/
const obj = {
set foo(value) {}
};
class A {
set foo(value) {}
static set foo(value) {}
}
```
:::
### allow: constructors
Examples of **correct** code for the `{ "allow": ["constructors"] }` option:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["constructors"] }]*/
class A {
constructor() {}
}
```
:::
### allow: asyncFunctions
Examples of **correct** code for the `{ "allow": ["asyncFunctions"] }` options:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["asyncFunctions"] }]*/
async function a(){}
```
:::
### allow: asyncMethods
Examples of **correct** code for the `{ "allow": ["asyncMethods"] }` options:
::: correct
```js
/*eslint no-empty-function: ["error", { "allow": ["asyncMethods"] }]*/
const obj = {
async foo() {}
};
class A {
async foo() {}
static async foo() {}
}
```
:::
### allow: privateConstructors
Examples of **correct** TypeScript code for the `{ "allow": ["privateConstructors"] }` option:
::: correct
```ts
/*eslint no-empty-function: ["error", { "allow": ["privateConstructors"] }]*/
class A {
private constructor() {}
}
```
:::
### allow: protectedConstructors
Examples of **correct** TypeScript code for the `{ "allow": ["protectedConstructors"] }` option:
::: correct
```ts
/*eslint no-empty-function: ["error", { "allow": ["protectedConstructors"] }]*/
class A {
protected constructor() {}
}
```
:::
### allow: decoratedFunctions
Examples of **correct** TypeScript code for the `{ "allow": ["decoratedFunctions"] }` option:
::: correct
```ts
/*eslint no-empty-function: ["error", { "allow": ["decoratedFunctions"] }]*/
class A {
@decorator
foo() {}
}
```
:::
### allow: overrideMethods
Examples of **correct** TypeScript code for the `{ "allow": ["overrideMethods"] }` option:
::: correct
```ts
/*eslint no-empty-function: ["error", { "allow": ["overrideMethods"] }]*/
abstract class Base {
abstract method(): void;
}
class Derived extends Base {
override method() {}
}
```
:::
## When Not To Use It
If you don't want to be notified about empty functions, then it's safe to disable this rule.
---
---
title: no-empty-label
related_rules:
- no-labels
- no-label-var
- no-unused-labels
---
Disallows labels for anything other than loops and switches.
::: important
This rule was removed in ESLint v2.0.0 and replaced by the [no-labels](no-labels) rule.
:::
Labeled statements are only used in conjunction with labeled break and continue statements. ECMAScript has no goto statement.
## Rule Details
This error occurs when a label is used to mark a statement that is not an iteration or switch
Example of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty-label: "error"*/
labeled:
var x = 10;
```
:::
Example of **correct** code for this rule:
::: correct
```js
/*eslint no-empty-label: "error"*/
labeled:
for (var i=10; i; i--) {
// ...
}
```
:::
## When Not To Use It
If you don't want to be notified about usage of labels, then it's safe to disable this rule.
---
---
title: no-empty-pattern
rule_type: problem
---
When using destructuring, it's possible to create a pattern that has no effect. This happens when empty curly braces are used to the right of an embedded object destructuring pattern, such as:
```js
// doesn't create any variables
const {a: {}} = foo;
```
In this code, no new variables are created because `a` is just a location helper while the `{}` is expected to contain the variables to create, such as:
```js
// creates variable b
const {a: { b }} = foo;
```
In many cases, the empty object pattern is a mistake where the author intended to use a default value instead, such as:
```js
// creates variable a
const {a = {}} = foo;
```
The difference between these two patterns is subtle, especially because the problematic empty pattern looks just like an object literal.
## Rule Details
This rule aims to flag any empty patterns in destructured objects and arrays, and as such, will report a problem whenever one is encountered.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty-pattern: "error"*/
const {} = foo;
const [] = foo;
const {a: {}} = foo;
const {a: []} = foo;
function foo({}) {}
function bar([]) {}
function baz({a: {}}) {}
function qux({a: []}) {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-empty-pattern: "error"*/
const {a = {}} = foo;
const {b = []} = foo;
function foo({a = {}}) {}
function bar({a = []}) {}
```
:::
## Options
This rule has an object option for exceptions:
### allowObjectPatternsAsParameters
Set to `false` by default. Setting this option to `true` allows empty object patterns as function parameters.
**Note:** This rule doesn't allow empty array patterns as function parameters.
Examples of **incorrect** code for this rule with the `{"allowObjectPatternsAsParameters": true}` option:
::: incorrect
```js
/*eslint no-empty-pattern: ["error", { "allowObjectPatternsAsParameters": true }]*/
function foo({a: {}}) {}
const bar = function({a: {}}) {};
const qux = ({a: {}}) => {};
const quux = ({} = bar) => {};
const item = ({} = { bar: 1 }) => {};
function baz([]) {}
```
:::
Examples of **correct** code for this rule with the `{"allowObjectPatternsAsParameters": true}` option:
::: correct
```js
/*eslint no-empty-pattern: ["error", { "allowObjectPatternsAsParameters": true }]*/
function foo({}) {}
const bar = function({}) {};
const qux = ({}) => {};
function baz({} = {}) {}
```
:::
---
---
title: no-empty-static-block
layout: doc
rule_type: suggestion
related_rules:
- no-empty
- no-empty-function
further_reading:
- https://github.com/tc39/proposal-class-static-block
---
Empty static blocks, while not technically errors, usually occur due to refactoring that wasn't completed. They can cause confusion when reading code.
## Rule Details
This rule disallows empty static blocks. This rule ignores static blocks which contain a comment.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty-static-block: "error"*/
class Foo {
static {}
}
```
:::
Examples of **correct** code for this rule:
:::correct
```js
/*eslint no-empty-static-block: "error"*/
class Foo {
static {
bar();
}
}
class Bar {
static {
// comment
}
}
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in environments prior to ES2022.
---
---
title: no-empty
rule_type: suggestion
related_rules:
- no-empty-function
---
Empty block statements, while not technically errors, usually occur due to refactoring that wasn't completed. They can cause confusion when reading code.
## Rule Details
This rule disallows empty block statements. This rule ignores block statements which contain a comment (for example, in an empty `catch` or `finally` block of a `try` statement to indicate that execution should continue regardless of errors).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-empty: "error"*/
if (foo) {
}
while (foo) {
}
switch(foo) {
}
try {
doSomething();
} catch(ex) {
} finally {
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-empty: "error"*/
if (foo) {
// empty
}
while (foo) {
/* empty */
}
switch(foo) {
/* empty */
}
try {
doSomething();
} catch (ex) {
// continue regardless of error
}
try {
doSomething();
} finally {
/* continue regardless of error */
}
```
:::
## Options
This rule has an object option for exceptions:
* `"allowEmptyCatch": true` allows empty `catch` clauses (that is, which do not contain a comment)
### allowEmptyCatch
Examples of additional **correct** code for this rule with the `{ "allowEmptyCatch": true }` option:
::: correct
```js
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
try {
doSomething();
} catch (ex) {}
try {
doSomething();
}
catch (ex) {}
finally {
/* continue regardless of error */
}
```
:::
## When Not To Use It
If you intentionally use empty block statements then you can disable this rule.
---
---
title: no-eq-null
rule_type: suggestion
related_rules:
- eqeqeq
---
Comparing to `null` without a type-checking operator (`==` or `!=`), can have unintended results as the comparison will evaluate to `true` when comparing to not just a `null`, but also an `undefined` value.
```js
if (foo == null) {
bar();
}
```
## Rule Details
The `no-eq-null` rule aims reduce potential bug and unwanted behavior by ensuring that comparisons to `null` only match `null`, and not also `undefined`. As such it will flag comparisons to `null` when using `==` and `!=`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-eq-null: "error"*/
if (foo == null) {
bar();
}
while (qux != null) {
baz();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-eq-null: "error"*/
if (foo === null) {
bar();
}
while (qux !== null) {
baz();
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to enforce type-checking operations in general, use the more powerful [eqeqeq](./eqeqeq) instead.
## Compatibility
* **JSHint**: This rule corresponds to `eqnull` rule of JSHint.
---
---
title: no-eval
rule_type: suggestion
related_rules:
- no-implied-eval
further_reading:
- https://ericlippert.com/2003/11/01/eval-is-evil-part-one/
- https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
---
JavaScript's `eval()` function is potentially dangerous and is often misused. Using `eval()` on untrusted code can open a program up to several different injection attacks. The use of `eval()` in most contexts can be substituted for a better, alternative approach to a problem.
```js
const obj = { x: "foo" },
key = "x",
value = eval("obj." + key);
```
## Rule Details
This rule is aimed at preventing potentially dangerous, unnecessary, and slow code by disallowing the use of the `eval()` function. As such, it will warn whenever the `eval()` function is used.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-eval: "error"*/
const obj = { x: "foo" },
key = "x",
value = eval("obj." + key);
(0, eval)("const a = 0");
const foo = eval;
foo("const a = 0");
// This `this` is the global object.
this.eval("const a = 0");
```
:::
Example of additional **incorrect** code for this rule with `window` global variable:
::: incorrect
```js
/*eslint no-eval: "error"*/
/*global window*/
window.eval("const a = 0");
```
:::
Example of additional **incorrect** code for this rule with `global` global variable:
::: incorrect
```js
/*eslint no-eval: "error"*/
/*global global*/
global.eval("const a = 0");
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-eval: "error"*/
const obj = { x: "foo" },
key = "x",
value = obj[key];
class A {
foo() {
// This is a user-defined method.
this.eval("const a = 0");
}
eval() {
}
static {
// This is a user-defined static method.
this.eval("const a = 0");
}
static eval() {
}
}
```
:::
## Options
### allowIndirect
This rule has an option to allow ["indirect eval"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#direct_and_indirect_eval).
Indirect calls to `eval` are less dangerous than direct calls to `eval` because they cannot dynamically change the scope. Because of this, they also will not negatively impact performance to the degree of direct `eval`.
```js
{
"no-eval": ["error", {"allowIndirect": true}] // default is false
}
```
Example of **incorrect** code for this rule with the `{"allowIndirect": true}` option:
::: incorrect
```js
/*eslint no-eval: ["error", {"allowIndirect": true} ]*/
const obj = { x: "foo" },
key = "x",
value = eval("obj." + key);
```
:::
Examples of **correct** code for this rule with the `{"allowIndirect": true}` option:
::: correct { "sourceType": "script" }
```js
/*eslint no-eval: ["error", {"allowIndirect": true} ]*/
(0, eval)("const a = 0");
const foo = eval;
foo("const a = 0");
this.eval("const a = 0");
```
:::
::: correct
```js
/*eslint no-eval: ["error", {"allowIndirect": true} ]*/
/*global window*/
window.eval("const a = 0");
```
:::
::: correct
```js
/*eslint no-eval: ["error", {"allowIndirect": true} ]*/
/*global global*/
global.eval("const a = 0");
```
:::
## Known Limitations
* This rule is warning every `eval()` even if the `eval` is not global's.
This behavior is in order to detect calls of direct `eval`. Such as:
```js
module.exports = function(eval) {
// If the value of this `eval` is built-in `eval` function, this is a
// call of direct `eval`.
eval("const a = 0");
};
```
* This rule cannot catch renaming the global object. Such as:
```js
const foo = window;
foo.eval("const a = 0");
```
---
---
title: no-ex-assign
rule_type: problem
further_reading:
- https://bocoup.com/blog/the-catch-with-try-catch
---
If a `catch` clause in a `try` statement accidentally (or purposely) assigns another value to the exception parameter, it is impossible to refer to the error from that point on.
Since there is no `arguments` object to offer alternative access to this data, assignment of the parameter is absolutely destructive.
## Rule Details
This rule disallows reassigning exceptions in `catch` clauses.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-ex-assign: "error"*/
try {
// code
} catch (e) {
e = 10;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-ex-assign: "error"*/
try {
// code
} catch (e) {
const foo = 10;
}
```
:::
## Options
This rule has no options.
---
---
title: no-extend-native
rule_type: suggestion
related_rules:
- no-global-assign
---
In JavaScript, you can extend any object, including builtin or "native" objects. Sometimes people change the behavior of these native objects in ways that break the assumptions made about them in other parts of the code.
For example here we are overriding a builtin method that will then affect all Objects, even other builtins.
```js
// seems harmless
Object.prototype.extra = 55;
// loop through some userIds
const users = {
"123": "Stan",
"456": "David"
};
// not what you'd expect
for (const id in users) {
console.log(id); // "123", "456", "extra"
}
```
A common suggestion to avoid this problem would be to wrap the inside of the `for` loop with `users.hasOwnProperty(id)`. However, if this rule is strictly enforced throughout your codebase you won't need to take that step.
## Rule Details
Disallows directly modifying the prototype of builtin objects.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-extend-native: "error"*/
Object.prototype.a = "a";
Object.defineProperty(Array.prototype, "times", { value: 999 });
```
:::
## Options
This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which extensions will be allowed.
### exceptions
Examples of **correct** code for the sample `{ "exceptions": ["Object"] }` option:
::: correct
```js
/*eslint no-extend-native: ["error", { "exceptions": ["Object"] }]*/
Object.prototype.a = "a";
```
:::
## Known Limitations
This rule *does not* report any of the following less obvious approaches to modify the prototype of builtin objects:
```js
const x = Object;
x.prototype.thing = a;
eval("Array.prototype.forEach = 'muhahaha'");
with(Array) {
prototype.thing = 'thing';
};
window.Function.prototype.bind = 'tight';
```
## When Not To Use It
You may want to disable this rule when working with polyfills that try to patch older versions of JavaScript with the latest spec, such as those that might `Function.prototype.bind` or `Array.prototype.forEach` in a future-friendly way.
---
---
title: no-extra-bind
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
- https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/
---
The `bind()` method is used to create functions with specific `this` values and, optionally, binds arguments to specific values. When used to specify the value of `this`, it's important that the function actually uses `this` in its function body. For example:
```js
const boundGetName = (function getName() {
return this.name;
}).bind({ name: "ESLint" });
console.log(boundGetName()); // "ESLint"
```
This code is an example of a good use of `bind()` for setting the value of `this`.
Sometimes during the course of code maintenance, the `this` value is removed from the function body. In that case, you can end up with a call to `bind()` that doesn't accomplish anything:
```js
// useless bind
const boundGetName = (function getName() {
return "ESLint";
}).bind({ name: "ESLint" });
console.log(boundGetName()); // "ESLint"
```
In this code, the reference to `this` has been removed but `bind()` is still used. In this case, the `bind()` is unnecessary overhead (and a performance hit) and can be safely removed.
## Rule Details
This rule is aimed at avoiding the unnecessary use of `bind()` and as such will warn whenever an immediately-invoked function expression (IIFE) is using `bind()` and doesn't have an appropriate `this` value. This rule won't flag usage of `bind()` that includes function argument binding.
**Note:** Arrow functions can never have their `this` value set using `bind()`. This rule flags all uses of `bind()` with arrow functions as a problem
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-extra-bind: "error"*/
const x = function () {
foo();
}.bind(bar);
const y = (() => {
foo();
}).bind(bar);
const z = (() => {
this.foo();
}).bind(bar);
const a = function () {
(function () {
this.foo();
}());
}.bind(bar);
const b = function () {
function foo() {
this.bar();
}
}.bind(baz);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-extra-bind: "error"*/
const x = function () {
this.foo();
}.bind(bar);
const y = function (a) {
return a + 1;
}.bind(foo, bar);
```
:::
## Options
This rule has no options.
## When Not To Use It
If you are not concerned about unnecessary calls to `bind()`, you can safely disable this rule.
---
---
title: no-extra-boolean-cast
rule_type: suggestion
---
In contexts such as an `if` statement's test where the result of the expression will already be coerced to a Boolean, casting to a Boolean via double negation (`!!`) or a `Boolean` call is unnecessary. For example, these `if` statements are equivalent:
```js
if (!!foo) {
// ...
}
if (Boolean(foo)) {
// ...
}
if (foo) {
// ...
}
```
## Rule Details
This rule disallows unnecessary boolean casts.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-extra-boolean-cast: "error"*/
const foo = !!!bar;
const foo1 = !!bar ? baz : bat;
const foo2 = Boolean(!!bar);
const foo3 = new Boolean(!!bar);
if (!!foo) {
// ...
}
if (Boolean(foo)) {
// ...
}
while (!!foo) {
// ...
}
do {
// ...
} while (Boolean(foo));
for (; !!foo; ) {
// ...
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-extra-boolean-cast: "error"*/
const foo = !!bar;
const foo1 = Boolean(bar);
function qux() {
return !!bar;
}
foo = bar ? !!baz : !!bat;
```
:::
## Options
This rule has an object option:
* `"enforceForInnerExpressions"` when set to `true`, in addition to checking default contexts, checks whether extra boolean casts are present in expressions whose result is used in a boolean context. See examples below. Default is `false`, meaning that this rule by default does not warn about extra booleans cast inside inner expressions.
**Deprecated:** The object property `enforceForLogicalOperands` is deprecated ([eslint#18222](https://github.com/eslint/eslint/pull/18222)). Please use `enforceForInnerExpressions` instead.
### enforceForInnerExpressions
Examples of **incorrect** code for this rule with `"enforceForInnerExpressions"` option set to `true`:
::: incorrect
```js
/*eslint no-extra-boolean-cast: ["error", {"enforceForInnerExpressions": true}]*/
if (!!foo || bar) {
//...
}
while (!!foo && bar) {
//...
}
if ((!!foo || bar) && !!baz) {
//...
}
const foo = new Boolean(!!bar || baz);
foo && Boolean(bar) ? baz : bat;
const ternaryBranches = Boolean(bar ? !!baz : bat);
const nullishCoalescingOperator = Boolean(bar ?? Boolean(baz));
const commaOperator = Boolean((bar, baz, !!bat));
// another comma operator example
for (let i = 0; console.log(i), Boolean(i < 10); i++) {
// ...
}
```
:::
Examples of **correct** code for this rule with `"enforceForInnerExpressions"` option set to `true`:
::: correct
```js
/*eslint no-extra-boolean-cast: ["error", {"enforceForInnerExpressions": true}]*/
// Note that `||` and `&&` alone aren't a boolean context for either operand
// since the resultant value need not be a boolean without casting.
const foo = !!bar || baz;
if (foo || bar) {
//...
}
while (foo && bar) {
//...
}
if ((foo || bar) && baz) {
//...
}
const foo1 = new Boolean(bar || baz);
foo && bar ? baz : bat;
const ternaryBranches = Boolean(bar ? baz : bat);
const nullishCoalescingOperator = Boolean(bar ?? baz);
const commaOperator = Boolean((bar, baz, bat));
// another comma operator example
for (let i = 0; console.log(i), i < 10; i++) {
// ...
}
// comma operator in non-final position
Boolean((Boolean(bar), baz, bat));
```
:::
---
---
title: no-extra-label
rule_type: suggestion
related_rules:
- no-labels
- no-label-var
- no-unused-labels
---
If a loop contains no nested loops or switches, labeling the loop is unnecessary.
```js
A: while (a) {
break A;
}
```
You can achieve the same result by removing the label and using `break` or `continue` without a label.
Probably those labels would confuse developers because they expect labels to jump to further.
## Rule Details
This rule is aimed at eliminating unnecessary labels.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-extra-label: "error"*/
A: while (a) {
break A;
}
B: for (let i = 0; i < 10; ++i) {
break B;
}
C: switch (a) {
case 0:
break C;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-extra-label: "error"*/
while (a) {
break;
}
for (let i = 0; i < 10; ++i) {
break;
}
switch (a) {
case 0:
break;
}
A: {
break A;
}
B: while (a) {
while (b) {
break B;
}
}
C: switch (a) {
case 0:
while (b) {
break C;
}
break;
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about usage of labels, then it's safe to disable this rule.
---
---
title: no-extra-parens
rule_type: layout
related_rules:
- arrow-parens
- no-cond-assign
- no-return-assign
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
---
This rule restricts the use of parentheses to only where they are necessary.
## Rule Details
This rule always ignores extra parentheses around the following:
* RegExp literals such as `(/abc/).test(var)` to avoid conflicts with the [wrap-regex](wrap-regex) rule
* immediately-invoked function expressions (also known as IIFEs) such as `var x = (function () {})();` and `var x = (function () {}());` to avoid conflicts with the [wrap-iife](wrap-iife) rule
* arrow function arguments to avoid conflicts with the [arrow-parens](arrow-parens) rule
Problems reported by this rule can be fixed automatically, except when removing the parentheses would create a new directive, because that could change the semantics of the code.
For example, the following script prints `object` to the console, but if the parentheses around `"use strict"` were removed, it would print `undefined` instead.
```js
("use strict");
function test() {
console.log(typeof this);
}
test();
```
In this case, the rule will not try to remove the parentheses around `"use strict"` but will still report them as a problem.
## Options
This rule has a string option:
* `"all"` (default) disallows unnecessary parentheses around *any* expression.
* `"functions"` disallows unnecessary parentheses *only* around function expressions.
This rule has an object option for exceptions to the `"all"` option:
* `"conditionalAssign": false` allows extra parentheses around assignments in conditional test expressions.
* `"returnAssign": false` allows extra parentheses around assignments in `return` statements.
* `"nestedBinaryExpressions": false` allows extra parentheses in nested binary expressions.
* `"ternaryOperandBinaryExpressions": false` allows extra parentheses around binary expressions that are operands of ternary `?:`.
* `"ignoreJSX": "none|all|multi-line|single-line"` allows extra parentheses around no/all/multi-line/single-line JSX components. Defaults to `none`.
* `"enforceForArrowConditionals": false` allows extra parentheses around ternary expressions which are the body of an arrow function.
* `"enforceForSequenceExpressions": false` allows extra parentheses around sequence expressions.
* `"enforceForNewInMemberExpressions": false` allows extra parentheses around `new` expressions in member expressions.
* `"enforceForFunctionPrototypeMethods": false` allows extra parentheses around immediate `.call` and `.apply` method calls on function expressions and around function expressions in the same context.
* `"allowParensAfterCommentPattern": "any-string-pattern"` allows extra parentheses preceded by a comment that matches a regular expression.
### all
Examples of **incorrect** code for this rule with the default `"all"` option:
::: incorrect
```js
/* eslint no-extra-parens: "error" */
a = (b * c);
(a * b) + c;
for (a in (b, c));
for (a in (b));
for (a of (b));
typeof (a);
(Object.prototype.toString.call());
class A {
[(x)] = 1;
}
class B {
x = (y + z);
}
```
:::
Examples of **correct** code for this rule with the default `"all"` option:
::: correct
```js
/* eslint no-extra-parens: "error" */
(0).toString();
({}.toString.call());
(function(){}) ? a() : b();
(/^a$/).test(x);
for (a of (b, c));
for (a of b);
for (a in b, c);
for (a in b);
class A {
[x] = 1;
}
class B {
x = y + z;
}
```
:::
### conditionalAssign
Examples of **correct** code for this rule with the `"all"` and `{ "conditionalAssign": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "conditionalAssign": false }] */
while ((foo = bar())) {}
if ((foo = bar())) {}
do; while ((foo = bar()))
for (;(a = b););
```
:::
### returnAssign
Examples of **correct** code for this rule with the `"all"` and `{ "returnAssign": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "returnAssign": false }] */
function a1(b) {
return (b = 1);
}
function a2(b) {
return b ? (c = d) : (c = e);
}
b => (b = 1);
b => b ? (c = d) : (c = e);
```
:::
### nestedBinaryExpressions
Examples of **correct** code for this rule with the `"all"` and `{ "nestedBinaryExpressions": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "nestedBinaryExpressions": false }] */
x = a || (b && c);
x = a + (b * c);
x = (a * b) / c;
```
:::
### ternaryOperandBinaryExpressions
Examples of **correct** code for this rule with the `"all"` and `{ "ternaryOperandBinaryExpressions": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "ternaryOperandBinaryExpressions": false }] */
(a && b) ? foo : bar;
(a - b > a) ? foo : bar;
foo ? (bar || baz) : qux;
foo ? bar : (baz || qux);
```
:::
### ignoreJSX
Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "all" }` options:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "all" }] */
const ThisComponent = ()
const ThatComponent = (
)
```
:::
Examples of **incorrect** code for this rule with the `all` and `{ "ignoreJSX": "multi-line" }` options:
::: incorrect { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "multi-line" }] */
const ThisComponent = ()
const ThatComponent = ()
```
:::
Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "multi-line" }` options:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "multi-line" }] */
const ThisComponent = (
)
const ThatComponent = (
)
```
:::
Examples of **incorrect** code for this rule with the `all` and `{ "ignoreJSX": "single-line" }` options:
::: incorrect { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "single-line" }] */
const ThisComponent = (
)
const ThatComponent = (
)
```
:::
Examples of **correct** code for this rule with the `all` and `{ "ignoreJSX": "single-line" }` options:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/* eslint no-extra-parens: ["error", "all", { ignoreJSX: "single-line" }] */
const ThisComponent = ()
const ThatComponent = ()
```
:::
### enforceForArrowConditionals
Examples of **correct** code for this rule with the `"all"` and `{ "enforceForArrowConditionals": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "enforceForArrowConditionals": false }] */
const b = a => 1 ? 2 : 3;
const d = c => (1 ? 2 : 3);
```
:::
### enforceForSequenceExpressions
Examples of **correct** code for this rule with the `"all"` and `{ "enforceForSequenceExpressions": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "enforceForSequenceExpressions": false }] */
(a, b);
if ((val = foo(), val < 10)) {}
while ((val = foo(), val < 10));
```
:::
### enforceForNewInMemberExpressions
Examples of **correct** code for this rule with the `"all"` and `{ "enforceForNewInMemberExpressions": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "enforceForNewInMemberExpressions": false }] */
const foo = (new Bar()).baz;
const quux = (new Bar())[baz];
(new Bar()).doSomething();
```
:::
### enforceForFunctionPrototypeMethods
Examples of **correct** code for this rule with the `"all"` and `{ "enforceForFunctionPrototypeMethods": false }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "enforceForFunctionPrototypeMethods": false }] */
const foo = (function () {}).call();
const bar = (function () {}).apply();
const baz = (function () {}.call());
const quux = (function () {}.apply());
```
:::
### allowParensAfterCommentPattern
To make this rule allow extra parentheses preceded by specific comments, set this option to a string pattern that will be passed to the [`RegExp` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp).
Examples of **correct** code for this rule with the `"all"` and `{ "allowParensAfterCommentPattern": "@type" }` options:
::: correct
```js
/* eslint no-extra-parens: ["error", "all", { "allowParensAfterCommentPattern": "@type" }] */
const span = /**@type {HTMLSpanElement}*/(event.currentTarget);
if (/** @type {Foo | Bar} */(options).baz) console.log('Lint free');
foo(/** @type {Bar} */ (bar), options, {
name: "name",
path: "path",
});
if (foo) {
/** @type {Bar} */
(bar).prop = false;
}
```
:::
### functions
Examples of **incorrect** code for this rule with the `"functions"` option:
::: incorrect
```js
/* eslint no-extra-parens: ["error", "functions"] */
((function foo() {}))();
var y = (function () {return 1;});
```
:::
Examples of **correct** code for this rule with the `"functions"` option:
::: correct
```js
/* eslint no-extra-parens: ["error", "functions"] */
(0).toString();
(Object.prototype.toString.call());
({}.toString.call());
(function(){} ? a() : b());
(/^a$/).test(x);
a = (b * c);
(a * b) + c;
typeof (a);
```
:::
---
---
title: no-extra-semi
rule_type: suggestion
related_rules:
- semi
- semi-spacing
---
Typing mistakes and misunderstandings about where semicolons are required can lead to semicolons that are unnecessary. While not technically an error, extra semicolons can cause confusion when reading code.
## Rule Details
This rule disallows unnecessary semicolons.
Problems reported by this rule can be fixed automatically, except when removing a semicolon would cause a following statement to become a directive such as `"use strict"`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-extra-semi: "error"*/
var x = 5;;
function foo() {
// code
};
class C {
field;;
method() {
// code
};
static {
// code
};
};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-extra-semi: "error"*/
var x = 5;
function foo() {
// code
}
var bar = function() {
// code
};
class C {
field;
method() {
// code
}
static {
// code
}
}
```
:::
## When Not To Use It
If you intentionally use extra semicolons then you can disable this rule.
---
---
title: no-extra-strict
further_reading:
- https://es5.github.io/#C
---
Disallows strict mode directives when already in strict mode.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [strict](strict) rule. The `"global"` or `"function"` options in the new rule are similar to the removed rule.
:::
The `"use strict";` directive applies to the scope in which it appears and all inner scopes contained within that scope. Therefore, using the `"use strict";` directive in one of these inner scopes is unnecessary.
```js
"use strict";
(function () {
"use strict";
var foo = true;
}());
```
## Rule Details
This rule is aimed at preventing unnecessary `"use strict";` directives. As such, it will warn when it encounters a `"use strict";` directive when already in strict mode.
Example of **incorrect** code for this rule:
::: incorrect
```js
"use strict";
(function () {
"use strict";
var foo = true;
}());
```
:::
Examples of **correct** code for this rule:
::: correct
```js
"use strict";
(function () {
var foo = true;
}());
```
:::
::: correct
```js
(function () {
"use strict";
var foo = true;
}());
```
:::
---
---
title: no-fallthrough
rule_type: problem
related_rules:
- default-case
---
The `switch` statement in JavaScript is one of the more error-prone constructs of the language thanks in part to the ability to "fall through" from one `case` to the next. For example:
```js
switch(foo) {
case 1:
doSomething();
case 2:
doSomethingElse();
}
```
In this example, if `foo` is `1`, then execution will flow through both cases, as the first falls through to the second. You can prevent this by using `break`, as in this example:
```js
switch(foo) {
case 1:
doSomething();
break;
case 2:
doSomethingElse();
}
```
That works fine when you don't want a fallthrough, but what if the fallthrough is intentional, there is no way to indicate that in the language. It's considered a best practice to always indicate when a fallthrough is intentional using a comment which matches the `/falls?\s?through/i` regular expression but isn't a directive:
```js
switch(foo) {
case 1:
doSomething();
// falls through
case 2:
doSomethingElse();
}
switch(foo) {
case 1:
doSomething();
// fall through
case 2:
doSomethingElse();
}
switch(foo) {
case 1:
doSomething();
// fallsthrough
case 2:
doSomethingElse();
}
switch(foo) {
case 1: {
doSomething();
// falls through
}
case 2: {
doSomethingElse();
}
}
```
In this example, there is no confusion as to the expected behavior. It is clear that the first case is meant to fall through to the second case.
## Rule Details
This rule is aimed at eliminating unintentional fallthrough of one case to the other. As such, it flags any fallthrough scenarios that are not marked by a comment.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-fallthrough: "error"*/
switch(foo) {
case 1:
doSomething();
case 2:
doSomething();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-fallthrough: "error"*/
switch(foo) {
case 1:
doSomething();
break;
case 2:
doSomething();
}
function bar(foo) {
switch(foo) {
case 1:
doSomething();
return;
case 2:
doSomething();
}
}
switch(foo) {
case 1:
doSomething();
throw new Error("Boo!");
case 2:
doSomething();
}
switch(foo) {
case 1:
case 2:
doSomething();
}
switch(foo) {
case 1: case 2:
doSomething();
}
switch(foo) {
case 1:
doSomething();
// falls through
case 2:
doSomething();
}
switch(foo) {
case 1: {
doSomething();
// falls through
}
case 2: {
doSomethingElse();
}
}
```
:::
Note that the last `case` statement in these examples does not cause a warning because there is nothing to fall through into.
## Options
This rule has an object option:
* Set the `commentPattern` option to a regular expression string to change the test for intentional fallthrough comment. If the fallthrough comment matches a directive, that takes precedence over `commentPattern`.
* Set the `allowEmptyCase` option to `true` to allow empty cases regardless of the layout. By default, this rule does not require a fallthrough comment after an empty `case` only if the empty `case` and the next `case` are on the same line or on consecutive lines.
* Set the `reportUnusedFallthroughComment` option to `true` to prohibit a fallthrough comment from being present if the case cannot fallthrough due to being unreachable. This is mostly intended to help avoid misleading comments occurring as a result of refactoring.
### commentPattern
Examples of **correct** code for the `{ "commentPattern": "break[\\s\\w]*omitted" }` option:
::: correct
```js
/*eslint no-fallthrough: ["error", { "commentPattern": "break[\\s\\w]*omitted" }]*/
switch(foo) {
case 1:
doSomething();
// break omitted
case 2:
doSomething();
}
switch(foo) {
case 1:
doSomething();
// caution: break is omitted intentionally
default:
doSomething();
}
```
:::
### allowEmptyCase
Examples of **correct** code for the `{ "allowEmptyCase": true }` option:
::: correct
```js
/* eslint no-fallthrough: ["error", { "allowEmptyCase": true }] */
switch(foo){
case 1:
case 2: doSomething();
}
switch(foo){
case 1:
/*
Put a message here
*/
case 2: doSomething();
}
```
:::
### reportUnusedFallthroughComment
Examples of **incorrect** code for the `{ "reportUnusedFallthroughComment": true }` option:
::: incorrect
```js
/* eslint no-fallthrough: ["error", { "reportUnusedFallthroughComment": true }] */
switch(foo){
case 1:
doSomething();
break;
// falls through
case 2: doSomething();
}
function f() {
switch(foo){
case 1:
if (a) {
throw new Error();
} else if (b) {
break;
} else {
return;
}
// falls through
case 2:
break;
}
}
```
:::
Examples of **correct** code for the `{ "reportUnusedFallthroughComment": true }` option:
::: correct
```js
/* eslint no-fallthrough: ["error", { "reportUnusedFallthroughComment": true }] */
switch(foo){
case 1:
doSomething();
break;
// just a comment
case 2: doSomething();
}
```
:::
## When Not To Use It
If you don't want to enforce that each `case` statement should end with a `throw`, `return`, `break`, or comment, then you can safely turn this rule off.
---
---
title: no-floating-decimal
rule_type: suggestion
---
Float values in JavaScript contain a decimal point, and there is no requirement that the decimal point be preceded or followed by a number. For example, the following are all valid JavaScript numbers:
```js
var num = .5;
var num = 2.;
var num = -.7;
```
Although not a syntax error, this format for numbers can make it difficult to distinguish between true decimal numbers and the dot operator. For this reason, some recommend that you should always include a number before and after a decimal point to make it clear the intent is to create a decimal number.
## Rule Details
This rule is aimed at eliminating floating decimal points and will warn whenever a numeric value has a decimal point but is missing a number either before or after it.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-floating-decimal: "error"*/
var num = .5;
var num = 2.;
var num = -.7;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-floating-decimal: "error"*/
var num = 0.5;
var num = 2.0;
var num = -0.7;
```
:::
## When Not To Use It
If you aren't concerned about misinterpreting floating decimal point values, then you can safely turn this rule off.
## Compatibility
* **JSHint**: W008, W047
---
---
title: no-func-assign
rule_type: problem
handled_by_typescript: true
---
JavaScript functions can be written as a FunctionDeclaration `function foo() { ... }` or as a FunctionExpression `const foo = function() { ... };`. While a JavaScript interpreter might tolerate it, overwriting/reassigning a function written as a FunctionDeclaration is often indicative of a mistake or issue.
```js
function foo() {}
foo = bar;
```
## Rule Details
This rule disallows reassigning `function` declarations.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-func-assign: "error"*/
function foo() {}
foo = bar;
function baz() {
baz = bar;
}
let a = function hello() {
hello = 123;
};
```
:::
Examples of **incorrect** code for this rule, unlike the corresponding rule in JSHint:
::: incorrect
```js
/*eslint no-func-assign: "error"*/
foo = bar;
function foo() {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-func-assign: "error"*/
let foo = function () {}
foo = bar;
function baz(baz) { // `baz` is shadowed.
baz = bar;
}
function qux() {
const qux = bar; // `qux` is shadowed.
}
```
:::
## Options
This rule has no options.
---
---
title: no-global-assign
rule_type: suggestion
related_rules:
- no-extend-native
- no-redeclare
- no-shadow
---
JavaScript environments contain a number of built-in global variables, such as `window` in browsers and `process` in Node.js. In almost all cases, you don't want to assign a value to these global variables as doing so could result in losing access to important functionality. For example, you probably don't want to do this in browser code:
```js
window = {};
```
While examples such as `window` are obvious, there are often hundreds of built-in global objects provided by JavaScript environments. It can be hard to know if you're assigning to a global variable or not.
## Rule Details
This rule disallows modifications to read-only global variables.
ESLint has the capability to configure global variables as read-only.
See also: [Specifying Globals](../use/configure#specifying-globals)
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-global-assign: "error"*/
Object = null
undefined = 1
```
:::
::: incorrect
```js
/*eslint no-global-assign: "error"*/
/*global window:readonly*/
window = {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-global-assign: "error"*/
a = 1
let b = 1
b = 2
```
:::
::: correct
```js
/*eslint no-global-assign: "error"*/
/*global onload:writable*/
onload = function() {}
```
:::
## Options
This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which reassignments will be allowed:
```json
{
"rules": {
"no-global-assign": ["error", {"exceptions": ["Object"]}]
}
}
```
## When Not To Use It
If you are trying to override one of the native objects.
---
---
title: no-implicit-coercion
rule_type: suggestion
---
In JavaScript, there are a lot of different ways to convert value types.
Some of them might be hard to read and understand.
Such as:
```js
const b = !!foo;
const b1 = ~foo.indexOf(".");
const n = +foo;
const n1 = -(-foo);
const n2 = foo - 0;
const n3 = 1 * foo;
const s = "" + foo;
foo += ``;
```
Those can be replaced with the following code:
```js
const b = Boolean(foo);
const b1 = foo.indexOf(".") !== -1;
const n = Number(foo);
const n1 = Number(foo);
const n2 = Number(foo);
const n3 = Number(foo);
const s = String(foo);
foo = String(foo);
```
## Rule Details
This rule is aimed to flag shorter notations for the type conversion, then suggest a more self-explanatory notation.
## Options
This rule has three main options and one override option to allow some coercions as required.
* `"boolean"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `boolean` type.
* `"number"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `number` type.
* `"string"` (`true` by default) - When this is `true`, this rule warns shorter type conversions for `string` type.
* `"disallowTemplateShorthand"` (`false` by default) - When this is `true`, this rule warns `string` type conversions using `${expression}` form.
* `"allow"` (`empty` by default) - Each entry in this array can be one of `~`, `!!`, `+`, `- -`, `-`, or `*` that are to be allowed.
Note that operator `+` in `allow` list would allow `+foo` (number coercion) as well as `"" + foo` (string coercion).
### boolean
Examples of **incorrect** code for the default `{ "boolean": true }` option:
::: incorrect
```js
/*eslint no-implicit-coercion: "error"*/
const b = !!foo;
const b1 = ~foo.indexOf(".");
// bitwise not is incorrect only with `indexOf`/`lastIndexOf` method calling.
```
:::
Examples of **correct** code for the default `{ "boolean": true }` option:
::: correct
```js
/*eslint no-implicit-coercion: "error"*/
const b = Boolean(foo);
const b1 = foo.indexOf(".") !== -1;
const n = ~foo; // This is a just bitwise not.
```
:::
### number
Examples of **incorrect** code for the default `{ "number": true }` option:
::: incorrect
```js
/*eslint no-implicit-coercion: "error"*/
const n = +foo;
const n1 = -(-foo);
const n2 = foo - 0;
const n3 = 1 * foo;
```
:::
Examples of **correct** code for the default `{ "number": true }` option:
::: correct
```js
/*eslint no-implicit-coercion: "error"*/
const n = Number(foo);
const n1 = parseFloat(foo);
const n2 = parseInt(foo, 10);
const n3 = foo * 1/4; // `* 1` is allowed when followed by the `/` operator
```
:::
### string
Examples of **incorrect** code for the default `{ "string": true }` option:
::: incorrect
```js
/*eslint no-implicit-coercion: "error"*/
const s = "" + foo;
const s1 = `` + foo;
foo += "";
foo += ``;
```
:::
Examples of **correct** code for the default `{ "string": true }` option:
::: correct
```js
/*eslint no-implicit-coercion: "error"*/
const s = String(foo);
foo = String(foo);
```
:::
### disallowTemplateShorthand
This option is **not** affected by the `string` option.
Examples of **incorrect** code for the `{ "disallowTemplateShorthand": true }` option:
::: incorrect
```js
/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": true }]*/
const s = `${foo}`;
```
:::
Examples of **correct** code for the `{ "disallowTemplateShorthand": true }` option:
::: correct
```js
/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": true }]*/
const s = String(foo);
const s1 = `a${foo}`;
const s2 = `${foo}b`;
const s3 = `${foo}${bar}`;
const s4 = tag`${foo}`;
```
:::
Examples of **correct** code for the default `{ "disallowTemplateShorthand": false }` option:
::: correct
```js
/*eslint no-implicit-coercion: ["error", { "disallowTemplateShorthand": false }]*/
const s = `${foo}`;
```
:::
### allow
Using `allow` list, we can override and allow specific operators.
Examples of **correct** code for the sample `{ "allow": ["!!", "~"] }` option:
::: correct
```js
/*eslint no-implicit-coercion: [2, { "allow": ["!!", "~"] } ]*/
const b = !!foo;
const b1 = ~foo.indexOf(".");
```
:::
## When Not To Use It
If you don't want to be notified about shorter notations for the type conversion, you can safely disable this rule.
---
---
title: no-implicit-globals
rule_type: suggestion
related_rules:
- no-undef
- no-global-assign
- no-unused-vars
further_reading:
- https://benalman.com/news/2010/11/immediately-invoked-function-expression/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Undeclared_var
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone
---
It is the best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script.
Global variables created from a script can produce name collisions with global variables created from another script, which will
usually lead to runtime errors or unexpected behavior.
This rule disallows the following:
* Declarations that create one or more variables in the global scope.
* Global variable leaks.
* Redeclarations of read-only global variables and assignments to read-only global variables.
There is an explicit way to create a global variable when needed, by assigning to a property of the global object.
This rule is mostly useful for browser scripts. Top-level declarations in ES modules and CommonJS modules create module-scoped
variables. ES modules also have implicit `strict` mode, which prevents global variable leaks.
By default, this rule does not check `const`, `let` and `class` declarations.
## Rule Details
### `var` and `function` declarations
When working with browser scripts, developers often forget that variable and function declarations at the top-level scope become global variables on the `window` object. As opposed to modules which have their own scope. Globals should be explicitly assigned to `window` or `self` if that is the intent. Otherwise variables intended to be local to the script should be wrapped in an IIFE.
This rule disallows `var` and `function` declarations at the top-level script scope. This does not apply to ES and CommonJS modules since they have a module scope.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-implicit-globals: "error"*/
var foo = 1;
function bar() {}
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-implicit-globals: "error"*/
// explicitly set on window
window.foo = 1;
window.bar = function() {};
// intended to be scope to this file
(function() {
var foo = 1;
function bar() {}
})();
```
:::
Examples of **correct** code for this rule with `"languageOptions": { "sourceType": "module" }` in the ESLint configuration:
::: correct
```js
/*eslint no-implicit-globals: "error"*/
// foo and bar are local to module
var foo = 1;
function bar() {}
```
:::
### Global variable leaks
When the code is not in `strict` mode, an assignment to an undeclared variable creates
a new global variable. This will happen even if the code is in a function.
This does not apply to ES modules since the module code is implicitly in `strict` mode.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-implicit-globals: "error"*/
foo = 1;
Bar.prototype.baz = function () {
a = 1; // Intended to be this.a = 1;
};
```
:::
### Read-only global variables
This rule also disallows redeclarations of read-only global variables and assignments to read-only global variables.
A read-only global variable can be a built-in ES global (e.g. `Array`), or a global variable defined as `readonly` in the configuration file or in a `/*global */` comment.
See also: [Specifying Globals](../use/configure#specifying-globals)
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-implicit-globals: "error"*/
/*global foo:readonly*/
foo = 1;
Array = [];
var Object;
```
:::
### exported
You can use `/* exported variableName */` block comments in the same way as in [`no-unused-vars`](./no-unused-vars). See the [`no-unused-vars` exported section](./no-unused-vars#exported) for details.
Examples of **correct** code for `/* exported variableName */` operation:
::: correct { "sourceType": "script" }
```js
/* eslint no-implicit-globals: error */
/* exported global_var */
var global_var = 42;
```
:::
## Options
This rule has an object option with one option:
* Set `"lexicalBindings"` to `true` if you want this rule to check `const`, `let` and `class` declarations as well.
### `const`, `let` and `class` declarations
Lexical declarations `const` and `let`, as well as `class` declarations, create variables that are block-scoped.
However, when declared in the top-level of a browser script these variables are not 'script-scoped'.
They are actually created in the global scope and could produce name collisions with
`var`, `const` and `let` variables and `function` and `class` declarations from other scripts.
This does not apply to ES and CommonJS modules.
If the variable is intended to be local to the script, wrap the code with a block or with an immediately-invoked function expression (IIFE).
Examples of **correct** code for this rule with `"lexicalBindings"` option set to `false` (default):
::: correct { "sourceType": "script" }
```js
/*eslint no-implicit-globals: ["error", {"lexicalBindings": false}]*/
const foo = 1;
let baz;
class Bar {}
```
:::
Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
const foo = 1;
let baz;
class Bar {}
```
:::
Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`:
::: correct { "sourceType": "script" }
```js
/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
{
const foo = 1;
let baz;
class Bar {}
}
(function() {
const foo = 1;
let baz;
class Bar {}
}());
```
:::
If you intend to create a global `const` or `let` variable or a global `class` declaration, to be used from other scripts,
be aware that there are certain differences when compared to the traditional methods, which are `var` declarations and assigning to a property of the global `window` object:
* Lexically declared variables cannot be conditionally created. A script cannot check for the existence of
a variable and then create a new one. `var` variables are also always created, but redeclarations do not
cause runtime exceptions.
* Lexically declared variables do not create properties on the global object, which is what a consuming script might expect.
* Lexically declared variables are shadowing properties of the global object, which might produce errors if a
consuming script is using both the variable and the property.
* Lexically declared variables can produce a permanent Temporal Dead Zone (TDZ) if the initialization throws an exception.
Even the `typeof` check is not safe from TDZ reference exceptions.
Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
const MyGlobalFunction = (function() {
const a = 1;
let b = 2;
return function() {
return a + b;
}
}());
```
:::
Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`:
::: correct { "sourceType": "script" }
```js
/*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
window.MyGlobalFunction = (function() {
const a = 1;
let b = 2;
return function() {
return a + b;
}
}());
```
:::
## When Not To Use It
In the case of a browser script, if you want to be able to explicitly declare variables and functions in the global scope,
and your code is in strict mode or you don't want this rule to warn you about undeclared variables,
and you also don't want this rule to warn you about read-only globals, you can disable this rule.
In the case of a CommonJS module, if your code is in strict mode or you don't want this rule to warn you about undeclared variables,
and you also don't want this rule to warn you about the read-only globals, you can disable this rule.
In the case of an ES module, if you don't want this rule to warn you about the read-only globals you can disable this rule.
---
---
title: no-implied-eval
rule_type: suggestion
related_rules:
- no-eval
---
It's considered a good practice to avoid using `eval()` in JavaScript. There are security and performance implications involved with doing so, which is why many linters (including ESLint) recommend disallowing `eval()`. However, there are some other ways to pass a string and have it interpreted as JavaScript code that have similar concerns.
The first is using `setTimeout()`, `setInterval()` or `execScript()` (Internet Explorer only), all of which can accept a string of JavaScript code as their first argument. For example:
```js
setTimeout("alert('Hi!');", 100);
```
This is considered an implied `eval()` because a string of JavaScript code is
passed in to be interpreted. The same can be done with `setInterval()` and `execScript()`. Both interpret the JavaScript code in the global scope. For both `setTimeout()` and `setInterval()`, the first argument can also be a function, and that is considered safer and is more performant:
```js
setTimeout(function() {
alert("Hi!");
}, 100);
```
The best practice is to always use a function for the first argument of `setTimeout()` and `setInterval()` (and avoid `execScript()`).
## Rule Details
This rule aims to eliminate implied `eval()` through the use of `setTimeout()`, `setInterval()` or `execScript()`. As such, it will warn when either function is used with a string as the first argument.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-implied-eval: "error"*/
/*global window, setTimeout, setInterval, execScript*/
setTimeout("alert('Hi!');", 100);
setInterval("alert('Hi!');", 100);
execScript("alert('Hi!')");
window.setTimeout("count = 5", 10);
window.setInterval("foo = bar", 10);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-implied-eval: "error"*/
/*global setTimeout, setInterval*/
setTimeout(function() {
alert("Hi!");
}, 100);
setInterval(function() {
alert("Hi!");
}, 100);
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow `setTimeout()` and `setInterval()` with string arguments, then you can safely disable this rule.
---
---
title: no-import-assign
rule_type: problem
handled_by_typescript: true
extra_typescript_info: Note that the compiler will not catch the `Object.assign()` case. Thus, if you use `Object.assign()` in your codebase, this rule will still provide some value.
---
The updates of imported bindings by ES Modules cause runtime errors.
## Rule Details
This rule warns the assignments, increments, and decrements of imported bindings.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-import-assign: "error"*/
import mod, { named } from "./mod.mjs"
import * as mod_ns from "./mod.mjs"
mod = 1 // ERROR: 'mod' is readonly.
named = 2 // ERROR: 'named' is readonly.
mod_ns.named = 3 // ERROR: The members of 'mod_ns' are readonly.
mod_ns = {} // ERROR: 'mod_ns' is readonly.
// Can't extend 'mod_ns'
Object.assign(mod_ns, { foo: "foo" }) // ERROR: The members of 'mod_ns' are readonly.
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-import-assign: "error"*/
import mod, { named } from "./mod.mjs"
import * as mod_ns from "./mod.mjs"
mod.prop = 1
named.prop = 2
mod_ns.named.prop = 3
// Known Limitation
function test(obj) {
obj.named = 4 // Not errored because 'obj' is not namespace objects.
}
test(mod_ns) // Not errored because it doesn't know that 'test' updates the member of the argument.
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about modifying imported bindings, you can disable this rule.
---
---
title: no-inline-comments
rule_type: suggestion
---
Some style guides disallow comments on the same line as code. Code can become difficult to read if comments immediately follow the code on the same line.
On the other hand, it is sometimes faster and more obvious to put comments immediately following code.
## Rule Details
This rule disallows comments on the same line as code.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-inline-comments: "error"*/
const a = 1; // declaring a to 1
function getRandomNumber(){
return 4; // chosen by fair dice roll.
// guaranteed to be random.
}
/* A block comment before code */ const b = 2;
const c = 3; /* A block comment after code */
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-inline-comments: "error"*/
// This is a comment above a line of code
const foo = 5;
const bar = 5;
//This is a comment below a line of code
```
:::
### JSX exception
Comments inside the curly braces in JSX are allowed to be on the same line as the braces, but only if they are not on the same line with other code, and the braces do not enclose an actual expression.
Examples of **incorrect** code for this rule:
::: incorrect { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint no-inline-comments: "error"*/
const foo = { /* On the same line with other code */ }
Some heading
;
const bar = (
{ // These braces are not just for the comment, so it can't be on the same line
baz
}
);
```
:::
Examples of **correct** code for this rule:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint no-inline-comments: "error"*/
const foo = (
{/* These braces are just for this comment and there is nothing else on this line */}
Some heading
)
const bar = (
{
// There is nothing else on this line
baz
}
);
const quux = (
{/*
Multiline
comment
*/}
Some heading
)
```
:::
## Options
### ignorePattern
To make this rule ignore specific comments, set the `ignorePattern` option to a string pattern that will be passed to the [`RegExp` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp).
Examples of **correct** code for the `ignorePattern` option:
::: correct
```js
/*eslint no-inline-comments: ["error", { "ignorePattern": "webpackChunkName:\\s.+" }]*/
import(/* webpackChunkName: "my-chunk-name" */ './locale/en');
```
:::
Examples of **incorrect** code for the `ignorePattern` option:
::: incorrect
```js
/*eslint no-inline-comments: ["error", { "ignorePattern": "something" }] */
const foo = 4; // other thing
```
:::
---
---
title: no-inner-declarations
rule_type: problem
---
In JavaScript, prior to ES6, a function declaration is only allowed in the first level of a program or the body of another function, though parsers sometimes [erroneously accept them elsewhere](https://code.google.com/p/esprima/issues/detail?id=422). This only applies to function declarations; named or anonymous function expressions can occur anywhere an expression is permitted.
```js
// Good
function doSomething() { }
// Bad
if (test) {
function doSomethingElse () { }
}
function anotherThing() {
var fn;
if (test) {
// Good
fn = function expression() { };
// Bad
function declaration() { }
}
}
```
In ES6, [block-level functions](https://leanpub.com/understandinges6/read#leanpub-auto-block-level-functions) (functions declared inside a block) are limited to the scope of the block they are declared in and outside of the block scope they can't be accessed and called, but only when the code is in strict mode (code with `"use strict"` tag or ESM modules). In non-strict mode, they can be accessed and called outside of the block scope.
```js
"use strict";
if (test) {
function doSomething () { }
doSomething(); // no error
}
doSomething(); // error
```
A variable declaration is permitted anywhere a statement can go, even nested deeply inside other blocks. This is often undesirable due to variable hoisting, and moving declarations to the root of the program or function body can increase clarity. Note that [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings) (`let`, `const`) are not hoisted and therefore they are not affected by this rule.
```js
// Good
var foo = 42;
// Good
if (foo) {
let bar1;
}
// Bad
while (test) {
var bar2;
}
function doSomething() {
// Good
var baz = true;
// Bad
if (baz) {
var quux;
}
}
```
## Rule Details
This rule requires that function declarations and, optionally, variable declarations be in the root of a program, or in the root of the body of a function, or in the root of the body of a class static block.
## Options
This rule has a string and an object option:
* `"functions"` (default) disallows `function` declarations in nested blocks
* `"both"` disallows `function` and `var` declarations in nested blocks
* `{ blockScopedFunctions: "allow" }` (default) this option allows `function` declarations in nested blocks when code is in strict mode (code with `"use strict"` tag or ESM modules) and `languageOptions.ecmaVersion` is set to `2015` or above. This option can be disabled by setting it to `"disallow"`.
### functions
Examples of **incorrect** code for this rule with the default `"functions"` option:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-inner-declarations: "error"*/
// script, non-strict code
if (test) {
function doSomething() { }
}
function doSomethingElse() {
if (test) {
function doAnotherThing() { }
}
}
if (foo) function f(){}
```
:::
Examples of **correct** code for this rule with the default `"functions"` option:
::: correct { "sourceType": "script" }
```js
/*eslint no-inner-declarations: "error"*/
function doSomething() { }
function doSomethingElse() {
function doAnotherThing() { }
}
function doSomethingElse() {
"use strict";
if (test) {
function doAnotherThing() { }
}
}
class C {
static {
function doSomething() { }
}
}
if (test) {
asyncCall(id, function (err, data) { });
}
var fn;
if (test) {
fn = function fnExpression() { };
}
if (foo) var a;
```
:::
### both
Examples of **incorrect** code for this rule with the `"both"` option:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-inner-declarations: ["error", "both"]*/
if (test) {
var foo = 42;
}
function doAnotherThing() {
if (test) {
var bar = 81;
}
}
if (foo) var a;
if (foo) function f(){}
class C {
static {
if (test) {
var something;
}
}
}
```
:::
Examples of **correct** code for this rule with the `"both"` option:
::: correct { "sourceType": "script" }
```js
/*eslint no-inner-declarations: ["error", "both"]*/
var bar = 42;
if (test) {
let baz = 43;
}
function doAnotherThing() {
var baz = 81;
}
class C {
static {
var something;
}
}
```
:::
### blockScopedFunctions
Example of **incorrect** code for this rule with `{ blockScopedFunctions: "disallow" }` option with `ecmaVersion: 2015`:
::: incorrect { "sourceType": "script", "ecmaVersion": 2015 }
```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/
// non-strict code
if (test) {
function doSomething() { }
}
function doSomething() {
if (test) {
function doSomethingElse() { }
}
}
// strict code
function foo() {
"use strict";
if (test) {
function bar() { }
}
}
```
:::
Example of **correct** code for this rule with `{ blockScopedFunctions: "disallow" }` option with `ecmaVersion: 2015`:
::: correct { "sourceType": "script", "ecmaVersion": 2015 }
```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/
function doSomething() { }
function doSomething() {
function doSomethingElse() { }
}
```
:::
Example of **correct** code for this rule with `{ blockScopedFunctions: "allow" }` option with `ecmaVersion: 2015`:
::: correct { "sourceType": "script", "ecmaVersion": 2015 }
```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/
"use strict";
if (test) {
function doSomething() { }
}
function doSomething() {
if (test) {
function doSomethingElse() { }
}
}
// OR
function foo() {
"use strict";
if (test) {
function bar() { }
}
}
```
:::
`ESM modules` and both `class` declarations and expressions are always in strict mode.
::: correct
```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/
if (test) {
function doSomething() { }
}
function doSomethingElse() {
if (test) {
function doAnotherThing() { }
}
}
class Some {
static {
if (test) {
function doSomething() { }
}
}
}
const C = class {
static {
if (test) {
function doSomething() { }
}
}
}
```
:::
## When Not To Use It
By default, this rule disallows inner function declarations only in contexts where their behavior is unspecified and thus inconsistent (pre-ES6 environments) or legacy semantics apply (non-strict mode code). If your code targets pre-ES6 environments or is not in strict mode, you should enable this rule to prevent unexpected behavior.
In ES6+ environments, in strict mode code, the behavior of inner function declarations is well-defined and consistent - they are always block-scoped. If your code targets only ES6+ environments and is in strict mode (ES modules, or code with `"use strict"` directives) then there is no need to enable this rule unless you want to disallow inner functions as a stylistic choice, in which case you should enable this rule with the option `blockScopedFunctions: "disallow"`.
Disable checking variable declarations when using [block-scoped-var](block-scoped-var) or if declaring variables in nested blocks is acceptable despite hoisting.
---
---
title: no-invalid-regexp
rule_type: problem
further_reading:
- https://es5.github.io/#x7.8.5
---
An invalid pattern in a regular expression literal is a `SyntaxError` when the code is parsed, but an invalid string in `RegExp` constructors throws a `SyntaxError` only when the code is executed.
## Rule Details
This rule disallows invalid regular expression strings in `RegExp` constructors.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-invalid-regexp: "error"*/
RegExp('[')
RegExp('.', 'z')
new RegExp('\\')
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-invalid-regexp: "error"*/
RegExp('.')
new RegExp
this.RegExp('[')
```
:::
Please note that this rule validates regular expressions per the latest ECMAScript specification, regardless of your parser settings.
If you want to allow additional constructor flags for any reason, you can specify them using the `allowConstructorFlags` option. These flags will then be ignored by the rule.
## Options
This rule has an object option for exceptions:
* `"allowConstructorFlags"` is a case-sensitive array of flags
### allowConstructorFlags
Examples of **correct** code for this rule with the `{ "allowConstructorFlags": ["a", "z"] }` option:
::: correct
```js
/*eslint no-invalid-regexp: ["error", { "allowConstructorFlags": ["a", "z"] }]*/
new RegExp('.', 'a')
new RegExp('.', 'az')
```
:::
---
---
title: no-invalid-this
rule_type: suggestion
handled_by_typescript: true
extra_typescript_info: Note that, technically, TypeScript will only catch this if you have the `strict` or `noImplicitThis` flags enabled. These are enabled in most TypeScript projects, since they are considered to be best practice.
---
Under the strict mode, `this` keywords outside of classes or class-like objects might be `undefined` and raise a `TypeError`.
## Rule Details
This rule aims to flag usage of `this` keywords in contexts where the value of `this` is `undefined`.
Top-level `this` in scripts is always considered valid because it refers to the global object regardless of the strict mode.
Top-level `this` in ECMAScript modules is always considered invalid because its value is `undefined`.
For `this` inside functions, this rule basically checks whether or not the function containing `this` keyword is a constructor or a method. Note that arrow functions have lexical `this`, and that therefore this rule checks their enclosing contexts.
This rule judges from following conditions whether or not the function is a constructor:
* The name of the function starts with uppercase.
* The function is assigned to a variable which starts with an uppercase letter.
* The function is a constructor of ES2015 Classes.
This rule judges from following conditions whether or not the function is a method:
* The function is on an object literal.
* The function is assigned to a property.
* The function is a method/getter/setter of ES2015 Classes.
And this rule allows `this` keywords in functions below:
* The `call/apply/bind` method of the function is called directly.
* The function is a callback of array methods (such as `.forEach()`) if `thisArg` is given.
* The function has `@this` tag in its JSDoc comment.
And this rule always allows `this` keywords in the following contexts:
* At the top level of scripts.
* In class field initializers.
* In class static blocks.
Otherwise are considered problems.
This rule applies **only** in strict mode.
With `"languageOptions": { "sourceType": "module" }` in the ESLint configuration, your code is in strict mode even without a `"use strict"` directive.
Examples of **incorrect** code for this rule in strict mode:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-invalid-this: "error"*/
"use strict";
(function() {
this.a = 0;
baz(() => this);
})();
function foo() {
this.a = 0;
baz(() => this);
}
const bar = function() {
this.a = 0;
baz(() => this);
};
foo(function() {
this.a = 0;
baz(() => this);
});
const obj = {
aaa: function() {
return function foo() {
// There is in a method `aaa`, but `foo` is not a method.
this.a = 0;
baz(() => this);
};
}
};
foo.forEach(function() {
this.a = 0;
baz(() => this);
});
```
:::
Examples of **correct** code for this rule in strict mode:
::: correct { "sourceType": "script" }
```js
/*eslint no-invalid-this: "error"*/
"use strict";
this.a = 0;
baz(() => this);
function Foo() {
// OK, this is in a legacy style constructor.
this.a = 0;
baz(() => this);
}
class Bar {
constructor() {
// OK, this is in a constructor.
this.a = 0;
baz(() => this);
}
}
const obj = {
foo: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
const obj1 = {
foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
const obj2 = {
get foo() {
// OK, this is in a method (this function is on object literal).
return this.a;
}
};
const obj3 = Object.create(null, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
Object.defineProperty(obj, "foo", {
value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
});
Object.defineProperties(obj, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
function Foo() {
this.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
baz(() => this);
};
}
obj.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
Foo.prototype.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
class Baz {
// OK, this is in a class field initializer.
a = this.b;
// OK, static initializers also have valid this.
static a = this.b;
foo() {
// OK, this is in a method.
this.a = 0;
baz(() => this);
}
static foo() {
// OK, this is in a method (static methods also have valid this).
this.a = 0;
baz(() => this);
}
static {
// OK, static blocks also have valid this.
this.a = 0;
baz(() => this);
}
}
const bar = (function foo() {
// OK, the `bind` method of this function is called directly.
this.a = 0;
}).bind(obj);
foo.forEach(function() {
// OK, `thisArg` of `.forEach()` is given.
this.a = 0;
baz(() => this);
}, thisArg);
/** @this Foo */
function foo() {
// OK, this function has a `@this` tag in its JSDoc comment.
this.a = 0;
}
```
:::
## Options
This rule has an object option, with one option:
* `"capIsConstructor": false` (default `true`) disables the assumption that a function which name starts with an uppercase is a constructor.
### capIsConstructor
By default, this rule always allows the use of `this` in functions which name starts with an uppercase and anonymous functions that are assigned to a variable which name starts with an uppercase, assuming that those functions are used as constructor functions.
Set `"capIsConstructor"` to `false` if you want those functions to be treated as 'regular' functions.
Examples of **incorrect** code for this rule with `"capIsConstructor"` option set to `false`:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
function Foo() {
this.a = 0;
}
const bar = function Foo() {
this.a = 0;
}
const Bar = function() {
this.a = 0;
};
Baz = function() {
this.a = 0;
};
```
:::
Examples of **correct** code for this rule with `"capIsConstructor"` option set to `false`:
::: correct { "sourceType": "script" }
```js
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
obj.Foo = function Foo() {
// OK, this is in a method.
this.a = 0;
};
```
:::
This rule additionally supports TypeScript type syntax.
Examples of **incorrect** TypeScript code for this rule:
:::incorrect
```ts
/*eslint no-invalid-this: "error"*/
function foo(bar: string) {
this.prop;
console.log(bar)
}
/** @this Obj */
foo(function() {
console.log(this);
z(x => console.log(x, this));
});
function foo() {
class C {
accessor [this.a] = foo;
}
}
```
:::
Examples of **correct** TypeScript code for this rule:
:::correct
```ts
/*eslint no-invalid-this: "error"*/
interface SomeType {
prop: string;
}
function foo(this: SomeType) {
this.prop;
}
class A {
a = 5;
b = this.a;
accessor c = this.a;
}
```
:::
## When Not To Use It
If you don't want to be notified about usage of `this` keyword outside of classes or class-like objects, you can safely disable this rule.
---
---
title: no-irregular-whitespace
rule_type: problem
further_reading:
- https://es5.github.io/#x7.2
- https://web.archive.org/web/20200414142829/http://timelessrepo.com/json-isnt-a-javascript-subset
- https://codepoints.net/U+1680
---
Invalid or irregular whitespace causes issues with ECMAScript 5 parsers and also makes code harder to debug in a similar nature to mixed tabs and spaces.
Various whitespace characters can be inputted by programmers by mistake for example from copying or keyboard shortcuts. Pressing Alt + Space on macOS adds in a non breaking space character for example.
A simple fix for this problem could be to rewrite the offending line from scratch. This might also be a problem introduced by the text editor: if rewriting the line does not fix it, try using a different editor.
Known issues these spaces cause:
* Ogham Space Mark
* Is a valid token separator, but is rendered as a visible glyph in most typefaces, which may be misleading in source code.
* Mongolian Vowel Separator
* Is no longer considered a space separator since Unicode 6.3. It will result in a syntax error in current parsers when used in place of a regular token separator.
* Line Separator and Paragraph Separator
* These have always been valid whitespace characters and line terminators, but were considered illegal in string literals prior to ECMAScript 2019.
* Zero Width Space
* Is NOT considered a separator for tokens and is often parsed as an `Unexpected token ILLEGAL`.
* Is NOT shown in modern browsers making code repository software expected to resolve the visualization.
In JSON, none of the characters listed as irregular whitespace by this rule may appear outside of a string.
## Rule Details
This rule is aimed at catching invalid whitespace that is not a normal tab and space. Some of these characters may cause issues in modern browsers and others will be a debugging issue to spot.
This rule disallows the following characters except where the options allow:
```text
\u000B - Line Tabulation (\v) -
\u000C - Form Feed (\f) -
\u0085 - Next Line -
\u00A0 - No-Break Space -
\u1680 - Ogham Space Mark -
\u180E - Mongolian Vowel Separator -
\u2000 - En Quad -
\u2001 - Em Quad -
\u2002 - En Space -
\u2003 - Em Space -
\u2004 - Three-Per-Em - - <3/MSP>
\u2005 - Four-Per-Em - - <4/MSP>
\u2006 - Six-Per-Em - - <6/MSP>
\u2007 - Figure Space -
\u2008 - Punctuation Space -
\u2009 - Thin Space -
\u200A - Hair Space -
\u200B - Zero Width Space -
\u2028 - Line Separator - -
\u2029 - Paragraph Separator - -
\u202F - Narrow No-Break Space -
\u205F - Medium Mathematical Space -
\u3000 - Ideographic Space -
\uFEFF - Zero Width No-Break Space -
```
## Options
This rule has an object option for exceptions:
* `"skipStrings": true` (default) allows any whitespace characters in string literals
* `"skipComments": true` allows any whitespace characters in comments
* `"skipRegExps": true` allows any whitespace characters in regular expression literals
* `"skipTemplates": true` allows any whitespace characters in template literals
* `"skipJSXText": true` allows any whitespace characters in JSX text
### skipStrings
Examples of **incorrect** code for this rule with the default `{ "skipStrings": true }` option:
::: incorrect
```js
/*eslint no-irregular-whitespace: "error"*/
const thing = function() /**/{
return 'test';
}
const foo = function( /**/){
return 'test';
}
const bar = function /**/(){
return 'test';
}
const baz = function /**/(){
return 'test';
}
const qux = function() {
return 'test'; /**/
}
const quux = function() {
return 'test'; /**/
}
const item = function() {
// Description : some descriptive text
}
/*
Description : some descriptive text
*/
const func = function() {
return / regexp/;
}
const myFunc = function() {
return `template string`;
}
```
:::
Examples of **correct** code for this rule with the default `{ "skipStrings": true }` option:
::: correct
```js
/*eslint no-irregular-whitespace: "error"*/
const thing = function() {
return ' thing';
}
const foo = function() {
return 'thing';
}
const bar = function() {
return 'th ing';
}
```
:::
### skipComments
Examples of additional **correct** code for this rule with the `{ "skipComments": true }` option:
::: correct
```js
/*eslint no-irregular-whitespace: ["error", { "skipComments": true }]*/
function thing() {
// Description : some descriptive text
}
/*
Description : some descriptive text
*/
```
:::
### skipRegExps
Examples of additional **correct** code for this rule with the `{ "skipRegExps": true }` option:
::: correct
```js
/*eslint no-irregular-whitespace: ["error", { "skipRegExps": true }]*/
function thing() {
return / regexp/;
}
```
:::
### skipTemplates
Examples of additional **correct** code for this rule with the `{ "skipTemplates": true }` option:
::: correct
```js
/*eslint no-irregular-whitespace: ["error", { "skipTemplates": true }]*/
function thing() {
return `template string`;
}
```
:::
### skipJSXText
Examples of additional **correct** code for this rule with the `{ "skipJSXText": true }` option:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint no-irregular-whitespace: ["error", { "skipJSXText": true }]*/
function Thing() {
return text in JSX
; // before `JSX`
}
```
:::
## When Not To Use It
If you decide that you wish to use whitespace other than tabs and spaces outside of strings in your application.
---
---
title: no-iterator
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
- https://kangax.github.io/es5-compat-table/es6/#Iterators
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#Object_methods
---
The `__iterator__` property was a SpiderMonkey extension to JavaScript that could be used to create custom iterators that are compatible with JavaScript's `for in` and `for each` constructs. However, this property is now obsolete, so it should not be used. Here's an example of how this used to work:
```js
Foo.prototype.__iterator__ = function() {
return new FooIterator(this);
}
```
You should use ECMAScript 6 iterators and generators instead.
## Rule Details
This rule is aimed at preventing errors that may arise from using the `__iterator__` property, which is not implemented in several browsers. As such, it will warn whenever it encounters the `__iterator__` property.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-iterator: "error"*/
Foo.prototype.__iterator__ = function() {
return new FooIterator(this);
};
foo.__iterator__ = function () {};
foo["__iterator__"] = function () {};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-iterator: "error"*/
const __iterator__ = foo; // Not using the `__iterator__` property.
```
:::
## Options
This rule has no options.
---
---
title: no-label-var
rule_type: suggestion
related_rules:
- no-extra-label
- no-labels
- no-unused-labels
---
## Rule Details
This rule aims to create clearer code by disallowing the bad practice of creating a label that shares a name with a variable that is in scope.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-label-var: "error"*/
var x = foo;
function bar() {
x:
for (;;) {
break x;
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-label-var: "error"*/
// The variable that has the same name as the label is not in scope.
function foo() {
var q = t;
}
function bar() {
q:
for(;;) {
break q;
}
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about usage of labels, then it's safe to disable this rule.
---
---
title: no-labels
rule_type: suggestion
related_rules:
- no-extra-label
- no-label-var
- no-unused-labels
---
Labeled statements in JavaScript are used in conjunction with `break` and `continue` to control flow around multiple loops. For example:
```js
outer:
while (true) {
while (true) {
break outer;
}
}
```
The `break outer` statement ensures that this code will not result in an infinite loop because control is returned to the next statement after the `outer` label was applied. If this statement was changed to be just `break`, control would flow back to the outer `while` statement and an infinite loop would result.
While convenient in some cases, labels tend to be used only rarely and are frowned upon by some as a remedial form of flow control that is more error prone and harder to understand.
## Rule Details
This rule aims to eliminate the use of labeled statements in JavaScript. It will warn whenever a labeled statement is encountered and whenever `break` or `continue` are used with a label.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-labels: "error"*/
label:
while(true) {
// ...
}
label:
while(true) {
break label;
}
label:
while(true) {
continue label;
}
label:
switch (a) {
case 0:
break label;
}
label:
{
break label;
}
label:
if (a) {
break label;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-labels: "error"*/
const f = {
label: "foo"
};
while (true) {
break;
}
while (true) {
continue;
}
```
:::
## Options
The options allow labels with loop or switch statements:
* `"allowLoop"` (`boolean`, default is `false`) - If this option was set `true`, this rule ignores labels which are sticking to loop statements.
* `"allowSwitch"` (`boolean`, default is `false`) - If this option was set `true`, this rule ignores labels which are sticking to switch statements.
Actually labeled statements in JavaScript can be used with other than loop and switch statements.
However, this way is ultra rare, not well-known, so this would be confusing developers.
### allowLoop
Examples of **correct** code for the `{ "allowLoop": true }` option:
::: correct
```js
/*eslint no-labels: ["error", { "allowLoop": true }]*/
label:
while (true) {
break label;
}
```
:::
### allowSwitch
Examples of **correct** code for the `{ "allowSwitch": true }` option:
::: correct
```js
/*eslint no-labels: ["error", { "allowSwitch": true }]*/
label:
switch (a) {
case 0:
break label;
}
```
:::
## When Not To Use It
If you need to use labeled statements everywhere, then you can safely disable this rule.
---
---
title: no-lone-blocks
rule_type: suggestion
---
In JavaScript, prior to ES6, standalone code blocks delimited by curly braces do not create a new scope and have no use. For example, these curly braces do nothing to `foo`:
```js
{
var foo = bar();
}
```
In ES6, code blocks may create a new scope if a block-level binding (`let` and `const`), a class declaration or a function declaration (in strict mode) are present. A block is not considered redundant in these cases.
## Rule Details
This rule aims to eliminate unnecessary and potentially confusing blocks at the top level of a script or within other blocks.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-lone-blocks: "error"*/
{}
if (foo) {
bar();
{
baz();
}
}
function bar() {
{
baz();
}
}
{
function foo() {}
}
{
aLabel: {
}
}
class C {
static {
{
foo();
}
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-lone-blocks: "error"*/
while (foo) {
bar();
}
if (foo) {
if (bar) {
baz();
}
}
function bar() {
baz();
}
{
let x = 1;
}
{
const y = 1;
}
{
class Foo {}
}
aLabel: {
}
class C {
static {
lbl: {
if (something) {
break lbl;
}
foo();
}
}
}
```
:::
Examples of **correct** code for this rule with ES6 environment and strict mode via `"languageOptions": { "sourceType": "module" }` in the ESLint configuration or `"use strict"` directive in the code:
::: correct
```js
/*eslint no-lone-blocks: "error"*/
"use strict";
{
function foo() {}
}
```
:::
## Options
This rule has no options.
---
---
title: no-lonely-if
rule_type: suggestion
---
If an `if` statement is the only statement in the `else` block, it is often clearer to use an `else if` form.
```js
if (foo) {
// ...
} else {
if (bar) {
// ...
}
}
```
should be rewritten as
```js
if (foo) {
// ...
} else if (bar) {
// ...
}
```
## Rule Details
This rule disallows `if` statements as the only statement in `else` blocks.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-lonely-if: "error"*/
if (condition) {
// ...
} else {
if (anotherCondition) {
// ...
}
}
if (condition) {
// ...
} else {
if (anotherCondition) {
// ...
} else {
// ...
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-lonely-if: "error"*/
if (condition) {
// ...
} else if (anotherCondition) {
// ...
}
if (condition) {
// ...
} else if (anotherCondition) {
// ...
} else {
// ...
}
if (condition) {
// ...
} else {
if (anotherCondition) {
// ...
}
doSomething();
}
```
:::
## Options
This rule has no options.
## When Not To Use It
Disable this rule if the code is clearer without requiring the `else if` form.
---
---
title: no-loop-func
rule_type: suggestion
---
Writing functions within loops tends to result in errors due to the way the function creates a closure around the loop. For example:
```js
for (var i = 0; i < 10; i++) {
funcs[i] = function() {
return i;
};
}
```
In this case, you would expect each function created within the loop to return a different number. In reality, each function returns 10, because that was the last value of `i` in the scope.
`let` or `const` mitigate this problem.
```js
for (let i = 0; i < 10; i++) {
funcs[i] = function() {
return i;
};
}
```
In this case, each function created within the loop returns a different number as expected.
## Rule Details
This error is raised to highlight a piece of code that may not work as you expect it to and could also indicate a misunderstanding of how the language works. Your code may run without any problems if you do not fix this error, but in some situations it could behave unexpectedly.
This rule disallows any function within a loop that contains unsafe references (e.g. to modified variables from the outer scope). This rule ignores IIFEs but not async or generator functions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-loop-func: "error"*/
var i = 0;
while(i < 5) {
var a = function() { return i; };
a();
i++;
}
var i = 0;
do {
function a() { return i; };
a();
i++
} while (i < 5);
let foo = 0;
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
foo += 1;
}
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
}
foo = 100;
var arr = [];
for (var i = 0; i < 5; i++) {
arr.push((f => f)(() => i));
}
for (var i = 0; i < 5; i++) {
arr.push((() => {
return () => i;
})());
}
for (var i = 0; i < 5; i++) {
(function fun () {
if (arr.includes(fun)) return i;
else arr.push(fun);
})();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-loop-func: "error"*/
var a = function() {};
for (var i=10; i; i--) {
a();
}
for (var i=10; i; i--) {
var a = function() {}; // OK, no references to variables in the outer scopes.
a();
}
for (let i=10; i; i--) {
var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
for (const i of foo) {
var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
for (using i of foo) {
var a = function() { return i; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
for (var i=10; i; i--) {
const foo = getsomething(i);
var a = function() { return foo; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
for (var i=10; i; i--) {
using foo = getsomething(i);
var a = function() { return foo; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
for (var i=10; i; i--) {
await using foo = getsomething(i);
var a = function() { return foo; }; // OK, all references are referring to block scoped variables in the loop.
a();
}
var foo = 100;
for (let i=10; i; i--) {
var a = function() { return foo; }; // OK, all references are referring to never modified variables.
a();
}
//... no modifications of foo after this loop ...
var arr = [];
for (var i=10; i; i--) {
(function() { return i; })();
}
for (var i = 0; i < 5; i++) {
arr.push((f => f)((() => i)()));
}
for (var i = 0; i < 5; i++) {
arr.push((() => {
return (() => i)();
})());
}
```
:::
This rule additionally supports TypeScript type syntax.
Examples of **correct** TypeScript code for this rule:
::: correct
```ts
/*eslint no-loop-func: "error"*/
type MyType = 1;
let someArray: MyType[] = [];
for (let i = 0; i < 10; i += 1) {
someArray = someArray.filter((item: MyType) => !!item);
}
```
:::
## Options
This rule has no options.
## Known Limitations
The rule cannot identify whether the function instance is just immediately invoked and then discarded, or possibly stored for later use.
```js
const foo = [1, 2, 3, 4];
var i = 0;
while(foo.some(e => e > i)){
i += 1;
}
```
Here the `some` method immediately executes the callback function for each element in the array and then discards the function instance. The function is not stored or reused beyond the scope of the loop iteration. So, this will work as intended.
`eslint-disable` comments can be used in such cases.
---
---
title: no-loss-of-precision
rule_type: problem
---
This rule would disallow the use of number literals that lose precision at runtime when converted to a JS `Number` due to 64-bit floating-point rounding.
## Rule Details
In JS, `Number`s are stored as double-precision floating-point numbers according to the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754). Because of this, numbers can only retain accuracy up to a certain amount of digits. If the programmer enters additional digits, those digits will be lost in the conversion to the `Number` type and will result in unexpected behavior.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-loss-of-precision: "error"*/
const a = 9007199254740993
const b = 5123000000000000000000000000001
const c = 1230000000000000000000000.0
const d = .1230000000000000000000000
const e = 0X20000000000001
const f = 0X2_000000000_0001;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-loss-of-precision: "error"*/
const a = 12345
const b = 123.456
const c = 123e34
const d = 12300000000000000000000000
const e = 0x1FFFFFFFFFFFFF
const f = 9007199254740991
const g = 9007_1992547409_91
```
:::
## Options
This rule has no options.
---
---
title: no-magic-numbers
rule_type: suggestion
---
'Magic numbers' are numbers that occur multiple times in code without an explicit meaning.
They should preferably be replaced by named constants.
```js
const now = Date.now(),
inOneHour = now + (60 * 60 * 1000);
```
## Rule Details
The `no-magic-numbers` rule aims to make code more readable and refactoring easier by ensuring that special numbers
are declared as constants to make their meaning explicit.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-magic-numbers: "error"*/
const dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * 0.25);
```
:::
::: incorrect
```js
/*eslint no-magic-numbers: "error"*/
const data = ['foo', 'bar', 'baz'];
const dataLast = data[2];
```
:::
::: incorrect
```js
/*eslint no-magic-numbers: "error"*/
let SECONDS;
SECONDS = 60;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-magic-numbers: "error"*/
const TAX = 0.25;
const dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * TAX);
```
:::
## Options
### ignore
An array of numbers to ignore. It's set to `[]` by default.
If provided, it must be an `Array`.
The array can contain values of `number` and `string` types.
If it's a string, the text must be parsed as `bigint` literal (e.g., `"100n"`).
Examples of **correct** code for the sample `{ "ignore": [1] }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignore": [1] }]*/
const data = ['foo', 'bar', 'baz'];
const dataLast = data.length && data[data.length - 1];
```
:::
Examples of **correct** code for the sample `{ "ignore": ["1n"] }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignore": ["1n"] }]*/
foo(1n);
```
:::
### ignoreArrayIndexes
A boolean to specify if numbers used in the context of array indexes (e.g., `data[2]`) are considered okay. `false` by default.
This option allows only valid array indexes: numbers that will be coerced to one of `"0"`, `"1"`, `"2"` ... `"4294967294"`.
Arrays are objects, so they can have property names such as `"-1"` or `"2.5"`. However, those are just "normal" object properties that don't represent array elements. They don't influence the array's `length`, and they are ignored by array methods like `.map` or `.forEach`.
Additionally, since the maximum [array length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) is 232 - 1, all values above 232 - 2 also represent just normal property names and are thus not considered to be array indexes.
Examples of **correct** code for the `{ "ignoreArrayIndexes": true }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/
const item = data[2];
data[100] = a;
f(data[0]);
a = data[-0]; // same as data[0], -0 will be coerced to "0"
a = data[+1]; // same as data[1], +1 will be coerced to "1"
a = data[0xAB];
a = data[5.6e1];
a = data[10n]; // same as data[10], 10n will be coerced to "10"
a = data[4294967294]; // max array index
```
:::
Examples of **incorrect** code for the `{ "ignoreArrayIndexes": true }` option:
::: incorrect
```js
/*eslint no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/
f(2); // not used as array index
a = data[-1];
a = data[2.5];
a = data[5.67e1];
a = data[-10n];
a = data[4294967295]; // above the max array index
a = data[1e500]; // same as data["Infinity"]
```
:::
### ignoreDefaultValues
A boolean to specify if numbers used in default value assignments are considered okay. `false` by default.
Examples of **correct** code for the `{ "ignoreDefaultValues": true }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignoreDefaultValues": true }]*/
const { tax = 0.25 } = accountancy;
function mapParallel(concurrency = 3) { /***/ }
```
:::
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignoreDefaultValues": true }]*/
let head;
[head = 100] = []
```
:::
### ignoreClassFieldInitialValues
A boolean to specify if numbers used as initial values of class fields are considered okay. `false` by default.
Examples of **correct** code for the `{ "ignoreClassFieldInitialValues": true }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "ignoreClassFieldInitialValues": true }]*/
class C {
foo = 2;
bar = -3;
tux = +1;
#baz = 4;
static qux = 5;
}
```
:::
Examples of **incorrect** code for the `{ "ignoreClassFieldInitialValues": true }` option:
::: incorrect
```js
/*eslint no-magic-numbers: ["error", { "ignoreClassFieldInitialValues": true }]*/
class C {
foo = 2 + 3;
}
class D {
2;
}
```
:::
### enforceConst
A boolean to specify if we should check for the const keyword in variable declaration of numbers. `false` by default.
Examples of **incorrect** code for the `{ "enforceConst": true }` option:
::: incorrect
```js
/*eslint no-magic-numbers: ["error", { "enforceConst": true }]*/
let TAX = 0.25;
let dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * TAX);
```
:::
### detectObjects
A boolean to specify if we should detect numbers when setting object properties for example. `false` by default.
Examples of **incorrect** code for the `{ "detectObjects": true }` option:
::: incorrect
```js
/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/
const magic = {
tax: 0.25
};
const dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * magic.tax);
```
:::
Examples of **correct** code for the `{ "detectObjects": true }` option:
::: correct
```js
/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/
const TAX = 0.25;
const magic = {
tax: TAX
};
const dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * magic.tax);
```
:::
### ignoreEnums (TypeScript only)
Whether enums used in TypeScript are considered okay. `false` by default.
Examples of **incorrect** code for the `{ "ignoreEnums": false }` option:
::: incorrect
```ts
/*eslint no-magic-numbers: ["error", { "ignoreEnums": false }]*/
enum foo {
SECOND = 1000,
}
```
:::
Examples of **correct** code for the `{ "ignoreEnums": true }` option:
::: correct
```ts
/*eslint no-magic-numbers: ["error", { "ignoreEnums": true }]*/
enum foo {
SECOND = 1000,
}
```
:::
### ignoreNumericLiteralTypes (TypeScript only)
Whether numbers used in TypeScript numeric literal types are considered okay. `false` by default.
Examples of **incorrect** code for the `{ "ignoreNumericLiteralTypes": false }` option:
::: incorrect
```ts
/*eslint no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": false }]*/
type Foo = 1 | 2 | 3;
```
:::
Examples of **correct** code for the `{ "ignoreNumericLiteralTypes": true }` option:
::: correct
```ts
/*eslint no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": true }]*/
type Foo = 1 | 2 | 3;
```
:::
### ignoreReadonlyClassProperties (TypeScript only)
Whether numbers used in TypeScript readonly class properties are considered okay. `false` by default.
Examples of **incorrect** code for the `{ "ignoreReadonlyClassProperties": false }` option:
::: incorrect
```ts
/*eslint no-magic-numbers: ["error", { "ignoreReadonlyClassProperties": false }]*/
class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
```
:::
Examples of **correct** code for the `{ "ignoreReadonlyClassProperties": true }` option:
::: correct
```ts
/*eslint no-magic-numbers: ["error", { "ignoreReadonlyClassProperties": true }]*/
class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
```
:::
### ignoreTypeIndexes (TypeScript only)
Whether numbers used to index types are okay. `false` by default.
Examples of **incorrect** code for the `{ "ignoreTypeIndexes": false }` option:
::: incorrect
```ts
/*eslint no-magic-numbers: ["error", { "ignoreTypeIndexes": false }]*/
type Foo = Bar[0];
type Baz = Parameters[2];
```
:::
Examples of **correct** code for the `{ "ignoreTypeIndexes": true }` option:
::: correct
```ts
/*eslint no-magic-numbers: ["error", { "ignoreTypeIndexes": true }]*/
type Foo = Bar[0];
type Baz = Parameters[2];
```
:::
---
---
title: no-misleading-character-class
rule_type: problem
---
Unicode includes characters which are made by multiple code points.
RegExp character class syntax (`/[abc]/`) cannot handle characters which are made by multiple code points as a character; those characters will be dissolved to each code point. For example, `❇️` is made by `❇` (`U+2747`) and VARIATION SELECTOR-16 (`U+FE0F`). If this character is in a RegExp character class, it will match either `❇` (`U+2747`) or VARIATION SELECTOR-16 (`U+FE0F`) rather than `❇️`.
This rule reports regular expressions which include multiple code point characters in character class syntax. This rule considers the following characters as multiple code point characters.
**A character with combining characters:**
The combining characters are characters which belong to one of `Mc`, `Me`, and `Mn` [Unicode general categories](http://www.unicode.org/L2/L1999/UnicodeData.html#General%20Category).
```js
/^[Á]$/u.test("Á"); //→ false
/^[❇️]$/u.test("❇️"); //→ false
```
**A character with Emoji modifiers:**
```js
/^[👶🏻]$/u.test("👶🏻"); //→ false
/^[👶🏽]$/u.test("👶🏽"); //→ false
```
**A pair of regional indicator symbols:**
```js
/^[🇯🇵]$/u.test("🇯🇵"); //→ false
```
**Characters that ZWJ joins:**
```js
/^[👨👩👦]$/u.test("👨👩👦"); //→ false
```
**A surrogate pair without Unicode flag:**
```js
/^[👍]$/.test("👍"); //→ false
// Surrogate pair is OK if with u flag.
/^[👍]$/u.test("👍"); //→ true
```
## Rule Details
This rule reports regular expressions which include multiple code point characters in character class syntax.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-misleading-character-class: error */
/^[Á]$/u;
/^[❇️]$/u;
/^[👶🏻]$/u;
/^[🇯🇵]$/u;
/^[👨👩👦]$/u;
/^[👍]$/;
new RegExp("[🎵]");
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-misleading-character-class: error */
/^[abc]$/;
/^[👍]$/u;
/^[\q{👶🏻}]$/v;
new RegExp("^[]$");
new RegExp(`[Á-${z}]`, "u"); // variable pattern
```
:::
## Options
This rule has an object option:
* `"allowEscape"`: When set to `true`, the rule allows any grouping of code points inside a character class as long as they are written using escape sequences. This option only has effect on regular expression literals and on regular expressions created with the `RegExp` constructor with a literal argument as a pattern.
### allowEscape
Examples of **incorrect** code for this rule with the `{ "allowEscape": true }` option:
::: incorrect
```js
/* eslint no-misleading-character-class: ["error", { "allowEscape": true }] */
/[\👍]/; // backslash can be omitted
new RegExp("[\ud83d" + "\udc4d]");
const pattern = "[\ud83d\udc4d]";
new RegExp(pattern);
```
:::
Examples of **correct** code for this rule with the `{ "allowEscape": true }` option:
::: correct
```js
/* eslint no-misleading-character-class: ["error", { "allowEscape": true }] */
/[\ud83d\udc4d]/;
/[\u00B7\u0300-\u036F]/u;
/[👨\u200d👩]/u;
new RegExp("[\x41\u0301]");
new RegExp(`[\u{1F1EF}\u{1F1F5}]`, "u");
new RegExp("[\\u{1F1EF}\\u{1F1F5}]", "u");
```
:::
## When Not To Use It
You can turn this rule off if you don't want to check RegExp character class syntax for multiple code point characters.
---
---
title: no-mixed-operators
rule_type: suggestion
related_rules:
- no-extra-parens
---
Enclosing complex expressions by parentheses clarifies the developer's intention, which makes the code more readable.
This rule warns when different operators are used consecutively without parentheses in an expression.
```js
var foo = a && b || c || d; /*BAD: Unexpected mix of '&&' and '||'.*/
var foo = (a && b) || c || d; /*GOOD*/
var foo = a && (b || c || d); /*GOOD*/
```
**Note:**
It is expected for this rule to emit one error for each mixed operator in a pair. As a result, for each two consecutive mixed operators used, a distinct error will be displayed, pointing to where the specific operator that breaks the rule is used:
```js
var foo = a && b || c || d;
```
will generate
```shell
1:13 Unexpected mix of '&&' and '||'. (no-mixed-operators)
1:18 Unexpected mix of '&&' and '||'. (no-mixed-operators)
```
## Rule Details
This rule checks `BinaryExpression`, `LogicalExpression` and `ConditionalExpression`.
This rule may conflict with [no-extra-parens](no-extra-parens) rule.
If you use both this and [no-extra-parens](no-extra-parens) rule together, you need to use the `nestedBinaryExpressions` option of [no-extra-parens](no-extra-parens) rule.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-mixed-operators: "error"*/
var foo = a && b < 0 || c > 0 || d + 1 === 0;
var foo = a + b * c;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-mixed-operators: "error"*/
var foo = a || b || c;
var foo = a && b && c;
var foo = (a && b < 0) || c > 0 || d + 1 === 0;
var foo = a && (b < 0 || c > 0 || d + 1 === 0);
var foo = a + (b * c);
var foo = (a + b) * c;
```
:::
## Options
```json
{
"no-mixed-operators": [
"error",
{
"groups": [
["+", "-", "*", "/", "%", "**"],
["&", "|", "^", "~", "<<", ">>", ">>>"],
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["&&", "||"],
["in", "instanceof"]
],
"allowSamePrecedence": true
}
]
}
```
This rule has 2 options.
* `groups` (`string[][]`) - specifies operator groups to be checked. The `groups` option is a list of groups, and a group is a list of binary operators. Default operator groups are defined as arithmetic, bitwise, comparison, logical, and relational operators. Note: Ternary operator(?:) can be part of any group and by default is allowed to be mixed with other operators.
* `allowSamePrecedence` (`boolean`) - specifies whether to allow mixed operators if they are of equal precedence. Default is `true`.
### groups
The following operators can be used in `groups` option:
* Arithmetic Operators: `"+"`, `"-"`, `"*"`, `"/"`, `"%"`, `"**"`
* Bitwise Operators: `"&"`, `"|"`, `"^"`, `"~"`, `"<<"`, `">>"`, `">>>"`
* Comparison Operators: `"=="`, `"!="`, `"==="`, `"!=="`, `">"`, `">="`, `"<"`, `"<="`
* Logical Operators: `"&&"`, `"||"`
* Coalesce Operator: `"??"`
* Relational Operators: `"in"`, `"instanceof"`
* Ternary Operator: `?:`
Now, consider the following group configuration: `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}`.
There are 2 groups specified in this configuration: bitwise operators and logical operators.
This rule checks if the operators belong to the same group only.
In this case, this rule checks if bitwise operators and logical operators are mixed, but ignores all other operators.
Examples of **incorrect** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option:
::: incorrect
```js
/*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/
var foo = a && b < 0 || c > 0 || d + 1 === 0;
var foo = a & b | c;
```
:::
::: incorrect
```js
/*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/
var foo = a || b ? c : d;
var bar = a ? b || c : d;
var baz = a ? b : c || d;
```
:::
Examples of **correct** code for this rule with `{"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}` option:
::: correct
```js
/*eslint no-mixed-operators: ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}]*/
var foo = a || b > 0 || c + 1 === 0;
var foo = a && b > 0 && c + 1 === 0;
var foo = (a && b < 0) || c > 0 || d + 1 === 0;
var foo = a && (b < 0 || c > 0 || d + 1 === 0);
var foo = (a & b) | c;
var foo = a & (b | c);
var foo = a + b * c;
var foo = a + (b * c);
var foo = (a + b) * c;
```
:::
::: correct
```js
/*eslint no-mixed-operators: ["error", {"groups": [["&&", "||", "?:"]]}]*/
var foo = (a || b) ? c : d;
var foo = a || (b ? c : d);
var bar = a ? (b || c) : d;
var baz = a ? b : (c || d);
var baz = (a ? b : c) || d;
```
:::
### allowSamePrecedence
Examples of **correct** code for this rule with `{"allowSamePrecedence": true}` option:
::: correct
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": true}]*/
// + and - have the same precedence.
var foo = a + b - c;
```
:::
Examples of **incorrect** code for this rule with `{"allowSamePrecedence": false}` option:
::: incorrect
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/
// + and - have the same precedence.
var foo = a + b - c;
```
:::
Examples of **correct** code for this rule with `{"allowSamePrecedence": false}` option:
::: correct
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/
// + and - have the same precedence.
var foo = (a + b) - c;
```
:::
## When Not To Use It
If you don't want to be notified about mixed operators, then it's safe to disable this rule.
---
---
title: no-mixed-requires
rule_type: suggestion
---
In the Node.js community it is often customary to separate initializations with calls to `require` modules from other variable declarations, sometimes also grouping them by the type of module. This rule helps you enforce this convention.
## Rule Details
When this rule is enabled, each `var` statement must satisfy the following conditions:
* either none or all variable declarations must be require declarations (default)
* all require declarations must be of the same type (grouping)
This rule distinguishes between six kinds of variable declaration types:
* `core`: declaration of a required [core module][1]
* `file`: declaration of a required [file module][2]
* `module`: declaration of a required module from the [node_modules folder][3]
* `computed`: declaration of a required module whose type could not be determined (either because it is computed or because require was called without an argument)
* `uninitialized`: a declaration that is not initialized
* `other`: any other kind of declaration
In this document, the first four types are summed up under the term *require declaration*.
```js
var fs = require('fs'), // "core" \
async = require('async'), // "module" |- these are "require declaration"s
foo = require('./foo'), // "file" |
bar = require(getName()), // "computed" /
baz = 42, // "other"
bam; // "uninitialized"
```
## Options
This rule can have an object literal option whose two properties have `false` values by default.
Configuring this rule with one boolean option `true` is deprecated.
Examples of **incorrect** code for this rule with the default `{ "grouping": false, "allowCall": false }` options:
::: incorrect
```js
/*eslint no-mixed-requires: "error"*/
var fs = require('fs'),
i = 0;
var async = require('async'),
debug = require('diagnostics').someFunction('my-module'),
eslint = require('eslint');
```
:::
Examples of **correct** code for this rule with the default `{ "grouping": false, "allowCall": false }` options:
::: correct
```js
/*eslint no-mixed-requires: "error"*/
// only require declarations (grouping off)
var eventEmitter = require('events').EventEmitter,
myUtils = require('./utils'),
util = require('util'),
bar = require(getBarModuleName());
// only non-require declarations
var foo = 42,
bar = 'baz';
// always valid regardless of grouping because all declarations are of the same type
var foo = require('foo' + VERSION),
bar = require(getBarModuleName()),
baz = require();
```
:::
### grouping
Examples of **incorrect** code for this rule with the `{ "grouping": true }` option:
::: incorrect
```js
/*eslint no-mixed-requires: ["error", { "grouping": true }]*/
// invalid because of mixed types "core" and "module"
var fs = require('fs'),
async = require('async');
// invalid because of mixed types "file" and "unknown"
var foo = require('foo'),
bar = require(getBarModuleName());
```
:::
### allowCall
Examples of **incorrect** code for this rule with the `{ "allowCall": true }` option:
::: incorrect
```js
/*eslint no-mixed-requires: ["error", { "allowCall": true }]*/
var async = require('async'),
debug = require('diagnostics').someFunction('my-module'), /* allowCall doesn't allow calling any function */
eslint = require('eslint');
```
:::
Examples of **correct** code for this rule with the `{ "allowCall": true }` option:
::: correct
```js
/*eslint no-mixed-requires: ["error", { "allowCall": true }]*/
var async = require('async'),
debug = require('diagnostics')('my-module'),
eslint = require('eslint');
```
:::
## Known Limitations
* The implementation is not aware of any local functions with the name `require` that may shadow Node.js' global `require`.
* Internally, the list of core modules is retrieved via `require("repl")._builtinLibs`. If you use different versions of Node.js for ESLint and your application, the list of core modules for each version may be different.
The above mentioned `_builtinLibs` property became available in 0.8, for earlier versions a hardcoded list of module names is used as a fallback. If your version of Node.js is older than 0.6 that list may be inaccurate.
## When Not To Use It
If you use a pattern such as [UMD][4] where the `require`d modules are not loaded in variable declarations, this rule will obviously do nothing for you.
[1]: https://nodejs.org/api/modules.html#modules_core_modules
[2]: https://nodejs.org/api/modules.html#modules_file_modules
[3]: https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders
[4]: https://github.com/umdjs/umd
---
---
title: no-mixed-spaces-and-tabs
rule_type: layout
further_reading:
- https://www.emacswiki.org/emacs/SmartTabs
---
Most code conventions require either tabs or spaces be used for indentation. As such, it's usually an error if a single line of code is indented with both tabs and spaces.
## Rule Details
This rule disallows mixed spaces and tabs for indentation.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-mixed-spaces-and-tabs: "error"*/
function add(x, y) {
return x + y;
}
function main() {
var x = 5,
y = 7;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-mixed-spaces-and-tabs: "error"*/
function add(x, y) {
return x + y;
}
```
:::
## Options
This rule has a string option.
* `"smart-tabs"` allows mixed tabs and spaces when the spaces are used for alignment.
### smart-tabs
Examples of **correct** code for this rule with the `"smart-tabs"` option:
::: correct
```js
/*eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"]*/
function main() {
var x = 5,
y = 7;
}
```
:::
---
---
title: no-multi-assign
rule_type: suggestion
related_rules:
- max-statements-per-line
---
Chaining the assignment of variables can lead to unexpected results and be difficult to read.
```js
(function() {
const foo = bar = 0; // Did you mean `foo = bar == 0`?
bar = 1; // This will not fail since `bar` is not constant.
})();
console.log(bar); // This will output 1 since `bar` is not scoped.
```
## Rule Details
This rule disallows using multiple assignments within a single statement.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-multi-assign: "error"*/
let a = b = c = 5;
const foo = bar = "baz";
let d =
e =
c;
class Foo {
a = b = 10;
}
a = b = "quux";
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-multi-assign: "error"*/
let a = 5;
let b = 5;
const c = 5;
const foo = "baz";
const bar = "baz";
let d = c;
let e = c;
class Foo {
a = 10;
b = 10;
}
a = "quux";
b = "quux";
```
:::
## Options
This rule has an object option:
* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Default is `false`.
### ignoreNonDeclaration
Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option:
::: correct
```js
/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/
let a;
let b;
a = b = "baz";
const x = {};
const y = {};
x.one = y.one = 1;
```
:::
Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option:
::: incorrect
```js
/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/
let a = b = "baz";
const foo = bar = 1;
class Foo {
a = b = 10;
}
```
:::
---
---
title: no-multi-spaces
rule_type: layout
related_rules:
- key-spacing
- space-infix-ops
- space-in-brackets
- space-in-parens
- space-after-keywords
- space-unary-ops
- space-return-throw-case
---
Multiple spaces in a row that are not used for indentation are typically mistakes. For example:
```js
if(foo === "bar") {}
```
It's hard to tell, but there are two spaces between `foo` and `===`. Multiple spaces such as this are generally frowned upon in favor of single spaces:
```js
if(foo === "bar") {}
```
## Rule Details
This rule aims to disallow multiple whitespace around logical expressions, conditional expressions, declarations, array elements, object properties, sequences and function parameters.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-multi-spaces: "error"*/
var a = 1;
if(foo === "bar") {}
a << b
var arr = [1, 2];
a ? b: c
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-multi-spaces: "error"*/
var a = 1;
if(foo === "bar") {}
a << b
var arr = [1, 2];
a ? b: c
```
:::
## Options
This rule's configuration consists of an object with the following properties:
* `"ignoreEOLComments": true` (defaults to `false`) ignores multiple spaces before comments that occur at the end of lines
* `"exceptions": { "Property": true }` (`"Property"` is the only node specified by default) specifies nodes to ignore
### ignoreEOLComments
Examples of **incorrect** code for this rule with the `{ "ignoreEOLComments": false }` (default) option:
::: incorrect
```js
/*eslint no-multi-spaces: ["error", { ignoreEOLComments: false }]*/
var x = 5; // comment
var x = 5; /* multiline
* comment
*/
```
:::
Examples of **correct** code for this rule with the `{ "ignoreEOLComments": false }` (default) option:
::: correct
```js
/*eslint no-multi-spaces: ["error", { ignoreEOLComments: false }]*/
var x = 5; // comment
var x = 5; /* multiline
* comment
*/
```
:::
Examples of **correct** code for this rule with the `{ "ignoreEOLComments": true }` option:
::: correct
```js
/*eslint no-multi-spaces: ["error", { ignoreEOLComments: true }]*/
var x = 5; // comment
var x = 5; // comment
var x = 5; /* multiline
* comment
*/
var x = 5; /* multiline
* comment
*/
```
:::
### exceptions
To avoid contradictions with other rules that require multiple spaces, this rule has an `exceptions` option to ignore certain nodes.
This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use [AST Explorer](https://astexplorer.net/) with the espree parser.
Only the `Property` node type is ignored by default, because for the [key-spacing](key-spacing) rule some alignment options require multiple spaces in properties of object literals.
Examples of **correct** code for the default `"exceptions": { "Property": true }` option:
::: correct
```js
/*eslint no-multi-spaces: "error"*/
/*eslint key-spacing: ["error", { align: "value" }]*/
var obj = {
first: "first",
second: "second"
};
```
:::
Examples of **incorrect** code for the `"exceptions": { "Property": false }` option:
::: incorrect
```js
/*eslint no-multi-spaces: ["error", { exceptions: { "Property": false } }]*/
/*eslint key-spacing: ["error", { align: "value" }]*/
var obj = {
first: "first",
second: "second"
};
```
:::
Examples of **correct** code for the `"exceptions": { "BinaryExpression": true }` option:
::: correct
```js
/*eslint no-multi-spaces: ["error", { exceptions: { "BinaryExpression": true } }]*/
var a = 1 * 2;
```
:::
Examples of **correct** code for the `"exceptions": { "VariableDeclarator": true }` option:
::: correct
```js
/*eslint no-multi-spaces: ["error", { exceptions: { "VariableDeclarator": true } }]*/
var someVar = 'foo';
var someOtherVar = 'barBaz';
```
:::
Examples of **correct** code for the `"exceptions": { "ImportDeclaration": true }` option:
::: correct
```js
/*eslint no-multi-spaces: ["error", { exceptions: { "ImportDeclaration": true } }]*/
import mod from 'mod';
import someOtherMod from 'some-other-mod';
```
:::
## When Not To Use It
If you don't want to check and disallow multiple spaces, then you should turn this rule off.
---
---
title: no-multi-str
rule_type: suggestion
---
It's possible to create multiline strings in JavaScript by using a slash before a newline, such as:
```js
const x = "Line 1 \
Line 2";
```
Some consider this to be a bad practice as it was an undocumented feature of JavaScript that was only formalized later.
## Rule Details
This rule is aimed at preventing the use of multiline strings.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-multi-str: "error"*/
const x = "some very \
long text";
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-multi-str: "error"*/
const x = "some very long text";
const y = "some very " +
"long text";
```
:::
## Options
This rule has no options.
---
---
title: no-multiple-empty-lines
rule_type: layout
---
Some developers prefer to have multiple blank lines removed, while others feel that it helps improve readability. Whitespace is useful for separating logical sections of code, but excess whitespace takes up more of the screen.
## Rule Details
This rule aims to reduce the scrolling required when reading through your code. It will warn when the maximum amount of empty lines has been exceeded.
## Options
This rule has an object option:
* `"max"` (default: `2`) enforces a maximum number of consecutive empty lines.
* `"maxEOF"` enforces a maximum number of consecutive empty lines at the end of files.
* `"maxBOF"` enforces a maximum number of consecutive empty lines at the beginning of files.
### max
Examples of **incorrect** code for this rule with the default `{ "max": 2 }` option:
::: incorrect
```js
/*eslint no-multiple-empty-lines: "error"*/
var foo = 5;
var bar = 3;
```
:::
Examples of **correct** code for this rule with the default `{ "max": 2 }` option:
::: correct
```js
/*eslint no-multiple-empty-lines: "error"*/
var foo = 5;
var bar = 3;
```
:::
### maxEOF
Examples of **incorrect** code for this rule with the `{ max: 2, maxEOF: 0 }` options:
::: incorrect
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎
⏎
var foo = 5;⏎
⏎
⏎
var bar = 3;⏎
⏎
```
:::
Examples of **correct** code for this rule with the `{ max: 2, maxEOF: 0 }` options:
::: correct
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎
⏎
var foo = 5;⏎
⏎
⏎
var bar = 3;
```
:::
**Note**: Although this ensures zero empty lines at the EOF, most editors will still show one empty line at the end if the file ends with a line break, as illustrated below. There is no empty line at the end of a file after the last `\n`, although editors may show an additional line. A true additional line would be represented by `\n\n`.
**Correct**:
::: correct
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎
⏎
var foo = 5;⏎
⏎
⏎
var bar = 3;⏎
```
:::
### maxBOF
Examples of **incorrect** code for this rule with the `{ max: 2, maxBOF: 1 }` options:
::: incorrect
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1 }]*/
var foo = 5;
var bar = 3;
```
:::
Examples of **correct** code for this rule with the `{ max: 2, maxBOF: 1 }` options:
::: correct
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1}]*/
var foo = 5;
var bar = 3;
```
:::
::: correct
```js
/*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxBOF": 1}]*/
var foo = 5;
var bar = 3;
```
:::
## When Not To Use It
If you do not care about extra blank lines, turn this off.
---
---
title: no-native-reassign
rule_type: suggestion
related_rules:
- no-extend-native
- no-redeclare
- no-shadow
---
JavaScript environments contain a number of built-in global variables, such as `window` in browsers and `process` in Node.js. In almost all cases, you don't want to assign a value to these global variables as doing so could result in losing access to important functionality. For example, you probably don't want to do this in browser code:
```js
window = {};
```
While examples such as `window` are obvious, there are often hundreds of built-in global objects provided by JavaScript environments. It can be hard to know if you're assigning to a global variable or not.
## Rule Details
This rule disallows modifications to read-only global variables.
ESLint has the capability to configure global variables as read-only.
See also: [Specifying Globals](../use/configure#specifying-globals)
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-native-reassign: "error"*/
Object = null
undefined = 1
```
:::
::: incorrect
```js
/*eslint no-native-reassign: "error"*/
/*global window:readonly*/
window = {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-native-reassign: "error"*/
a = 1
var b = 1
b = 2
```
:::
::: correct
```js
/*eslint no-native-reassign: "error"*/
/*global onload:writable*/
onload = function() {}
```
:::
## Options
This rule accepts an `exceptions` option, which can be used to specify a list of builtins for which reassignments will be allowed:
```json
{
"rules": {
"no-native-reassign": ["error", {"exceptions": ["Object"]}]
}
}
```
## When Not To Use It
If you are trying to override one of the native objects.
---
---
title: no-negated-condition
rule_type: suggestion
---
Negated conditions are more difficult to understand. Code can be made more readable by inverting the condition instead.
## Rule Details
This rule disallows negated conditions in either of the following:
* `if` statements which have an `else` branch
* ternary expressions
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-negated-condition: "error"*/
if (!a) {
doSomething();
} else {
doSomethingElse();
}
if (a != b) {
doSomething();
} else {
doSomethingElse();
}
if (a !== b) {
doSomething();
} else {
doSomethingElse();
}
!a ? c : b
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-negated-condition: "error"*/
if (!a) {
doSomething();
}
if (!a) {
doSomething();
} else if (b) {
doSomething();
}
if (a != b) {
doSomething();
}
a ? b : c
```
:::
## Options
This rule has no options.
---
---
title: no-negated-in-lhs
rule_type: problem
---
Just as developers might type `-a + b` when they mean `-(a + b)` for the negative of a sum, they might type `!key in object` by mistake when they almost certainly mean `!(key in object)` to test that a key is not in an object.
## Rule Details
This rule disallows negating the left operand in `in` expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-negated-in-lhs: "error"*/
if(!key in object) {
// operator precedence makes it equivalent to (!key) in object
// and type conversion makes it equivalent to (key ? "false" : "true") in object
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-negated-in-lhs: "error"*/
if(!(key in object)) {
// key is not in object
}
if(('' + !key) in object) {
// make operator precedence and type conversion explicit
// in a rare situation when that is the intended meaning
}
```
:::
## When Not To Use It
Never.
---
---
title: no-nested-ternary
rule_type: suggestion
related_rules:
- no-ternary
- no-unneeded-ternary
---
Nesting ternary expressions can make code more difficult to understand.
```js
const foo = bar ? baz : qux === quxx ? bing : bam;
```
## Rule Details
The `no-nested-ternary` rule disallows nested ternary expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-nested-ternary: "error"*/
const thing = foo ? bar : baz === qux ? quxx : foobar;
foo ? baz === qux ? quxx() : foobar() : bar();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-nested-ternary: "error"*/
const thing = foo ? bar : foobar;
let otherThing;
if (foo) {
otherThing = bar;
} else if (baz === qux) {
otherThing = quxx;
} else {
otherThing = foobar;
}
```
:::
## Options
This rule has no options.
---
---
title: no-new-func
rule_type: suggestion
---
It's possible to create functions in JavaScript from strings at runtime using the `Function` constructor, such as:
```js
const a = new Function("a", "b", "return a + b");
const b = Function("a", "b", "return a + b");
const c = Function.call(null, "a", "b", "return a + b");
const d = Function.apply(null, ["a", "b", "return a + b"]);
const x = Function.bind(null, "a", "b", "return a + b")();
```
This is considered by many to be a bad practice due to the difficulty in debugging and reading these types of functions. In addition, Content-Security-Policy (CSP) directives may disallow the use of `eval()` and similar methods for creating code from strings.
## Rule Details
This error is raised to highlight the use of a bad practice. By passing a string to the `Function` constructor, you are requiring the engine to parse that string much in the way it has to when you call the `eval` function.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-func: "error"*/
const a = new Function("a", "b", "return a + b");
const b = Function("a", "b", "return a + b");
const c = Function.call(null, "a", "b", "return a + b");
const d = Function.apply(null, ["a", "b", "return a + b"]);
const x = Function.bind(null, "a", "b", "return a + b")();
const y = Function.bind(null, "a", "b", "return a + b"); // assuming that the result of Function.bind(...) will be eventually called.
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-func: "error"*/
const x = function (a, b) {
return a + b;
};
```
:::
## Options
This rule has no options.
## When Not To Use It
In more advanced cases where you really need to use the `Function` constructor.
---
---
title: no-new-native-nonconstructor
layout: doc
rule_type: problem
handled_by_typescript: true
related_rules:
- no-obj-calls
further_reading:
- https://tc39.es/ecma262/#sec-symbol-constructor
- https://tc39.es/ecma262/#sec-bigint-constructor
---
It is a convention in JavaScript that global variables beginning with an uppercase letter typically represent classes that can be instantiated using the `new` operator, such as `new Array` and `new Map`. Confusingly, JavaScript also provides some global variables that begin with an uppercase letter that cannot be called using the `new` operator and will throw an error if you attempt to do so. These are typically functions that are related to data types and are easy to mistake for classes. Consider the following example:
```js
// throws a TypeError
const foo = new Symbol("foo");
// throws a TypeError
const result = new BigInt(9007199254740991);
```
Both `new Symbol` and `new BigInt` throw a type error because they are functions and not classes. It is easy to make this mistake by assuming the uppercase letters indicate classes.
## Rule Details
This rule is aimed at preventing the accidental calling of native JavaScript global functions with the `new` operator. These functions are:
* `Symbol`
* `BigInt`
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-native-nonconstructor: "error"*/
const foo = new Symbol('foo');
const bar = new BigInt(9007199254740991);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-native-nonconstructor: "error"*/
const foo = Symbol('foo');
const bar = BigInt(9007199254740991);
// Ignores shadowed Symbol.
function baz(Symbol) {
const qux = new Symbol("baz");
}
function quux(BigInt) {
const corge = new BigInt(9007199254740991);
}
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
---
---
title: no-new-object
rule_type: suggestion
related_rules:
- no-array-constructor
- no-new-wrappers
---
The `Object` constructor is used to create new generic objects in JavaScript, such as:
```js
var myObject = new Object();
```
However, this is no different from using the more concise object literal syntax:
```js
var myObject = {};
```
For this reason, many prefer to always use the object literal syntax and never use the `Object` constructor.
While there are no performance differences between the two approaches, the byte savings and conciseness of the object literal form is what has made it the de facto way of creating new objects.
## Rule Details
This rule disallows calling the `Object` constructor with `new`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-object: "error"*/
var myObject = new Object();
new Object();
var foo = new Object("foo");
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-object: "error"*/
var myObject = new CustomObject();
var myObject = {};
var Object = function Object() {};
new Object();
var foo = Object("foo");
```
:::
## When Not To Use It
If you wish to allow the use of the `Object` constructor with `new`, you can safely turn this rule off.
---
---
title: no-new-require
rule_type: suggestion
---
The `require` function is used to include modules that exist in separate files, such as:
```js
var appHeader = require('app-header');
```
Some modules return a constructor which can potentially lead to code such as:
```js
var appHeader = new require('app-header');
```
Unfortunately, this introduces a high potential for confusion since the code author likely meant to write:
```js
var appHeader = new (require('app-header'));
```
For this reason, it is usually best to disallow this particular expression.
## Rule Details
This rule aims to eliminate use of the `new require` expression.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-require: "error"*/
var appHeader = new require('app-header');
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-require: "error"*/
var AppHeader = require('app-header');
var appHeader = new AppHeader();
```
:::
## When Not To Use It
If you are using a custom implementation of `require` and your code will never be used in projects where a standard `require` (CommonJS, Node.js, AMD) is expected, you can safely turn this rule off.
---
---
title: no-new-symbol
rule_type: problem
handled_by_typescript: true
further_reading:
- https://www.ecma-international.org/ecma-262/6.0/#sec-symbol-objects
---
`Symbol` is not intended to be used with the `new` operator, but to be called as a function.
```js
var foo = new Symbol("foo");
```
This throws a `TypeError` exception.
## Rule Details
This rule is aimed at preventing the accidental calling of `Symbol` with the `new` operator.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-symbol: "error"*/
var foo = new Symbol('foo');
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-symbol: "error"*/
var foo = Symbol('foo');
// Ignores shadowed Symbol.
function bar(Symbol) {
const baz = new Symbol("baz");
}
```
:::
## When Not To Use It
This rule should not be used in ES3/5 environments.
---
---
title: no-new-wrappers
rule_type: suggestion
related_rules:
- no-array-constructor
- no-object-constructor
further_reading:
- https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-3/wrapper-objects
---
There are three primitive types in JavaScript that have wrapper objects: string, number, and boolean. These are represented by the constructors `String`, `Number`, and `Boolean`, respectively. The primitive wrapper types are used whenever one of these primitive values is read, providing them with object-like capabilities such as methods. Behind the scenes, an object of the associated wrapper type is created and then destroyed, which is why you can call methods on primitive values, such as:
```js
const text = "Hello world".substring(2);
```
Behind the scenes in this example, a `String` object is constructed. The `substring()` method exists on `String.prototype` and so is accessible to the string instance.
It's also possible to manually create a new wrapper instance:
```js
const stringObject = new String("Hello world");
const numberObject = new Number(33);
const booleanObject = new Boolean(false);
```
Although possible, there aren't any good reasons to use these primitive wrappers as constructors. They tend to confuse other developers more than anything else because they seem like they should act as primitives, but they do not. For example:
```js
const stringObject = new String("Hello world");
console.log(typeof stringObject); // "object"
const text = "Hello world";
console.log(typeof text); // "string"
const booleanObject = new Boolean(false);
if (booleanObject) { // all objects are truthy!
console.log("This executes");
}
```
The first problem is that primitive wrapper objects are, in fact, objects. That means `typeof` will return `"object"` instead of `"string"`, `"number"`, or `"boolean"`. The second problem comes with boolean objects. Every object is truthy, that means an instance of `Boolean` always resolves to `true` even when its actual value is `false`.
For these reasons, it's considered a best practice to avoid using primitive wrapper types with `new`.
## Rule Details
This rule aims to eliminate the use of `String`, `Number`, and `Boolean` with the `new` operator. As such, it warns whenever it sees `new String`, `new Number`, or `new Boolean`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new-wrappers: "error"*/
const stringObject = new String("Hello world");
const numberObject = new Number(33);
const booleanObject = new Boolean(false);
const stringObject2 = new String;
const numberObject2 = new Number;
const booleanObject2 = new Boolean;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new-wrappers: "error"*/
const text = String(someValue);
const num = Number(someValue);
const object = new MyString();
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow the use of primitive wrapper objects, then you can safely disable this rule.
---
---
title: no-new
rule_type: suggestion
---
The goal of using `new` with a constructor is typically to create an object of a particular type and store that object in a variable, such as:
```js
const person = new Person();
```
It's less common to use `new` and not store the result, such as:
```js
new Person();
```
In this case, the created object is thrown away because its reference isn't stored anywhere, and in many cases, this means that the constructor should be replaced with a function that doesn't require `new` to be used.
## Rule Details
This rule is aimed at maintaining consistency and convention by disallowing constructor calls using the `new` keyword that do not assign the resulting object to a variable.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-new: "error"*/
new Thing();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-new: "error"*/
const thing = new Thing();
Foo();
```
:::
## Options
This rule has no options.
---
---
title: no-nonoctal-decimal-escape
rule_type: suggestion
related_rules:
- no-octal-escape
further_reading:
- https://tc39.es/ecma262/#prod-annexB-NonOctalDecimalEscapeSequence
---
Although not being specified in the language until ECMAScript 2021, `\8` and `\9` escape sequences in string literals were allowed in most JavaScript engines, and treated as "useless" escapes:
```js
"\8" === "8"; // true
"\9" === "9"; // true
```
Since ECMAScript 2021, these escape sequences are specified as [non-octal decimal escape sequences](https://tc39.es/ecma262/#prod-annexB-NonOctalDecimalEscapeSequence), retaining the same behavior.
Nevertheless, the ECMAScript specification treats `\8` and `\9` in string literals as a legacy feature. This syntax is optional if the ECMAScript host is not a web browser. Browsers still have to support it, but only in non-strict mode.
Regardless of your targeted environment, these escape sequences shouldn't be used when writing new code.
## Rule Details
This rule disallows `\8` and `\9` escape sequences in string literals.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-nonoctal-decimal-escape: "error"*/
"\8";
"\9";
const foo = "w\8less";
const bar = "December 1\9";
const baz = "Don't use \8 and \9 escapes.";
const quux = "\0\8";
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-nonoctal-decimal-escape: "error"*/
"8";
"9";
const foo = "w8less";
const bar = "December 19";
const baz = "Don't use \\8 and \\9 escapes.";
const quux = "\0\u0038";
```
:::
## Options
This rule has no options.
---
---
title: no-obj-calls
rule_type: problem
handled_by_typescript: true
further_reading:
- https://es5.github.io/#x15.8
---
ECMAScript provides several global objects that are intended to be used as-is. Some of these objects look as if they could be constructors due their capitalization (such as `Math` and `JSON`) but will throw an error if you try to execute them as functions.
The [ECMAScript 5 specification](https://es5.github.io/#x15.8) makes it clear that both `Math` and `JSON` cannot be invoked:
> The Math object does not have a `[[Call]]` internal property; it is not possible to invoke the Math object as a function.
The [ECMAScript 2015 specification](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect-object) makes it clear that `Reflect` cannot be invoked:
> The Reflect object also does not have a `[[Call]]` internal method; it is not possible to invoke the Reflect object as a function.
The [ECMAScript 2017 specification](https://www.ecma-international.org/ecma-262/8.0/index.html#sec-atomics-object) makes it clear that `Atomics` cannot be invoked:
> The Atomics object does not have a `[[Call]]` internal method; it is not possible to invoke the Atomics object as a function.
And the [ECMAScript Internationalization API Specification](https://tc39.es/ecma402/#intl-object) makes it clear that `Intl` cannot be invoked:
> The Intl object does not have a `[[Call]]` internal method; it is not possible to invoke the Intl object as a function.
## Rule Details
This rule disallows calling the `Math`, `JSON`, `Reflect`, `Atomics` and `Intl` objects as functions.
This rule also disallows using these objects as constructors with the `new` operator.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-obj-calls: "error"*/
const math = Math();
const newMath = new Math();
const json = JSON();
const newJSON = new JSON();
const reflect = Reflect();
const newReflect = new Reflect();
const atomics = Atomics();
const newAtomics = new Atomics();
const intl = Intl();
const newIntl = new Intl();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-obj-calls: "error"*/
function area(r) {
return Math.PI * r * r;
}
const object = JSON.parse("{}");
const value = Reflect.get({ x: 1, y: 2 }, "x");
const first = Atomics.load(foo, 0);
const segmenterFr = new Intl.Segmenter("fr", { granularity: "word" });
```
:::
## Options
This rule has no options.
---
---
title: no-object-constructor
rule_type: suggestion
related_rules:
- no-array-constructor
- no-new-wrappers
---
Use of the `Object` constructor to construct a new empty object is generally discouraged in favor of object literal notation because of conciseness and because the `Object` global may be redefined.
The exception is when the `Object` constructor is used to intentionally wrap a specified value which is passed as an argument.
## Rule Details
This rule disallows calling the `Object` constructor without an argument.
Examples of **incorrect** code for this rule:
:::incorrect
```js
/*eslint no-object-constructor: "error"*/
Object();
new Object();
```
:::
Examples of **correct** code for this rule:
:::correct
```js
/*eslint no-object-constructor: "error"*/
Object("foo");
const obj = { a: 1, b: 2 };
const isObject = value => value === Object(value);
const createObject = Object => new Object();
```
:::
## Options
This rule has no options.
## When Not To Use It
If you wish to allow the use of the `Object` constructor, you can safely turn this rule off.
---
---
title: no-octal-escape
rule_type: suggestion
---
As of the ECMAScript 5 specification, octal escape sequences in string literals are deprecated and should not be used. Unicode escape sequences should be used instead.
```js
const foo = "Copyright \251";
```
## Rule Details
This rule disallows octal escape sequences in string literals.
If ESLint parses code in strict mode, the parser (instead of this rule) reports the error.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-octal-escape: "error"*/
const foo = "Copyright \251";
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-octal-escape: "error"*/
const foo = "Copyright \u00A9"; // unicode
const buz = "Copyright \xA9"; // hexadecimal
```
:::
## Options
This rule has no options.
---
---
title: no-octal
rule_type: suggestion
---
Octal literals are numerals that begin with a leading zero, such as:
```js
const num = 071; // 57
```
Because the leading zero which identifies an octal literal has been a source of confusion and error in JavaScript code, ECMAScript 5 deprecates the use of octal numeric literals.
## Rule Details
The rule disallows octal literals.
If ESLint parses code in strict mode, the parser (instead of this rule) reports the error.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-octal: "error"*/
const num = 071;
const result = 5 + 07;
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-octal: "error"*/
const num = "071";
```
:::
## Options
This rule has no options.
## Compatibility
* **JSHint**: W115
---
---
title: no-param-reassign
rule_type: suggestion
further_reading:
- https://spin.atomicobject.com/2011/04/10/javascript-don-t-reassign-your-function-arguments/
---
Assignment to variables declared as function parameters can be misleading and lead to confusing behavior, as modifying function parameters will also mutate the `arguments` object when not in `strict` mode (see [When Not To Use It](#when-not-to-use-it) below). Often, assignment to function parameters is unintended and indicative of a mistake or programmer error.
This rule can be also configured to fail when function parameters are modified. Side effects on parameters can cause counter-intuitive execution flow and make errors difficult to track down.
## Rule Details
This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-param-reassign: "error"*/
const foo = function(bar) {
bar = 13;
}
const foo1 = function(bar) {
bar++;
}
const foo2 = function(bar) {
for (bar in baz) {}
}
const foo3 = function(bar) {
for (bar of baz) {}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-param-reassign: "error"*/
const foo = function(bar) {
const baz = bar;
}
```
:::
## Options
This rule takes one option, an object, with a boolean property `"props"`, and arrays `"ignorePropertyModificationsFor"` and `"ignorePropertyModificationsForRegex"`. `"props"` is `false` by default. If `"props"` is set to `true`, this rule warns against the modification of parameter properties unless they're included in `"ignorePropertyModificationsFor"` or `"ignorePropertyModificationsForRegex"`, which is an empty array by default.
### props
Examples of **correct** code for the default `{ "props": false }` option:
::: correct
```js
/*eslint no-param-reassign: ["error", { "props": false }]*/
const foo = function(bar) {
bar.prop = "value";
}
const foo1 = function(bar) {
delete bar.aaa;
}
const foo2 = function(bar) {
bar.aaa++;
}
const foo3 = function(bar) {
for (bar.aaa in baz) {}
}
const foo4 = function(bar) {
for (bar.aaa of baz) {}
}
```
:::
Examples of **incorrect** code for the `{ "props": true }` option:
::: incorrect
```js
/*eslint no-param-reassign: ["error", { "props": true }]*/
const foo = function(bar) {
bar.prop = "value";
}
const foo1 = function(bar) {
delete bar.aaa;
}
const foo2 = function(bar) {
bar.aaa++;
}
const foo3 = function(bar) {
for (bar.aaa in baz) {}
}
const foo4 = function(bar) {
for (bar.aaa of baz) {}
}
```
:::
Examples of **correct** code for the `{ "props": true }` option with `"ignorePropertyModificationsFor"` set:
::: correct
```js
/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsFor": ["bar"] }]*/
const foo = function(bar) {
bar.prop = "value";
}
const foo1 = function(bar) {
delete bar.aaa;
}
const foo2 = function(bar) {
bar.aaa++;
}
const foo3 = function(bar) {
for (bar.aaa in baz) {}
}
const foo4 = function(bar) {
for (bar.aaa of baz) {}
}
```
:::
Examples of **correct** code for the `{ "props": true }` option with `"ignorePropertyModificationsForRegex"` set:
::: correct
```js
/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsForRegex": ["^bar"] }]*/
const foo = function(barVar) {
barVar.prop = "value";
}
const foo1 = function(barrito) {
delete barrito.aaa;
}
const foo2 = function(bar_) {
bar_.aaa++;
}
const foo3 = function(barBaz) {
for (barBaz.aaa in baz) {}
}
const foo4 = function(barBaz) {
for (barBaz.aaa of baz) {}
}
```
:::
## When Not To Use It
If you want to allow assignment to function parameters, then you can safely disable this rule.
`strict` mode code doesn't sync indices of the arguments object with each parameter binding. Therefore, this rule is not necessary to protect against arguments object mutation in ESM modules or other `strict` mode functions.
---
---
title: no-path-concat
rule_type: suggestion
---
In Node.js, the `__dirname` and `__filename` global variables contain the directory path and the file path of the currently executing script file, respectively. Sometimes, developers try to use these variables to create paths to other files, such as:
```js
var fullPath = __dirname + "/foo.js";
```
However, there are a few problems with this. First, you can't be sure what type of system the script is running on. Node.js can be run on any computer, including Windows, which uses a different path separator. It's very easy, therefore, to create an invalid path using string concatenation and assuming Unix-style separators. There's also the possibility of having double separators, or otherwise ending up with an invalid path.
In order to avoid any confusion as to how to create the correct path, Node.js provides the `path` module. This module uses system-specific information to always return the correct value. So you can rewrite the previous example as:
```js
var fullPath = path.join(__dirname, "foo.js");
```
This example doesn't need to include separators as `path.join()` will do it in the most appropriate manner. Alternately, you can use `path.resolve()` to retrieve the fully-qualified path:
```js
var fullPath = path.resolve(__dirname, "foo.js");
```
Both `path.join()` and `path.resolve()` are suitable replacements for string concatenation wherever file or directory paths are being created.
## Rule Details
This rule aims to prevent string concatenation of directory paths in Node.js
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-path-concat: "error"*/
var fullPath = __dirname + "/foo.js";
var fullPath = __filename + "/foo.js";
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-path-concat: "error"*/
var fullPath = dirname + "/foo.js";
```
:::
## When Not To Use It
If you want to allow string concatenation of path names.
---
---
title: no-plusplus
rule_type: suggestion
---
Because the unary `++` and `--` operators are subject to automatic semicolon insertion, differences in whitespace can change semantics of source code.
```js
let i = 10;
let j = 20;
i ++
j
// i = 11, j = 20
```
```js
let i = 10;
let j = 20;
i
++
j
// i = 10, j = 21
```
## Rule Details
This rule disallows the unary operators `++` and `--`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-plusplus: "error"*/
let foo = 0;
foo++;
let bar = 42;
bar--;
for (let i = 0; i < l; i++) {
doSomething(i);
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-plusplus: "error"*/
let foo = 0;
foo += 1;
let bar = 42;
bar -= 1;
for (let i = 0; i < l; i += 1) {
doSomething(i);
}
```
:::
## Options
This rule has an object option.
* `"allowForLoopAfterthoughts": true` allows unary operators `++` and `--` in the afterthought (final expression) of a `for` loop.
### allowForLoopAfterthoughts
Examples of **correct** code for this rule with the `{ "allowForLoopAfterthoughts": true }` option:
::: correct
```js
/*eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }]*/
for (let i = 0; i < l; i++) {
doSomething(i);
}
for (let i = l; i >= 0; i--) {
doSomething(i);
}
for (let i = 0, j = l; i < l; i++, j--) {
doSomething(i, j);
}
```
:::
Examples of **incorrect** code for this rule with the `{ "allowForLoopAfterthoughts": true }` option:
::: incorrect
```js
/*eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }]*/
for (let i = 0; i < l; j = i++) {
doSomething(i, j);
}
for (let i = l; i--;) {
doSomething(i);
}
for (let i = 0; i < l;) i++;
```
:::
---
---
title: no-process-env
rule_type: suggestion
further_reading:
- https://stackoverflow.com/questions/5869216/how-to-store-node-js-deployment-settings-configuration-files
- https://blog.benhall.me.uk/2012/02/storing-application-config-data-in/
---
The `process.env` object in Node.js is used to store deployment/configuration parameters. Littering it through out a project could lead to maintenance issues as it's another kind of global dependency. As such, it could lead to merge conflicts in a multi-user setup and deployment issues in a multi-server setup. Instead, one of the best practices is to define all those parameters in a single configuration/settings file which could be accessed throughout the project.
## Rule Details
This rule is aimed at discouraging use of `process.env` to avoid global dependencies. As such, it will warn whenever `process.env` is used.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-process-env: "error"*/
if(process.env.NODE_ENV === "development") {
//...
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-process-env: "error"*/
var config = require("./config");
if(config.env === "development") {
//...
}
```
:::
## When Not To Use It
If you prefer to use `process.env` throughout your project to retrieve values from environment variables, then you can safely disable this rule.
---
---
title: no-process-exit
rule_type: suggestion
---
The `process.exit()` method in Node.js is used to immediately stop the Node.js process and exit. This is a dangerous operation because it can occur in any method at any point in time, potentially stopping a Node.js application completely when an error occurs. For example:
```js
if (somethingBadHappened) {
console.error("Something bad happened!");
process.exit(1);
}
```
This code could appear in any module and will stop the entire application when `somethingBadHappened` is truthy. This doesn't give the application any chance to respond to the error. It's usually better to throw an error and allow the application to handle it appropriately:
```js
if (somethingBadHappened) {
throw new Error("Something bad happened!");
}
```
By throwing an error in this way, other parts of the application have an opportunity to handle the error rather than stopping the application altogether. If the error bubbles all the way up to the process without being handled, then the process will exit and a non-zero exit code will returned, so the end result is the same.
If you are using `process.exit()` only for specifying the exit code, you can set [`process.exitCode`](https://nodejs.org/api/process.html#process_process_exitcode) (introduced in Node.js 0.11.8) instead.
## Rule Details
This rule aims to prevent the use of `process.exit()` in Node.js JavaScript. As such, it warns whenever `process.exit()` is found in code.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-process-exit: "error"*/
process.exit(1);
process.exit(0);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-process-exit: "error"*/
Process.exit();
var exit = process.exit;
```
:::
## When Not To Use It
There may be a part of a Node.js application that is responsible for determining the correct exit code to return upon exiting. In that case, you should turn this rule off to allow proper handling of the exit code.
---
---
title: no-promise-executor-return
rule_type: problem
related_rules:
- no-async-promise-executor
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
---
The `new Promise` constructor accepts a single argument, called an *executor*.
```js
const myPromise = new Promise(function executor(resolve, reject) {
readFile('foo.txt', function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
```
The executor function usually initiates some asynchronous operation. Once it is finished, the executor should call `resolve` with the result, or `reject` if an error occurred.
The return value of the executor is ignored. Returning a value from an executor function is a possible error because the returned value cannot be used and it doesn't affect the promise in any way.
## Rule Details
This rule disallows returning values from Promise executor functions.
Only `return` without a value is allowed, as it's a control flow statement.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-promise-executor-return: "error"*/
new Promise((resolve, reject) => {
if (someCondition) {
return defaultResult;
}
getSomething((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
new Promise((resolve, reject) => getSomething((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
}));
new Promise(() => {
return 1;
});
new Promise(r => r(1));
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-promise-executor-return: "error"*/
// Turn return inline into two lines
new Promise((resolve, reject) => {
if (someCondition) {
resolve(defaultResult);
return;
}
getSomething((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
// Add curly braces
new Promise((resolve, reject) => {
getSomething((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
new Promise(r => { r(1) });
// or just use Promise.resolve
Promise.resolve(1);
```
:::
## Options
This rule takes one option, an object, with the following properties:
* `allowVoid`: If set to `true` (`false` by default), this rule will allow returning void values.
### allowVoid
Examples of **correct** code for this rule with the `{ "allowVoid": true }` option:
::: correct
```js
/*eslint no-promise-executor-return: ["error", { allowVoid: true }]*/
new Promise((resolve, reject) => {
if (someCondition) {
return void resolve(defaultResult);
}
getSomething((err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
new Promise((resolve, reject) => void getSomething((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
}));
new Promise(r => void r(1));
```
:::
---
---
title: no-proto
rule_type: suggestion
further_reading:
- https://johnresig.com/blog/objectgetprototypeof/
---
`__proto__` property has been deprecated as of ECMAScript 3.1 and shouldn't be used in the code. Use `Object.getPrototypeOf` and `Object.setPrototypeOf` instead.
## Rule Details
When an object is created with the `new` operator, `__proto__` is set to the original "prototype" property of the object's constructor function. `Object.getPrototypeOf` is the preferred method of getting the object's prototype. To change an object's prototype, use `Object.setPrototypeOf`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-proto: "error"*/
const a = obj.__proto__;
const a1 = obj["__proto__"];
obj.__proto__ = b;
obj["__proto__"] = b;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-proto: "error"*/
const a = Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, b);
const c = { __proto__: a };
```
:::
## Options
This rule has no options.
## When Not To Use It
You might want to turn this rule off if you need to support legacy browsers which implement the
`__proto__` property but not `Object.getPrototypeOf` or `Object.setPrototypeOf`.
---
---
title: no-prototype-builtins
rule_type: problem
---
In ECMAScript 5.1, `Object.create` was added, which enables the creation of objects with a specified `[[Prototype]]`. `Object.create(null)` is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from `Object.prototype`. This rule prevents calling some `Object.prototype` methods directly from an object.
Additionally, objects can have properties that shadow the builtins on `Object.prototype`, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call `hasOwnProperty` directly on the resulting object, because a malicious client could send a JSON value like `{"hasOwnProperty": 1}` and cause the server to crash.
To avoid subtle bugs like this, it's better to always call these methods from `Object.prototype`. For example, `foo.hasOwnProperty("bar")` should be replaced with `Object.prototype.hasOwnProperty.call(foo, "bar")`.
## Rule Details
This rule disallows calling some `Object.prototype` methods directly on object instances.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-prototype-builtins: "error"*/
const hasBarProperty = foo.hasOwnProperty("bar");
const isPrototypeOfBar = foo.isPrototypeOf(bar);
const barIsEnumerable = foo.propertyIsEnumerable("bar");
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-prototype-builtins: "error"*/
const hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
const isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);
const barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
```
:::
## Options
This rule has no options.
## When Not To Use It
You may want to turn this rule off if your code only touches objects with hardcoded keys, and you will never use an object that shadows an `Object.prototype` method or which does not inherit from `Object.prototype`.
---
---
title: no-redeclare
rule_type: suggestion
handled_by_typescript: true
extra_typescript_info: Note that while TypeScript will catch `let` redeclares and `const` redeclares, it will not catch `var` redeclares. Thus, if you use the legacy `var` keyword in your TypeScript codebase, this rule will still provide some value.
related_rules:
- no-shadow
---
In JavaScript, it's possible to redeclare the same variable name using `var`. This can lead to confusion as to where the variable is actually declared and initialized.
## Rule Details
This rule is aimed at eliminating variables that have multiple declarations in the same scope.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-redeclare: "error"*/
var a = 3;
var a = 10;
class C {
foo() {
var b = 3;
var b = 10;
}
static {
var c = 3;
var c = 10;
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-redeclare: "error"*/
var a = 3;
a = 10;
class C {
foo() {
var b = 3;
b = 10;
}
static {
var c = 3;
c = 10;
}
}
```
:::
## Options
This rule takes one optional argument, an object with a boolean property `"builtinGlobals"`. It defaults to `true`.
If set to `true`, this rule also checks redeclaration of built-in globals, such as `Object`, `Array`, `Number`...
### builtinGlobals
The `"builtinGlobals"` option will check for redeclaration of built-in globals in global scope.
Examples of **incorrect** code for the `{ "builtinGlobals": true }` option:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-redeclare: ["error", { "builtinGlobals": true }]*/
var Object = 0;
```
:::
Note that when using `sourceType: "commonjs"` (or `ecmaFeatures.globalReturn`, if using the default parser), the top scope of a program is not actually the global scope, but rather a "module" scope. When this is the case, declaring a variable named after a builtin global is not a redeclaration, but rather a shadowing of the global variable. In that case, the [`no-shadow`](no-shadow) rule with the `"builtinGlobals"` option should be used.
---
---
title: no-regex-spaces
rule_type: suggestion
related_rules:
- no-div-regex
- no-control-regex
---
Regular expressions can be very complex and difficult to understand, which is why it's important to keep them as simple as possible in order to avoid mistakes. One of the more error-prone things you can do with a regular expression is to use more than one space, such as:
```js
const re = /foo bar/;
```
In this regular expression, it's very hard to tell how many spaces are intended to be matched. It's better to use only one space and then specify how many spaces are expected, such as:
```js
const re = /foo {3}bar/;
```
Now it is very clear that three spaces are expected to be matched.
## Rule Details
This rule disallows multiple spaces in regular expression literals.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-regex-spaces: "error"*/
const re = /foo bar/;
const re1 = new RegExp("foo bar");
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-regex-spaces: "error"*/
const re = /foo {3}bar/;
const re1 = new RegExp("foo {3}bar");
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow multiple spaces in a regular expression, then you can safely turn this rule off.
---
---
title: no-reserved-keys
further_reading:
- https://kangax.github.io/compat-table/es5/#Reserved_words_as_property_names
---
Disallows unquoted reserved words as property names in object literals.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [quote-props](quote-props) rule.
:::
ECMAScript 3 described as series of keywords and reserved words, such as `if` and `public`, that are used or intended to be used for a core language feature. The specification also indicated that these keywords and reserved words could not be used as object property names without being enclosed in strings. An error occurs in an ECMAScript 3 environment when you use a keyword or reserved word in an object literal. For example:
```js
var values = {
enum: ["red", "blue", "green"] // throws an error in ECMAScript 3
}
```
In this code, `enum` is used as an object key and will throw an error in an ECMAScript 3 environment (such as Internet Explorer 8).
ECMAScript 5 loosened the restriction such that keywords and reserved words can be used as object keys without causing an error. However, any code that needs to run in ECMAScript 3 still needs to avoid using keywords and reserved words as keys.
## Rule Details
This rule is aimed at eliminating the use of ECMAScript 3 keywords and reserved words as object literal keys. As such, it warns whenever an object key would throw an error in an ECMAScript 3 environment.
Examples of **incorrect** code for this rule:
::: incorrect
```js
var superman = {
class: "Superhero",
private: "Clark Kent"
};
var values = {
enum: ["red", "blue", "green"]
};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
var superman = {
"class": "Superhero",
"private": "Clark Kent"
};
var values = {
"enum": ["red", "blue", "green"]
};
```
:::
## When Not To Use It
If your code is only going to be executed in an ECMAScript 5 or higher environment, then you can safely leave this rule off.
---
---
title: no-restricted-exports
rule_type: suggestion
---
In a project, certain names may be disallowed from being used as exported names for various reasons.
## Rule Details
This rule disallows specified names from being used as exported names.
## Options
By default, this rule doesn't disallow any names. Only the names you specify in the configuration will be disallowed.
This rule has an object option:
* `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted.
* `"restrictedNamedExportsPattern"` is a string representing a regular expression pattern. Named exports matching this pattern will be restricted. This option does not apply to `default` named exports.
* `"restrictDefaultExports"` is an object option with boolean properties to restrict certain default export declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. The following properties are allowed:
* `direct`: restricts `export default` declarations.
* `named`: restricts `export { foo as default };` declarations.
* `defaultFrom`: restricts `export { default } from 'foo';` declarations.
* `namedFrom`: restricts `export { foo as default } from 'foo';` declarations.
* `namespaceFrom`: restricts `export * as default from 'foo';` declarations.
### restrictedNamedExports
Examples of **incorrect** code for the `"restrictedNamedExports"` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", {
"restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d", "e", "👍"]
}]*/
export const foo = 1;
export function bar() {}
export class Baz {}
const a = {};
export { a };
function someFunction() {}
export { someFunction as b };
export { c } from "some_module";
export { "d" } from "some_module";
export { something as e } from "some_module";
export { "👍" } from "some_module";
```
:::
Examples of **correct** code for the `"restrictedNamedExports"` option:
::: correct
```js
/*eslint no-restricted-exports: ["error", {
"restrictedNamedExports": ["foo", "bar", "Baz", "a", "b", "c", "d", "e", "👍"]
}]*/
export const quux = 1;
export function myFunction() {}
export class MyClass {}
const a = {};
export { a as myObject };
function someFunction() {}
export { someFunction };
export { c as someName } from "some_module";
export { "d" as " d " } from "some_module";
export { something } from "some_module";
export { "👍" as thumbsUp } from "some_module";
```
:::
#### Default exports
By design, the `"restrictedNamedExports"` option doesn't disallow `export default` declarations. If you configure `"default"` as a restricted name, that restriction will apply only to named export declarations.
Examples of additional **incorrect** code for the `"restrictedNamedExports": ["default"]` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/
function foo() {}
export { foo as default };
```
:::
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/
export { default } from "some_module";
```
:::
Examples of additional **correct** code for the `"restrictedNamedExports": ["default"]` option:
::: correct
```js
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default", "foo"] }]*/
export default function foo() {}
```
:::
### restrictedNamedExportsPattern
Example of **incorrect** code for the `"restrictedNamedExportsPattern"` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", {
"restrictedNamedExportsPattern": "bar$"
}]*/
export const foobar = 1;
```
:::
Example of **correct** code for the `"restrictedNamedExportsPattern"` option:
::: correct
```js
/*eslint no-restricted-exports: ["error", {
"restrictedNamedExportsPattern": "bar$"
}]*/
export const abc = 1;
```
:::
Note that this option does not apply to `export default` or any `default` named exports. If you want to also restrict `default` exports, use the `restrictDefaultExports` option.
### restrictDefaultExports
This option allows you to restrict certain `default` declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. This option accepts the following properties:
#### direct
Examples of **incorrect** code for the `"restrictDefaultExports": { "direct": true }` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "direct": true } }]*/
export default foo;
```
:::
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "direct": true } }]*/
export default 42;
```
:::
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "direct": true } }]*/
export default function foo() {}
```
:::
#### named
Examples of **incorrect** code for the `"restrictDefaultExports": { "named": true }` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "named": true } }]*/
const foo = 123;
export { foo as default };
```
:::
#### defaultFrom
Examples of **incorrect** code for the `"restrictDefaultExports": { "defaultFrom": true }` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "defaultFrom": true } }]*/
export { default } from 'foo';
```
:::
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "defaultFrom": true } }]*/
export { default as default } from 'foo';
```
:::
#### namedFrom
Examples of **incorrect** code for the `"restrictDefaultExports": { "namedFrom": true }` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "namedFrom": true } }]*/
export { foo as default } from 'foo';
```
:::
#### namespaceFrom
Examples of **incorrect** code for the `"restrictDefaultExports": { "namespaceFrom": true }` option:
::: incorrect
```js
/*eslint no-restricted-exports: ["error", { "restrictDefaultExports": { "namespaceFrom": true } }]*/
export * as default from 'foo';
```
:::
## Known Limitations
This rule doesn't inspect the content of source modules in re-export declarations. In particular, if you are re-exporting everything from another module's export, that export may include a restricted name. This rule cannot detect such cases.
```js
//----- some_module.js -----
export function foo() {}
//----- my_module.js -----
/*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["foo"] }]*/
export * from "some_module"; // allowed, although this declaration exports "foo" from my_module
```
---
---
title: no-restricted-globals
rule_type: suggestion
related_rules:
- no-restricted-properties
- no-restricted-syntax
---
Disallowing usage of specific global variables can be useful if you want to allow a set of global
variables, but still want to disallow some of those.
For instance, early Internet Explorer versions exposed the current DOM event as a global variable
`event`, but using this variable has been considered as a bad practice for a long time. Restricting
this will make sure this variable isn't used in browser code.
## Rule Details
This rule allows you to specify global variable names that you don't want to use in your application.
## Options
This rule has both string and object options to specify the global variables to restrict.
Using the string option, you can specify the name of a global variable that you want to restrict as a value in the rule options array:
```json
{
"rules": {
"no-restricted-globals": ["error", "event", "fdescribe"]
}
}
```
Alternatively, the rule also accepts objects, where the global name and an optional custom message are specified:
```json
{
"rules": {
"no-restricted-globals": [
"error",
{
"name": "event",
"message": "Use local parameter instead."
},
{
"name": "fdescribe",
"message": "Do not commit fdescribe. Use describe instead."
}
]
}
}
```
Examples of **incorrect** code for sample `"event", "fdescribe"` global variable names:
::: incorrect
```js
/*global event, fdescribe*/
/*eslint no-restricted-globals: ["error", "event", "fdescribe"]*/
function onClick() {
console.log(event);
}
fdescribe("foo", function() {
});
```
:::
Examples of **correct** code for a sample `"event"` global variable name:
::: correct
```js
/*global event*/
/*eslint no-restricted-globals: ["error", "event"]*/
import event from "event-module";
```
:::
::: correct
```js
/*global event*/
/*eslint no-restricted-globals: ["error", "event"]*/
const event = 1;
```
:::
Examples of **incorrect** code for a sample `"event"` global variable name, along with a custom error message:
::: incorrect
```js
/*global event*/
/* eslint no-restricted-globals: ["error", { name: "event", message: "Use local parameter instead." }] */
function onClick() {
console.log(event); // Unexpected global variable 'event'. Use local parameter instead.
}
```
:::
### globals
An object option whose value is an array containing the names of the globals you want to restrict.
Examples of **incorrect** code for `"event"` and `"fdescribe"` global variable names:
::: incorrect
```js
/*global event, fdescribe*/
/*eslint no-restricted-globals: ["error", { globals: ["event", "fdescribe"] }]*/
function onClick() {
console.log(event);
}
fdescribe("foo", function() {
});
```
:::
Custom messages for a particular global can also be specified in `globals` array using objects with `name` and `message`:
Examples of **incorrect** code for an `"event"` global variable name, along with a custom error message:
::: incorrect
```js
/*global event*/
/* eslint no-restricted-globals: ["error", { globals: [{ name: "event", message: "Use local parameter instead." }] }] */
function onClick() {
console.log(event);
}
```
:::
### checkGlobalObject
A boolean option that enables detection of restricted globals accessed via global objects. Default is `false`.
Examples of **incorrect** code for `checkGlobalObject: true` option:
::: incorrect
```js
/*global globalThis, self, window*/
/*eslint no-restricted-globals: ["error", { globals: ["Promise"], checkGlobalObject: true }]*/
globalThis.Promise
self.Promise
window.Promise
```
:::
### globalObjects
An array option that specifies additional global object names to check when `checkGlobalObject` is enabled. By default, the rule checks these global objects: `globalThis`, `self`, and `window`.
Examples of **incorrect** code for `globalObjects` option:
::: incorrect
```js
/*global globalThis, self, window, myGlobal*/
/*eslint no-restricted-globals: ["error", {
globals: ["Promise"],
checkGlobalObject: true,
globalObjects: ["myGlobal"]
}]*/
globalThis.Promise
self.Promise
window.Promise
myGlobal.Promise;
```
:::
Restricted globals used in TypeScript type annotations—such as type references, interface inheritance, or class implementations—are ignored by this rule.
Examples of **correct** TypeScript code for "Promise", "Event", and "Window" global variable names:
::: correct
```ts
/*eslint no-restricted-globals: ["error", "Promise", "Event", "Window"]*/
const fetchData: Promise = fetchString();
interface CustomEvent extends Event {}
class CustomWindow implements Window {}
function handleClick(event: Event) {
console.log(event);
}
```
:::
---
---
title: no-restricted-imports
rule_type: suggestion
---
Imports are an ES6/ES2015 standard for making the functionality of other modules available in your current module. In CommonJS this is implemented through the `require()` call which makes this ESLint rule roughly equivalent to its CommonJS counterpart `no-restricted-modules`.
Why would you want to restrict imports?
* Some imports might not make sense in a particular environment. For example, Node.js' `fs` module would not make sense in an environment that didn't have a file system.
* Some modules provide similar or identical functionality, think `lodash` and `underscore`. Your project may have standardized on a module. You want to make sure that the other alternatives are not being used as this would unnecessarily bloat the project and provide a higher maintenance cost of two dependencies when one would suffice.
## Rule Details
This rule allows you to specify imports that you don't want to use in your application.
It applies to static imports only, not dynamic ones.
## Options
This rule has both string and object options to specify the imported modules to restrict.
Using string option, you can specify the name of a module that you want to restrict from being imported as a value in the rule options array:
```json
"no-restricted-imports": ["error", "import1", "import2"]
```
Examples of **incorrect** code for string option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", "fs"]*/
import fs from 'fs';
```
:::
String options also restrict the module from being exported, as in this example:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", "fs"]*/
export { fs } from 'fs';
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", "fs"]*/
export * from 'fs';
```
:::
Examples of **correct** code for string option:
::: correct
```js
/*eslint no-restricted-imports: ["error", "fs"]*/
import crypto from 'crypto';
export { foo } from "bar";
```
:::
You may also specify a custom message for a particular module using the `name` and `message` properties inside an object, where the value of the `name` is the name of the module and `message` property contains the custom message. (The custom message is appended to the default error message from the rule.)
```json
"no-restricted-imports": ["error", {
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
```
Examples of **incorrect** code for string option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", {
"name": "disallowed-import",
"message": "Please use 'allowed-import' instead"
}]*/
import foo from 'disallowed-import';
```
:::
### paths
This is an object option whose value is an array containing the names of the modules you want to restrict.
```json
"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]
```
Examples of **incorrect** code for `paths`:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { "paths": ["cluster"] }]*/
import cluster from 'cluster';
```
:::
Custom messages for a particular module can also be specified in `paths` array using objects with `name` and `message`.
```json
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"message": "Please use import-bar instead."
}, {
"name": "import-baz",
"message": "Please use import-quux instead."
}]
}]
```
#### importNames
This option in `paths` is an array and can be used to specify the names of certain bindings exported from a module. Import names specified inside `paths` array affect the module specified in the `name` property of corresponding object, so it is required to specify the `name` property first when you are using `importNames` or `message` option.
Specifying `"default"` string inside the `importNames` array will restrict the default export from being imported.
```json
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"importNames": ["Bar"],
"message": "Please use Bar from /import-bar/baz/ instead."
}]
}]
```
Examples of **incorrect** code when `importNames` in `paths` has `"default"`:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["default"],
message: "Please use the default import from '/bar/baz/' instead."
}]}]*/
import DisallowedObject from "foo";
```
:::
Examples of **incorrect** code for `importNames` in `paths`:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import { DisallowedObject } from "foo";
import { DisallowedObject as AllowedObject } from "foo";
import { "DisallowedObject" as SomeObject } from "foo";
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import * as Foo from "foo";
```
:::
Examples of **correct** code for `importNames` in `paths`:
If the local name assigned to a default export is the same as a string in `importNames`, this will not cause an error.
::: correct
```js
/*eslint no-restricted-imports: ["error", { paths: [{ name: "foo", importNames: ["DisallowedObject"] }] }]*/
import DisallowedObject from "foo"
```
:::
::: correct
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
importNames: ["DisallowedObject"],
message: "Please import 'DisallowedObject' from '/bar/baz/' instead."
}]}]*/
import { AllowedObject as DisallowedObject } from "foo";
```
:::
#### allowImportNames
This option is an array. Inverse of `importNames`, `allowImportNames` allows the imports that are specified inside this array. So it restricts all imports from a module, except specified allowed ones.
Note: `allowImportNames` cannot be used in combination with `importNames`.
```json
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
"allowImportNames": ["Bar"],
"message": "Please use only Bar from import-foo."
}]
}]
```
Examples of **incorrect** code for `allowImportNames` in `paths`:
Disallowing all import names except 'AllowedObject'.
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Please use only 'AllowedObject' from 'foo'."
}]}]*/
import { DisallowedObject } from "foo";
```
:::
Examples of **correct** code for `allowImportNames` in `paths`:
Disallowing all import names except 'AllowedObject'.
::: correct
```js
/*eslint no-restricted-imports: ["error", { paths: [{
name: "foo",
allowImportNames: ["AllowedObject"],
message: "Only use 'AllowedObject' from 'foo'."
}]}]*/
import { AllowedObject } from "foo";
```
:::
#### allowTypeImports (TypeScript only)
Whether to allow [Type-Only Imports](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) for a path. This includes type-only `export` statements, as they are equivalent to re-exporting an `import`. Default: `false`.
Examples of **incorrect** code for `allowTypeImports` in `paths`:
::: incorrect
```ts
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
allowTypeImports: true,
message: "Please use only type-only imports from 'import-foo'."
}]}]*/
import foo from 'import-foo';
export { Foo } from 'import-foo';
```
:::
Examples of **correct** code for `allowTypeImports` in `paths`:
::: correct
```ts
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
allowTypeImports: true,
message: "Please use only type-only imports from 'import-foo'."
}]}]*/
import type foo from 'import-foo';
export type { Foo } from 'import-foo';
import type foo = require("import-foo");
```
:::
::: correct
```ts
/*eslint no-restricted-imports: ["error", { paths: [{
name: "import-foo",
importNames: ["Baz"],
allowTypeImports: true,
message: "Please use 'Baz' from 'import-foo' as a type only."
}]}]*/
import { Bar, type Baz } from "import-foo";
```
:::
### patterns
This is also an object option whose value is an array. This option allows you to specify multiple modules to restrict using `gitignore`-style patterns or regular expressions.
Where `paths` option takes exact import paths, `patterns` option can be used to specify the import paths with more flexibility, allowing for the restriction of multiple modules within the same directory. For example:
```json
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
}]
}]
```
This configuration restricts import of the `import-foo` module but wouldn't restrict the import of `import-foo/bar` or `import-foo/baz`. You can use `patterns` to restrict both:
```json
"no-restricted-imports": ["error", {
"paths": [{
"name": "import-foo",
}],
"patterns": [{
"group": ["import-foo/ba*"],
}]
}]
```
This configuration restricts imports not just from `import-foo` using `path`, but also `import-foo/bar` and `import-foo/baz` using `patterns`.
To re-include a module when using `gitignore-`style patterns, add a negation (`!`) mark before the pattern. (Make sure these negated patterns are placed last in the array, as order matters)
```json
"no-restricted-imports": ["error", {
"patterns": ["import1/private/*", "import2/*", "!import2/good"]
}]
```
You can also use regular expressions to restrict modules (see the [`regex` option](#regex)).
Examples of **incorrect** code for `patterns` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*"] }]*/
import pick from 'lodash/pick';
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/
import pick from 'lodash/map';
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private/*"] }]*/
import pick from 'import1/private/someModule';
```
:::
In this example, `"!import1/private/*"` is not reincluding the modules inside `private` because the negation mark (`!`) does not reinclude the files if it's parent directory is excluded by a pattern. In this case, `import1/private` directory is already excluded by the `import1/*` pattern. (The excluded directory can be reincluded using `"!import1/private"`.)
Examples of **correct** code for `patterns` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["crypto/*"] }]*/
import crypto from 'crypto';
```
:::
::: correct
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["lodash/*", "!lodash/pick"] }]*/
import pick from 'lodash/pick';
```
:::
::: correct
```js
/*eslint no-restricted-imports: ["error", { "patterns": ["import1/*", "!import1/private"] }]*/
import pick from 'import1/private/someModule';
```
:::
#### group
The `patterns` array can also include objects. The `group` property is used to specify the `gitignore`-style patterns for restricting modules and the `message` property is used to specify a custom message.
Either of the `group` or `regex` properties is required when using the `patterns` option.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/*"],
"message": "usage of import1 private modules not allowed."
}, {
"group": ["import2/*", "!import2/good"],
"message": "import2 is deprecated, except the modules in import2/good."
}]
}]
```
Examples of **incorrect** code for `group` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import pick from 'lodash/pick';
```
:::
Examples of **correct** code for this `group` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["lodash/*"],
message: "Please use the default import from 'lodash' instead."
}]}]*/
import lodash from 'lodash';
```
:::
#### regex
The `regex` property is used to specify the regex patterns for restricting modules.
Note: `regex` cannot be used in combination with `group`.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"regex": "import1/private/",
"message": "usage of import1 private modules not allowed."
}, {
"regex": "import2/(?!good)",
"message": "import2 is deprecated, except the modules in import2/good."
}]
}]
```
Examples of **incorrect** code for `regex` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
regex: "@app/(?!(api/enums$)).*",
}]}]*/
import Foo from '@app/api';
import Bar from '@app/api/bar';
import Baz from '@app/api/baz';
import Bux from '@app/api/enums/foo';
```
:::
Examples of **correct** code for `regex` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
regex: "@app/(?!(api/enums$)).*",
}]}]*/
import Foo from '@app/api/enums';
```
:::
#### caseSensitive
This is a boolean option and sets the patterns specified in the `group` or `regex` properties to be case-sensitive when `true`. Default is `false`.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import1/private/prefix[A-Z]*"],
"caseSensitive": true
}]
}]
```
Examples of **incorrect** code for `caseSensitive: true` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'fooBar';
```
:::
Examples of **correct** code for `caseSensitive: true` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo[A-Z]*"],
caseSensitive: true
}]}]*/
import pick from 'food';
```
:::
#### importNames
You can also specify `importNames` within objects inside the `patterns` array. In this case, the specified names apply only to the associated `group` or `regex` property.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"importNames": ["isEmpty"],
"message": "Use 'isEmpty' from lodash instead."
}]
}]
```
Examples of **incorrect** code for `importNames` in `patterns`:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
```
:::
Examples of **correct** code for `importNames` in `patterns`:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNames: ['isEmpty'],
message: "Use 'isEmpty' from lodash instead."
}]}]*/
import { hasValues } from 'utils/collection-utils';
```
:::
#### allowImportNames
You can also specify `allowImportNames` within objects inside the `patterns` array. In this case, the specified names apply only to the associated `group` or `regex` property.
Note: `allowImportNames` cannot be used in combination with `importNames`, `importNamePattern` or `allowImportNamePattern`.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["utils/*"],
"allowImportNames": ["isEmpty"],
"message": "Please use only 'isEmpty' from utils."
}]
}]
```
Examples of **incorrect** code for `allowImportNames` in `patterns`:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { hasValues } from 'utils/collection-utils';
```
:::
Examples of **correct** code for `allowImportNames` in `patterns`:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNames: ['isEmpty'],
message: "Please use only 'isEmpty' from utils."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
```
:::
#### importNamePattern
This option allows you to use regex patterns to restrict import names:
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"importNamePattern": "^foo",
}]
}]
```
Examples of **incorrect** code for `importNamePattern` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import { isEmpty } from 'utils/collection-utils';
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo/*"],
importNamePattern: '^(is|has)',
message: "Use 'is*' and 'has*' functions from baz/bar instead"
}]}]*/
import { isSomething, hasSomething } from 'foo/bar';
```
:::
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["foo/*"],
importNames: ["bar"],
importNamePattern: '^baz',
}]}]*/
import { bar, bazQux } from 'foo/quux';
```
:::
Examples of **correct** code for `importNamePattern` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: '^is',
message: "Use 'is*' functions from lodash instead."
}]}]*/
import isEmpty, { hasValue } from 'utils/collection-utils';
```
:::
You can also use this option to allow only side-effect imports by setting it to a pattern that matches any name, such as `^`.
Examples of **incorrect** code for `importNamePattern` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: "^"
}]}]*/
import isEmpty, { hasValue } from 'utils/collection-utils';
import * as file from 'utils/file-utils';
```
:::
Examples of **correct** code for `importNamePattern` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
importNamePattern: "^"
}]}]*/
import 'utils/init-utils';
```
:::
#### allowImportNamePattern
This is a string option. Inverse of `importNamePattern`, this option allows imports that matches the specified regex pattern. So it restricts all imports from a module, except specified allowed patterns.
Note: `allowImportNamePattern` cannot be used in combination with `importNames`, `importNamePattern` or `allowImportNames`.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import-foo/*"],
"allowImportNamePattern": "^foo",
}]
}]
```
Examples of **incorrect** code for `allowImportNamePattern` option:
::: incorrect
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^has'
}]}]*/
import { isEmpty } from 'utils/collection-utils';
```
:::
Examples of **correct** code for `allowImportNamePattern` option:
::: correct
```js
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["utils/*"],
allowImportNamePattern: '^is'
}]}]*/
import { isEmpty } from 'utils/collection-utils';
```
:::
#### allowTypeImports (TypeScript only)
Whether to allow [Type-Only Imports](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) for a path. This includes type-only `export` statements, as they are equivalent to re-exporting an `import`. Default: `false`.
```json
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["import/private/*"],
"allowTypeImports": true,
}]
}]
```
Examples of **incorrect** code for `allowTypeImports` in `patterns`:
::: incorrect
```ts
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
allowTypeImports: true,
message: "Please use only type-only imports from 'import/private/*'."
}]}]*/
import { foo } from 'import/private/bar';
export { foo } from 'import/private/bar';
```
:::
Examples of **correct** code for `allowTypeImports` in `patterns`:
::: correct
```ts
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
allowTypeImports: true,
message: "Please use only type-only imports from 'import/private/*'."
}]}]*/
import type { foo } from 'import/private/bar';
export type { foo } from 'import/private/bar';
import type foo = require("import/private/bar");
```
:::
::: correct
```ts
/*eslint no-restricted-imports: ["error", { patterns: [{
group: ["import/private/*"],
importNames: ["Baz"],
allowTypeImports: true,
message: "Please use 'Baz' from 'import/private/*' as a type only."
}]}]*/
import { Bar, type Baz } from "import/private/bar";
```
:::
## Known Limitations
TypeScript [`import = require()` syntax](https://www.typescriptlang.org/docs/handbook/2/modules.html#es-module-syntax-with-commonjs-behavior) is valid and the rule can recognize and lint such instances, but with certain limitations.
You can only fully restrict these imports, you cannot restrict them based on specific import names like `importNames`, `allowImportNames`, `importNamePattern`, or `allowImportNamePattern` options.
Examples of **incorrect** code for TypeScript import equals declarations:
::: incorrect
```ts
/*eslint no-restricted-imports: ["error", "disallowed-import"]*/
import foo = require("disallowed-import");
```
:::
::: incorrect
```ts
/*eslint no-restricted-imports: ["error", {
"paths": [{ "name": "disallowed-import" }]
}]*/
import foo = require("disallowed-import");
```
:::
**Note:** Import name restrictions do not apply to TypeScript import equals declarations. The following configuration will not restrict the import equals declaration:
::: correct
```ts
/*eslint no-restricted-imports: ["error", {
"paths": [{
"name": "foo",
"importNames": ["foo"]
}]
}]*/
// This import equals declaration will NOT be restricted
// even though it imports the entire module
import foo = require("foo");
```
:::
## When Not To Use It
Don't use this rule or don't include a module in the list for this rule if you want to be able to import a module in your project without an ESLint error or warning.
---
---
title: no-restricted-modules
rule_type: suggestion
---
A module in Node.js is a simple or complex functionality organized in a JavaScript file which can be reused throughout the Node.js
application. The keyword `require` is used in Node.js/CommonJS to import modules into an application. This way you can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required".
Why would you want to restrict a module?
Disallowing usage of specific Node.js modules can be useful if you want to limit the available methods a developer can use. For example, you can block usage of the `fs` module if you want to disallow file system access.
## Rule Details
This rule allows you to specify modules that you don’t want to use in your application.
## Options
The rule takes one or more strings as options: the names of restricted modules.
```json
"no-restricted-modules": ["error", "foo-module", "bar-module"]
```
It can also take an object with lists of `paths` and gitignore-style `patterns` strings.
```json
"no-restricted-modules": ["error", { "paths": ["foo-module", "bar-module"] }]
```
```json
"no-restricted-modules": ["error", {
"paths": ["foo-module", "bar-module"],
"patterns": ["foo-module/private/*", "bar-module/*","!baz-module/good"]
}]
```
You may also specify a custom message for any paths you want to restrict as follows:
```json
"no-restricted-modules": ["error", {
"name": "foo-module",
"message": "Please use bar-module instead."
}
]
```
or like this:
```json
"no-restricted-modules": ["error",{
"paths":[{
"name": "foo-module",
"message": "Please use bar-module instead."
}]
}]
```
The custom message will be appended to the default error message. Please note that you may not specify custom error messages for restricted patterns as a particular module may match more than one pattern.
To restrict the use of all Node.js core modules (via ):
```json
{
"no-restricted-modules": ["error",
"assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","freelist","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","sys","timers","tls","tracing","tty","url","util","vm","zlib"
]
}
```
Examples of **incorrect** code for this rule with sample `"fs", "cluster", "lodash"` restricted modules:
::: incorrect
```js
/*eslint no-restricted-modules: ["error", "fs", "cluster"]*/
const fs = require('fs');
const cluster = require('cluster');
```
:::
::: incorrect
```js
/*eslint no-restricted-modules: ["error", {"paths": ["cluster"] }]*/
const cluster = require('cluster');
```
:::
::: incorrect
```js
/*eslint no-restricted-modules: ["error", { "patterns": ["lodash/*"] }]*/
const pick = require('lodash/pick');
```
:::
Examples of **correct** code for this rule with sample `"fs", "cluster", "lodash"` restricted modules:
::: correct
```js
/*eslint no-restricted-modules: ["error", "fs", "cluster"]*/
const crypto = require('crypto');
```
:::
::: correct
```js
/*eslint no-restricted-modules: ["error", {
"paths": ["fs", "cluster"],
"patterns": ["lodash/*", "!lodash/pick"]
}]*/
const crypto = require('crypto');
const pick = require('lodash/pick');
```
:::
---
---
title: no-restricted-properties
rule_type: suggestion
related_rules:
- no-restricted-globals
- no-restricted-syntax
---
Certain properties on objects may be disallowed in a codebase. This is useful for deprecating an API or restricting usage of a module's methods. For example, you may want to disallow using `describe.only` when using Mocha or telling people to use `Object.assign` instead of `_.extend`.
## Rule Details
This rule looks for accessing a given property key on a given object name, either when reading the property's value or invoking it as a function. You may specify an optional message to indicate an alternative API or a reason for the restriction. This rule applies to both properties accessed by dot notation and destructuring.
## Options
This rule takes a list of objects, where the object name and property names are specified:
```json
{
"rules": {
"no-restricted-properties": [2, {
"object": "disallowedObjectName",
"property": "disallowedPropertyName"
}]
}
}
```
Multiple object/property values can be disallowed, and you can specify an optional message:
```json
{
"rules": {
"no-restricted-properties": [2, {
"object": "disallowedObjectName",
"property": "disallowedPropertyName"
}, {
"object": "disallowedObjectName",
"property": "anotherDisallowedPropertyName",
"message": "Please use allowedObjectName.allowedPropertyName."
}]
}
}
```
If the object name is omitted, the property is disallowed for all objects:
```json
{
"rules": {
"no-restricted-properties": [2, {
"property": "__defineGetter__",
"message": "Please use Object.defineProperty instead."
}]
}
}
```
If the property name is omitted, accessing any property of the given object is disallowed:
```json
{
"rules": {
"no-restricted-properties": [2, {
"object": "require",
"message": "Please call require() directly."
}]
}
}
```
If you want to restrict a property globally but allow specific objects to use it, you can use the `allowObjects` option:
```json
{
"rules": {
"no-restricted-properties": [2, {
"property": "push",
"allowObjects": ["router"],
"message": "Prefer [...array, newValue] because it does not mutate the array in place."
}]
}
}
```
If you want to restrict all properties on an object except for specific ones, you can use the `allowProperties` option:
```json
{
"rules": {
"no-restricted-properties": [2, {
"object": "config",
"allowProperties": ["settings", "version"],
"message": "Accessing other properties is restricted."
}]
}
}
```
Note that the `allowObjects` option cannot be used together with the `object` option since they are mutually exclusive. Similarly, the `allowProperties` option cannot be used together with the `property` option since they are also mutually exclusive.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint no-restricted-properties: [2, {
"object": "disallowedObjectName",
"property": "disallowedPropertyName"
}] */
const example = disallowedObjectName.disallowedPropertyName; /*error Disallowed object property: disallowedObjectName.disallowedPropertyName.*/
disallowedObjectName.disallowedPropertyName(); /*error Disallowed object property: disallowedObjectName.disallowedPropertyName.*/
```
:::
::: incorrect
```js
/* eslint no-restricted-properties: [2, {
"property": "__defineGetter__"
}] */
foo.__defineGetter__(bar, baz);
const { __defineGetter__ } = qux();
({ __defineGetter__ }) => {};
```
:::
::: incorrect
```js
/* eslint no-restricted-properties: [2, {
"object": "require"
}] */
require.resolve('foo');
```
:::
::: incorrect
```js
/* eslint no-restricted-properties: [2, {
"property": "push",
"allowObjects": ["router"],
}] */
myArray.push(5);
```
:::
::: incorrect
```js
/* eslint no-restricted-properties: [2, {
"object": "config",
"allowProperties": ["settings", "version"]
}] */
config.apiKey = "12345";
config.timeout = 5000;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint no-restricted-properties: [2, {
"object": "disallowedObjectName",
"property": "disallowedPropertyName"
}] */
const example = disallowedObjectName.somePropertyName;
allowedObjectName.disallowedPropertyName();
```
:::
::: correct
```js
/* eslint no-restricted-properties: [2, {
"object": "require"
}] */
require('foo');
```
:::
::: correct
```js
/* eslint no-restricted-properties: [2, {
"property": "push",
"allowObjects": ["router", "history"],
}] */
router.push('/home');
history.push('/about');
```
:::
::: correct
```js
/* eslint no-restricted-properties: [2, {
"object": "config",
"allowProperties": ["settings", "version"]
}] */
config.settings = { theme: "dark" };
config.version = "1.0.0";
```
:::
## When Not To Use It
If you don't have any object/property combinations to restrict, you should not use this rule.
---
---
title: no-restricted-syntax
rule_type: suggestion
related_rules:
- no-alert
- no-console
- no-debugger
- no-restricted-properties
---
JavaScript has a lot of language features, and not everyone likes all of them. As a result, some projects choose to disallow the use of certain language features altogether. For instance, you might decide to disallow the use of `try-catch` or `class`, or you might decide to disallow the use of the `in` operator.
Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. For the JavaScript language, these elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may use [Code Explorer](https://explorer.eslint.org) to determine the nodes that represent your code.
You can also specify [AST selectors](../extend/selectors) to restrict, allowing much more precise control over syntax patterns.
Note: This rule can be used with any language you lint using ESLint. To see what type of nodes your code in another language consists of, you can use:
* [typescript-eslint Playground](https://typescript-eslint.io/play) if you're using ESLint with `typescript-eslint`.
* [ESLint Code Explorer](https://explorer.eslint.org/) if you're using ESLint to lint JavaScript, JSON, Markdown, or CSS.
## Rule Details
This rule disallows specified (that is, user-defined) syntax.
## Options
This rule takes a list of strings, where each string is an AST selector:
```json
{
"rules": {
"no-restricted-syntax": ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"]
}
}
```
Alternatively, the rule also accepts objects, where the selector and an optional custom message are specified:
```json
{
"rules": {
"no-restricted-syntax": [
"error",
{
"selector": "FunctionExpression",
"message": "Function expressions are not allowed."
},
{
"selector": "CallExpression[callee.name='setTimeout'][arguments.length!=2]",
"message": "setTimeout must always be invoked with two arguments."
}
]
}
}
```
If a custom message is specified with the `message` property, ESLint will use that message when reporting occurrences of the syntax specified in the `selector` property.
The string and object formats can be freely mixed in the configuration as needed.
Examples of **incorrect** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options:
::: incorrect { "sourceType": "script" }
```js
/* eslint no-restricted-syntax: ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"] */
with (me) {
dontMess();
}
const doSomething = function () {};
foo in bar;
```
:::
Examples of **correct** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options:
::: correct { "sourceType": "script" }
```js
/* eslint no-restricted-syntax: ["error", "FunctionExpression", "WithStatement", "BinaryExpression[operator='in']"] */
me.dontMess();
function doSomething() {};
foo instanceof bar;
```
:::
## When Not To Use It
If you don't want to restrict your code from using any JavaScript features or syntax, you should not use this rule.
---
---
title: no-return-assign
rule_type: suggestion
---
One of the interesting, and sometimes confusing, aspects of JavaScript is that assignment can happen at almost any point. Because of this, an errant equals sign can end up causing assignment when the true intent was to do a comparison. This is especially true when using a `return` statement. For example:
```js
function doSomething() {
return foo = bar + 2;
}
```
It is difficult to tell the intent of the `return` statement here. It's possible that the function is meant to return the result of `bar + 2`, but then why is it assigning to `foo`? It's also possible that the intent was to use a comparison operator such as `==` and that this code is an error.
Because of this ambiguity, it's considered a best practice to not use assignment in `return` statements.
## Rule Details
This rule aims to eliminate assignments from `return` statements. As such, it will warn whenever an assignment is found as part of `return`.
## Options
The rule takes one option, a string, which must contain one of the following values:
* `except-parens` (default): Disallow assignments unless they are enclosed in parentheses.
* `always`: Disallow all assignments.
### except-parens
This is the default option.
It disallows assignments unless they are enclosed in parentheses.
Examples of **incorrect** code for the default `"except-parens"` option:
::: incorrect
```js
/*eslint no-return-assign: "error"*/
function doSomething() {
return foo = bar + 2;
}
function doSomethingElse() {
return foo += 2;
}
const foo = (a, b) => a = b
const bar = (a, b, c) => (a = b, c == b)
function doSomethingMore() {
return foo = bar && foo > 0;
}
```
:::
Examples of **correct** code for the default `"except-parens"` option:
::: correct
```js
/*eslint no-return-assign: "error"*/
function doSomething() {
return foo == bar + 2;
}
function doSomethingElse() {
return foo === bar + 2;
}
function doSomethingMore() {
return (foo = bar + 2);
}
const foo = (a, b) => (a = b)
const bar = (a, b, c) => ((a = b), c == b)
function doAnotherThing() {
return (foo = bar) && foo > 0;
}
```
:::
### always
This option disallows all assignments in `return` statements.
All assignments are treated as problems.
Examples of **incorrect** code for the `"always"` option:
::: incorrect
```js
/*eslint no-return-assign: ["error", "always"]*/
function doSomething() {
return foo = bar + 2;
}
function doSomethingElse() {
return foo += 2;
}
function doSomethingMore() {
return (foo = bar + 2);
}
```
:::
Examples of **correct** code for the `"always"` option:
::: correct
```js
/*eslint no-return-assign: ["error", "always"]*/
function doSomething() {
return foo == bar + 2;
}
function doSomethingElse() {
return foo === bar + 2;
}
```
:::
## When Not To Use It
If you want to allow the use of assignment operators in a `return` statement, then you can safely disable this rule.
---
---
title: no-return-await
rule_type: suggestion
further_reading:
- https://v8.dev/blog/fast-async
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
- https://jakearchibald.com/2017/await-vs-return-vs-return-await/
---
It is NOT recommended to use the `no-return-await` rule anymore because:
* `return await` on a promise will not result in an extra microtask.
* `return await` yields a better stack trace for debugging.
Historical context: When promises were first introduced, calling `return await` introduced an additional microtask, one for the `await` and one for the return value of the async function. Each extra microtask delays the computation of a result and so this rule was added to help avoid this performance trap. Later, [ECMA-262 changed the way](https://github.com/tc39/ecma262/pull/1250) `return await` worked so it would create a single microtask, which means this rule is no longer necessary.
## Rule Details
This rule warns on any usage of `return await` except in `try` blocks.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-return-await: "error"*/
async function foo() {
return await bar();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-return-await: "error"*/
async function foo1() {
return bar();
}
async function foo2() {
await bar();
return;
}
// This is essentially the same as `return await bar();`, but the rule checks only `await` in `return` statements
async function foo3() {
const x = await bar();
return x;
}
// In this example the `await` is necessary to be able to catch errors thrown from `bar()`
async function foo4() {
try {
return await bar();
} catch (error) {}
}
```
:::
## When Not To Use It
You should not use this rule. There is no reason to avoid `return await`.
---
---
title: no-script-url
rule_type: suggestion
further_reading:
- https://stackoverflow.com/questions/13497971/what-is-the-matter-with-script-targeted-urls
---
Using `javascript:` URLs is considered by some as a form of `eval`. Code passed in `javascript:` URLs has to be parsed and evaluated by the browser in the same way that `eval` is processed.
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-script-url: "error"*/
location.href = "javascript:void(0)";
location.href = `javascript:void(0)`;
```
:::
## Options
This rule has no options.
## Compatibility
* **JSHint**: This rule corresponds to `scripturl` rule of JSHint.
---
---
title: no-self-assign
rule_type: problem
---
Self assignments have no effect, so probably those are an error due to incomplete refactoring.
Those indicate that what you should do is still remaining.
```js
foo = foo;
[bar, baz] = [bar, qiz];
```
## Rule Details
This rule is aimed at eliminating self assignments.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-self-assign: "error"*/
foo = foo;
[a, b] = [a, b];
[a, ...b] = [x, ...b];
({a, b} = {a, x});
foo &&= foo;
foo ||= foo;
foo ??= foo;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-self-assign: "error"*/
foo = bar;
[a, b] = [b, a];
// This pattern is warned by the `no-use-before-define` rule.
let foo = foo;
// The default values have an effect.
[foo = 1] = [foo];
// non-self-assignments with properties.
obj.a = obj.b;
obj.a.b = obj.c.b;
obj.a.b = obj.a.c;
obj[a] = obj["a"];
// This ignores if there is a function call.
obj.a().b = obj.a().b;
a().b = a().b;
// `&=` and `|=` have an effect on non-integers.
foo &= foo;
foo |= foo;
// Known limitation: this does not support computed properties except single literal or single identifier.
obj[a + b] = obj[a + b];
obj["a" + "b"] = obj["a" + "b"];
```
:::
## Options
This rule has the option to check properties as well.
```json
{
"no-self-assign": ["error", {"props": true}]
}
```
* `props` - if this is `true`, `no-self-assign` rule warns self-assignments of properties. Default is `true`.
### props
Examples of **correct** code with the `{ "props": false }` option:
::: correct
```js
/*eslint no-self-assign: ["error", {"props": false}]*/
// self-assignments with properties.
obj.a = obj.a;
obj.a.b = obj.a.b;
obj["a"] = obj["a"];
obj[a] = obj[a];
```
:::
## When Not To Use It
If you don't want to notify about self assignments, then it's safe to disable this rule.
---
---
title: no-self-compare
rule_type: problem
---
Comparing a variable against itself is usually an error, either a typo or refactoring error. It is confusing to the reader and may potentially introduce a runtime error.
The only time you would compare a variable against itself is when you are testing for `NaN`. However, it is far more appropriate to use `typeof x === 'number' && isNaN(x)` or the [Number.isNaN ES2015 function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) for that use case rather than leaving the reader of the code to determine the intent of self comparison.
## Rule Details
This error is raised to highlight a potentially confusing and potentially pointless piece of code. There are almost no situations in which you would need to compare something to itself.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-self-compare: "error"*/
let x = 10;
if (x === x) {
x = 20;
}
```
:::
## Options
This rule has no options.
## Known Limitations
This rule works by directly comparing the tokens on both sides of the operator. It flags them as problematic if they are structurally identical. However, it doesn't consider possible side effects or that functions may return different objects even when called with the same arguments. As a result, it can produce false positives in some cases, such as:
::: incorrect
```js
/*eslint no-self-compare: "error"*/
function parseDate(dateStr) {
return new Date(dateStr);
}
if (parseDate('December 17, 1995 03:24:00') === parseDate('December 17, 1995 03:24:00')) {
// do something
}
let counter = 0;
function incrementUnlessReachedMaximum() {
return Math.min(counter += 1, 10);
}
if (incrementUnlessReachedMaximum() === incrementUnlessReachedMaximum()) {
// ...
}
```
:::
---
---
title: no-sequences
rule_type: suggestion
---
The comma operator includes multiple expressions where only one is expected. It evaluates each operand from left to right and returns the value of the last operand. However, this frequently obscures side effects, and its use is often an accident. Here are some examples of sequences:
```js
let a = (3, 5); // a = 5
a = b += 5, a + b;
while (a = next(), a && a.length);
(0, eval)("doSomething();");
```
## Rule Details
This rule forbids the use of the comma operator, with the following exceptions:
* In the initialization or update portions of a `for` statement.
* By default, if the expression sequence is explicitly wrapped in parentheses. This exception can be removed with the `allowInParentheses` option.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-sequences: "error"*/
foo = doSomething(), val;
0, eval("doSomething();");
do {} while (doSomething(), !!test);
for (; doSomething(), !!test; );
if (doSomething(), !!test);
switch (val = foo(), val) {}
while (val = foo(), val < 42);
with (doSomething(), val) {}
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-sequences: "error"*/
foo = (doSomething(), val);
(0, eval)("doSomething();");
do {} while ((doSomething(), !!test));
for (i = 0, j = 10; i < j; i++, j--);
if ((doSomething(), !!test));
switch ((val = foo(), val)) {}
while ((val = foo(), val < 42));
with ((doSomething(), val)) {}
```
:::
### Note about arrow function bodies
If an arrow function body is a statement rather than a block, and that statement contains a sequence, you need to use double parentheses around the statement to indicate that the sequence is intentional.
Examples of **incorrect** code for arrow functions:
::: incorrect
```js
/*eslint no-sequences: "error"*/
const foo = (val) => (console.log('bar'), val);
const baz = () => ((bar = 123), 10);
const qux = () => { return (bar = 123), 10 }
```
:::
Examples of **correct** code for arrow functions:
::: correct
```js
/*eslint no-sequences: "error"*/
const foo = (val) => ((console.log('bar'), val));
const baz = () => (((bar = 123), 10));
const qux = () => { return ((bar = 123), 10) }
```
:::
## Options
This rule takes one option, an object, with the following properties:
* `"allowInParentheses"`: If set to `true` (default), this rule allows expression sequences that are explicitly wrapped in parentheses.
### allowInParentheses
Examples of **incorrect** code for this rule with the `{ "allowInParentheses": false }` option:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/
foo = (doSomething(), val);
(0, eval)("doSomething();");
do {} while ((doSomething(), !!test));
for (; (doSomething(), !!test); );
if ((doSomething(), !!test));
switch ((val = foo(), val)) {}
while ((val = foo(), val < 42));
with ((doSomething(), val)) {}
const foo = (val) => ((console.log('bar'), val));
```
:::
Examples of **correct** code for this rule with the `{ "allowInParentheses": false }` option:
::: correct
```js
/*eslint no-sequences: ["error", { "allowInParentheses": false }]*/
for (i = 0, j = 10; i < j; i++, j--);
```
:::
## When Not To Use It
Disable this rule if sequence expressions with the comma operator are acceptable.
Another case is where you might want to report all usages of the comma operator, even in a `for` loop. You can achieve this using rule `no-restricted-syntax`:
```js
{
"rules": {
"no-restricted-syntax": ["error", "SequenceExpression"]
}
}
```
---
---
title: no-setter-return
rule_type: problem
handled_by_typescript: true
related_rules:
- getter-return
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
---
Setters cannot return values.
While returning a value from a setter does not produce an error, the returned value is being ignored. Therefore, returning a value from a setter is either unnecessary or a possible error, since the returned value cannot be used.
## Rule Details
This rule disallows returning values from setters and reports `return` statements in setter functions.
Only `return` without a value is allowed, as it's a control flow statement.
This rule checks setters in:
* Object literals.
* Class declarations and class expressions.
* Property descriptors in `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty` methods of the global objects.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-setter-return: "error"*/
const foo = {
set a(value) {
this.val = value;
return value;
}
};
class Foo {
set a(value) {
this.val = value * 2;
return this.val;
}
}
const Bar = class {
static set a(value) {
if (value < 0) {
this.val = 0;
return 0;
}
this.val = value;
}
};
Object.defineProperty(foo, "bar", {
set(value) {
if (value < 0) {
return false;
}
this.val = value;
}
});
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-setter-return: "error"*/
const foo = {
set a(value) {
this.val = value;
}
};
class Foo {
set a(value) {
this.val = value * 2;
}
}
const Bar = class {
static set a(value) {
if (value < 0) {
this.val = 0;
return;
}
this.val = value;
}
};
Object.defineProperty(foo, "bar", {
set(value) {
if (value < 0) {
throw new Error("Negative value.");
}
this.val = value;
}
});
```
:::
## Options
This rule has no options.
---
---
title: no-shadow-restricted-names
rule_type: suggestion
related_rules:
- no-shadow
further_reading:
- https://262.ecma-international.org/11.0/#sec-value-properties-of-the-global-object
- https://262.ecma-international.org/11.0/#sec-strict-mode-of-ecmascript
---
ES2020 §18.1 Value Properties of the Global Object (`globalThis`, `NaN`, `Infinity`, `undefined`) as well as strict mode restricted identifiers `eval` and `arguments` are considered to be restricted names in JavaScript. Defining them to mean something else can have unintended consequences and confuse others reading the code. For example, there's nothing preventing you from writing:
```js
const undefined = "foo";
```
Then any code used within the same scope would not get the global `undefined`, but rather the local version with a very different meaning.
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-shadow-restricted-names: "error"*/
function NaN(){}
!function(Infinity){};
const undefined = 5;
try {} catch(eval){}
```
:::
::: incorrect
```js
/*eslint no-shadow-restricted-names: "error"*/
import NaN from "foo";
import { undefined } from "bar";
class Infinity {}
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-shadow-restricted-names: "error"*/
let Object;
function f(a, b){}
// Exception: `undefined` may be shadowed if the variable is never assigned a value.
let undefined;
```
:::
::: correct
```js
/*eslint no-shadow-restricted-names: "error"*/
import { undefined as undef } from "bar";
```
:::
## Options
This rule has an object option:
* `"reportGlobalThis"`: `true` (default) reports declarations of `globalThis`.
### reportGlobalThis
Examples of **incorrect** code for the default `{ "reportGlobalThis": true }` option:
::: incorrect
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": true }]*/
const globalThis = "foo";
```
:::
::: incorrect
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": true }]*/
function globalThis() {}
```
:::
::: incorrect
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": true }]*/
import { globalThis } from "bar";
```
:::
::: incorrect
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": true }]*/
class globalThis {}
```
:::
Examples of **correct** code for the default `{ "reportGlobalThis": true }` option:
::: correct
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": true }]*/
const foo = globalThis;
function bar() {
return globalThis;
}
import { globalThis as baz } from "foo";
```
:::
Examples of **correct** code for the `{ "reportGlobalThis": false }` option:
::: correct
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": false }]*/
const globalThis = "foo";
```
:::
::: correct
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": false }]*/
function globalThis() {}
```
:::
::: correct
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": false }]*/
import { globalThis } from "bar";
```
:::
::: correct
```js
/*eslint no-shadow-restricted-names: ["error", { "reportGlobalThis": false }]*/
class globalThis {}
```
:::
---
---
title: no-shadow
rule_type: suggestion
related_rules:
- no-shadow-restricted-names
further_reading:
- https://en.wikipedia.org/wiki/Variable_shadowing
---
Shadowing is the process by which a local variable shares the same name as a variable in its containing scope. For example:
```js
const a = 3;
function b() {
const a = 10;
}
```
In this case, the variable `a` inside of `b()` is shadowing the variable `a` in the global scope. This can cause confusion while reading the code and it's impossible to access the global variable.
## Rule Details
This rule aims to eliminate shadowed variable declarations.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-shadow: "error"*/
const a = 3;
function b() {
const a = 10;
}
const c = function () {
const a = 10;
}
function d(a) {
a = 10;
}
d(a);
if (true) {
const a = 5;
}
```
:::
## Options
This rule takes one option, an object, with the following properties:
- `"builtinGlobals"`
- `"hoist"`
- `"allow"`
- `"ignoreOnInitialization"`
- `"ignoreTypeValueShadow"` (TypeScript only)
- `"ignoreFunctionTypeParameterNameValueShadow"` (TypeScript only)
```json
{
"no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [], "ignoreOnInitialization": false }]
}
```
### builtinGlobals
The `builtinGlobals` option is `false` by default.
If it is `true`, the rule prevents shadowing of built-in global variables: `Object`, `Array`, `Number`, and so on.
Examples of **incorrect** code for the `{ "builtinGlobals": true }` option:
::: incorrect
```js
/*eslint no-shadow: ["error", { "builtinGlobals": true }]*/
function foo() {
const Object = 0;
}
```
:::
### hoist
The `hoist` option has five settings:
- `functions` (by default) - reports shadowing before the outer functions are defined.
- `all` - reports all shadowing before the outer variables/functions are defined.
- `never` - never report shadowing before the outer variables/functions are defined.
- `types` (TypeScript only) - reports shadowing before the outer types are defined.
- `functions-and-types` (TypeScript only) - reports shadowing before the outer functions and types are defined.
#### hoist: functions
Examples of **incorrect** code for the default `{ "hoist": "functions" }` option:
::: incorrect
```js
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/
if (true) {
const b = 6;
}
function b() {}
```
:::
Although `const b` in the `if` statement is before the *function* declaration in the outer scope, it is incorrect.
Examples of **correct** code for the default `{ "hoist": "functions" }` option:
::: correct
```js
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/
if (true) {
const a = 3;
}
const a = 5;
```
:::
Because `const a` in the `if` statement is before the *variable* declaration in the outer scope, it is correct.
#### hoist: all
Examples of **incorrect** code for the `{ "hoist": "all" }` option:
::: incorrect
```js
/*eslint no-shadow: ["error", { "hoist": "all" }]*/
if (true) {
const a = 3;
const b = 6;
}
const a = 5;
function b() {}
```
:::
#### hoist: never
Examples of **correct** code for the `{ "hoist": "never" }` option:
::: correct
```js
/*eslint no-shadow: ["error", { "hoist": "never" }]*/
if (true) {
const a = 3;
const b = 6;
}
const a = 5;
function b() {}
```
:::
Because `const a` and `const b` in the `if` statement are before the declarations in the outer scope, they are correct.
#### hoist: types
Examples of **incorrect** code for the `{ "hoist": "types" }` option:
::: incorrect
```ts
/*eslint no-shadow: ["error", { "hoist": "types" }]*/
type Bar = 1;
type Foo = 1;
```
:::
#### hoist: functions-and-types
Examples of **incorrect** code for the `{ "hoist": "functions-and-types" }` option:
::: incorrect
```ts
/*eslint no-shadow: ["error", { "hoist": "functions-and-types" }]*/
// types
type Bar = 1;
type Foo = 1;
// functions
if (true) {
const b = 6;
}
function b() {}
```
:::
### allow
The `allow` option is an array of identifier names for which shadowing is allowed. For example, `"resolve"`, `"reject"`, `"done"`, `"cb"`.
Examples of **correct** code for the `{ "allow": ["done"] }` option:
::: correct
```js
/*eslint no-shadow: ["error", { "allow": ["done"] }]*/
import async from 'async';
function foo(done) {
async.map([1, 2], function (e, done) {
done(null, e * 2)
}, done);
}
foo(function (err, result) {
console.log({ err, result });
});
```
:::
### ignoreOnInitialization
The `ignoreOnInitialization` option is `false` by default. If it is `true`, it prevents reporting shadowing of variables in their initializers when the shadowed variable is presumably still uninitialized.
The shadowed variable must be on the left side. The shadowing variable must be on the right side and declared in a callback function or in an IIFE.
Examples of **incorrect** code for the `{ "ignoreOnInitialization": "true" }` option:
::: incorrect
```js
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/
const x = x => x;
```
:::
Because the shadowing variable `x` will shadow the already initialized shadowed variable `x`.
Examples of **correct** code for the `{ "ignoreOnInitialization": true }` option:
::: correct
```js
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/
const x = foo(x => x)
const y = (y => y)()
```
:::
The rationale for callback functions is the assumption that they will be called during the initialization, so that at the time when the shadowing variable will be used, the shadowed variable has not yet been initialized.
### ignoreTypeValueShadow
Whether to ignore types named the same as a variable. Default: `true`.
This is generally safe because you cannot use variables in type locations without a typeof operator, so there's little risk of confusion.
Examples of **correct** code with `{ "ignoreTypeValueShadow": true }`:
::: correct
```ts
/*eslint no-shadow: ["error", { "ignoreTypeValueShadow": true }]*/
type Foo = number;
interface Bar {
prop: number;
}
function f() {
const Foo = 1;
const Bar = 'test';
}
```
:::
**Note:** Shadowing specifically refers to two identical identifiers that are in different, nested scopes. This is different from redeclaration, which is when two identical identifiers are in the same scope. Redeclaration is covered by the [`no-redeclare`](/rules/no-redeclare) rule instead.
### ignoreFunctionTypeParameterNameValueShadow
Whether to ignore function parameters named the same as a variable. Default: `true`.
Each of a function type's arguments creates a value variable within the scope of the function type. This is done so that you can reference the type later using the typeof operator:
```ts
type Func = (test: string) => typeof test;
declare const fn: Func;
const result = fn('str'); // typeof result === string
```
This means that function type arguments shadow value variable names in parent scopes:
```ts
let test = 1;
type TestType = typeof test; // === number
type Func = (test: string) => typeof test; // this "test" references the argument, not the variable
declare const fn: Func;
const result = fn('str'); // typeof result === string
```
If you do not use the `typeof` operator in a function type return type position, you can safely turn this option on.
Examples of **correct** code with `{ "ignoreFunctionTypeParameterNameValueShadow": true }`:
::: correct
```ts
/*eslint no-shadow: ["error", { "ignoreFunctionTypeParameterNameValueShadow": true }]*/
const test = 1;
type Func = (test: string) => typeof test;
```
:::
### Why does the rule report on enum members that share the same name as a variable in a parent scope?
This isn't a bug — the rule is working exactly as intended! The report is correct because of a lesser-known aspect of enums: enum members introduce a variable within the enum's own scope, allowing them to be referenced without needing a qualifier.
Here's a simple example to explain:
```ts
const A = 2;
enum Test {
A = 1,
B = A,
}
console.log(Test.B); // what should be logged?
```
At first glance, you might think it should log `2`, because the outer variable A's value is `2`. However, it actually logs `1`, the value of `Test.A`. This happens because inside the enum `B = A` is treated as `B = Test.A`. Due to this behavior, the enum member has shadowed the outer variable declaration.
---
---
title: no-space-before-semi
related_rules:
- semi
- no-extra-semi
---
Disallows spaces before semicolons.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [semi-spacing](semi-spacing) rule.
:::
JavaScript allows for placing unnecessary spaces between an expression and the closing semicolon.
Space issues can also cause code to look inconsistent and harder to read.
```js
var thing = function () {
var test = 12 ;
} ;
```
## Rule Details
This rule prevents the use of spaces before a semicolon in expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
var foo = "bar" ;
var foo = function() {} ;
var foo = function() {
} ;
var foo = 1 + 2 ;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
;(function(){}());
var foo = "bar";
```
:::
---
---
title: no-spaced-func
rule_type: layout
---
While it's possible to have whitespace between the name of a function and the parentheses that execute it, such patterns tend to look more like errors.
## Rule Details
This rule disallows spacing between function identifiers and their applications.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-spaced-func: "error"*/
fn ()
fn
()
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-spaced-func: "error"*/
fn()
```
:::
---
---
title: no-sparse-arrays
rule_type: problem
further_reading:
- https://www.nczonline.net/blog/2007/09/09/inconsistent-array-literals/
---
Sparse arrays contain empty slots, most frequently due to multiple commas being used in an array literal, such as:
```js
const items = [,,];
```
While the `items` array in this example has a `length` of 2, there are actually no values in `items[0]` or `items[1]`. The fact that the array literal is valid with only commas inside, coupled with the `length` being set and actual item values not being set, make sparse arrays confusing for many developers. Consider the following:
```js
const colors = [ "red",, "blue" ];
```
In this example, the `colors` array has a `length` of 3. But did the developer intend for there to be an empty spot in the middle of the array? Or is it a typo?
The confusion around sparse arrays defined in this manner is enough that it's recommended to avoid using them unless you are certain that they are useful in your code.
## Rule Details
This rule disallows sparse array literals which have "holes" where commas are not preceded by elements. It does not apply to a trailing comma following the last element.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-sparse-arrays: "error"*/
const items = [,];
const colors = [ "red",, "blue" ];
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-sparse-arrays: "error"*/
const items = [];
const arr = new Array(23);
// trailing comma (after the last element) is not a problem
const colors = [ "red", "blue", ];
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to use sparse arrays, then it is safe to disable this rule.
---
---
title: no-sync
rule_type: suggestion
---
In Node.js, most I/O is done through asynchronous methods. However, there are often synchronous versions of the asynchronous methods. For example, `fs.exists()` and `fs.existsSync()`. In some contexts, using synchronous operations is okay (if, as with ESLint, you are writing a command line utility). However, in other contexts the use of synchronous operations is considered a bad practice that should be avoided. For example, if you are running a high-travel web server on Node.js, you should consider carefully if you want to allow any synchronous operations that could lock up the server.
## Rule Details
This rule is aimed at preventing synchronous methods from being called in Node.js. It looks specifically for the method suffix "`Sync`" (as is the convention with Node.js operations).
## Options
This rule has an optional object option `{ allowAtRootLevel: }`, which determines whether synchronous methods should be allowed at the top level of a file, outside of any functions. This option defaults to `false`.
Examples of **incorrect** code for this rule with the default `{ allowAtRootLevel: false }` option:
::: incorrect
```js
/*eslint no-sync: "error"*/
fs.existsSync(somePath);
function foo() {
var contents = fs.readFileSync(somePath).toString();
}
```
:::
Examples of **correct** code for this rule with the default `{ allowAtRootLevel: false }` option:
::: correct
```js
/*eslint no-sync: "error"*/
obj.sync();
async(function() {
// ...
});
```
:::
Examples of **incorrect** code for this rule with the `{ allowAtRootLevel: true }` option
::: incorrect
```js
/*eslint no-sync: ["error", { allowAtRootLevel: true }]*/
function foo() {
var contents = fs.readFileSync(somePath).toString();
}
var bar = baz => fs.readFileSync(qux);
```
:::
Examples of **correct** code for this rule with the `{ allowAtRootLevel: true }` option
::: correct
```js
/*eslint no-sync: ["error", { allowAtRootLevel: true }]*/
fs.readFileSync(somePath).toString();
```
:::
## When Not To Use It
If you want to allow synchronous operations in your script, do not enable this rule.
---
---
title: no-tabs
rule_type: layout
---
Some style guides don't allow the use of tab characters at all, including within comments.
## Rule Details
This rule looks for tabs anywhere inside a file: code, comments or anything else.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint no-tabs: "error" */
var a = 2;
/**
* it's a test function
*/
function test(){}
var x = 1; // test
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint no-tabs: "error" */
var a = 2;
/**
* it's a test function
*/
function test(){}
var x = 1; // test
```
:::
### Options
This rule has an optional object option with the following properties:
* `allowIndentationTabs` (default: false): If this is set to true, then the rule will not report tabs used for indentation.
#### allowIndentationTabs
Examples of **correct** code for this rule with the `allowIndentationTabs: true` option:
::: correct
```js
/* eslint no-tabs: ["error", { allowIndentationTabs: true }] */
function test() {
doSomething();
}
// comment with leading indentation tab
```
:::
## When Not To Use It
If you have established a standard where having tabs is fine, then you can disable this rule.
## Compatibility
* **JSCS**: [disallowTabs](https://jscs-dev.github.io/rule/disallowTabs)
---
---
title: no-template-curly-in-string
rule_type: problem
---
ECMAScript 6 allows programmers to create strings containing variable or expressions using template literals, instead of string concatenation, by writing expressions like `${variable}` between two backtick quotes (\`). It can be easy to use the wrong quotes when wanting to use template literals, by writing `"${variable}"`, and end up with the literal value `"${variable}"` instead of a string containing the value of the injected expressions.
## Rule Details
This rule aims to warn when a regular string contains what looks like a template literal placeholder. It will warn when it finds a string containing the template literal placeholder (`${something}`) that uses either `"` or `'` for the quotes.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-template-curly-in-string: "error"*/
"Hello ${name}!";
'Hello ${name}!';
"Time: ${12 * 60 * 60 * 1000}";
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-template-curly-in-string: "error"*/
`Hello ${name}!`;
`Time: ${12 * 60 * 60 * 1000}`;
templateFunction`Hello ${name}`;
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
---
---
title: no-ternary
rule_type: suggestion
related_rules:
- no-nested-ternary
- no-unneeded-ternary
---
The ternary operator is used to conditionally assign a value to a variable. Some believe that the use of ternary operators leads to unclear code.
```js
const foo = isBar ? baz : qux;
```
## Rule Details
This rule disallows ternary operators.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-ternary: "error"*/
const foo = isBar ? baz : qux;
function quux() {
return foo ? bar() : baz();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-ternary: "error"*/
let foo;
if (isBar) {
foo = baz;
} else {
foo = qux;
}
function quux() {
if (foo) {
return bar();
} else {
return baz();
}
}
```
:::
## Options
This rule has no options.
---
---
title: no-this-before-super
rule_type: problem
handled_by_typescript: true
---
In the constructor of derived classes, if `this`/`super` are used before `super()` calls, it raises a reference error.
This rule checks `this`/`super` keywords in constructors, then reports those that are before `super()`.
## Rule Details
This rule is aimed to flag `this`/`super` keywords before `super()` callings.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-this-before-super: "error"*/
class A1 extends B {
constructor() {
this.a = 0;
super();
}
}
class A2 extends B {
constructor() {
this.foo();
super();
}
}
class A3 extends B {
constructor() {
super.foo();
super();
}
}
class A4 extends B {
constructor() {
super(this.foo());
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-this-before-super: "error"*/
class A1 {
constructor() {
this.a = 0; // OK, this class doesn't have an `extends` clause.
}
}
class A2 extends B {
constructor() {
super();
this.a = 0; // OK, this is after `super()`.
}
}
class A3 extends B {
foo() {
this.a = 0; // OK. this is not in a constructor.
}
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about using `this`/`super` before `super()` in constructors, you can safely disable this rule.
---
---
title: no-throw-literal
rule_type: suggestion
---
It is considered good practice to only `throw` the `Error` object itself or an object using the `Error` object as base objects for user-defined exceptions.
The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated.
This rule restricts what can be thrown as an exception. When it was first created, it only prevented literals from being thrown (hence the name), but it has now been expanded to only allow expressions which have a possibility of being an `Error` object.
## Rule Details
This rule is aimed at maintaining consistency when throwing exception by disallowing to throw literals and other expressions which cannot possibly be an `Error` object.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-throw-literal: "error"*/
throw "error";
throw 0;
throw undefined;
throw null;
const err = new Error();
throw "an " + err;
// err is recast to a string literal
const er2 = new Error();
throw `${err2}`
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-throw-literal: "error"*/
throw new Error();
throw new Error("error");
const e = new Error("error");
throw e;
try {
throw new Error("error");
} catch (e) {
throw e;
}
```
:::
## Options
This rule has no options.
## Known Limitations
Due to the limits of static analysis, this rule cannot guarantee that you will only throw `Error` objects.
Examples of **correct** code for this rule, but which do not throw an `Error` object:
::: correct
```js
/*eslint no-throw-literal: "error"*/
const err = "error";
throw err;
function foo(bar) {
console.log(bar);
}
throw foo("error");
throw new String("error");
const baz = {
bar: "error"
};
throw baz.bar;
```
:::
---
---
title: no-trailing-spaces
rule_type: layout
---
Sometimes in the course of editing files, you can end up with extra whitespace at the end of lines. These whitespace differences can be picked up by source control systems and flagged as diffs, causing frustration for developers. While this extra whitespace causes no functional issues, many code conventions require that trailing spaces be removed before check-in.
## Rule Details
This rule disallows trailing whitespace (spaces, tabs, and other Unicode whitespace characters) at the end of lines.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-trailing-spaces: "error"*/
var foo = 0;/* trailing whitespace */
var baz = 5;/* trailing whitespace */
/* trailing whitespace */
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-trailing-spaces: "error"*/
var foo = 0;
var baz = 5;
```
:::
## Options
This rule has an object option:
* `"skipBlankLines": false` (default) disallows trailing whitespace on empty lines
* `"skipBlankLines": true` allows trailing whitespace on empty lines
* `"ignoreComments": false` (default) disallows trailing whitespace in comment blocks
* `"ignoreComments": true` allows trailing whitespace in comment blocks
### skipBlankLines
Examples of **correct** code for this rule with the `{ "skipBlankLines": true }` option:
::: correct
```js
/*eslint no-trailing-spaces: ["error", { "skipBlankLines": true }]*/
var foo = 0;
var baz = 5;
// ↓ a line with whitespace only ↓
```
:::
### ignoreComments
Examples of **correct** code for this rule with the `{ "ignoreComments": true }` option:
::: correct
```js
/*eslint no-trailing-spaces: ["error", { "ignoreComments": true }]*/
// ↓ these comments have trailing whitespace →
//
/**
* baz
*
* bar
*/
```
:::
---
---
title: no-unassigned-vars
rule_type: problem
related_rules:
- init-declarations
- no-unused-vars
- prefer-const
---
This rule flags `let` or `var` declarations that are never assigned a value but are still read or used in the code. Since these variables will always be `undefined`, their usage is likely a programming mistake.
For example, if you check the value of a `status` variable, but it was never given a value, it will always be `undefined`:
```js
let status;
// ...forgot to assign a value to status...
if (status === 'ready') {
console.log('Ready!');
}
```
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unassigned-vars: "error"*/
let status;
if (status === 'ready') {
console.log('Ready!');
}
let user;
greet(user);
function test() {
let error;
return error || "Unknown error";
}
let options;
const { debug } = options || {};
let flag;
while (!flag) {
// Do something...
}
let config;
function init() {
return config?.enabled;
}
```
:::
In TypeScript:
::: incorrect
```ts
/*eslint no-unassigned-vars: "error"*/
let value: number | undefined;
console.log(value);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unassigned-vars: "error"*/
let message = "hello";
console.log(message);
let user;
user = getUser();
console.log(user.name);
let count;
count = 1;
count++;
// Variable is unused (should be reported by `no-unused-vars` only)
let temp;
let error;
if (somethingWentWrong) {
error = "Something went wrong";
}
console.log(error);
let item;
for (item of items) {
process(item);
}
let config;
function setup() {
config = { debug: true };
}
setup();
console.log(config);
let one = undefined;
if (one === two) {
// Noop
}
```
:::
In TypeScript:
::: correct
```ts
/*eslint no-unassigned-vars: "error"*/
declare let value: number | undefined;
console.log(value);
declare module "my-module" {
let value: string;
export = value;
}
```
:::
## Options
This rule has no options.
## When Not To Use It
You can disable this rule if your code intentionally uses variables that are declared and used, but are never assigned a value. This might be the case in:
- Legacy codebases where uninitialized variables are used as placeholders.
- Certain TypeScript use cases where variables are declared with a type and intentionally left unassigned (though using `declare` is preferred).
---
---
title: no-undef-init
rule_type: suggestion
related_rules:
- no-undefined
- no-void
---
In JavaScript, a variable that is declared and not initialized to any value automatically gets the value of `undefined`. For example:
```js
var foo;
console.log(foo === undefined); // true
```
It's therefore unnecessary to initialize a variable to `undefined`, such as:
```js
var foo = undefined;
```
It's considered a best practice to avoid initializing variables to `undefined`.
## Rule Details
This rule aims to eliminate `var` and `let` variable declarations that initialize to `undefined`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-undef-init: "error"*/
var foo = undefined;
let bar = undefined;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-undef-init: "error"*/
var foo;
let bar;
```
:::
Please note that this rule does not check `const` declarations, `using` declarations, `await using` declarations, destructuring patterns, function parameters, and class fields.
Examples of additional **correct** code for this rule:
::: correct
```js
/*eslint no-undef-init: "error"*/
const foo = undefined;
using foo1 = undefined;
await using foo2 = undefined;
let { bar = undefined } = baz;
[quux = undefined] = quuux;
(foo = undefined) => {};
class Foo {
bar = undefined;
}
```
:::
## Options
This rule has no options.
## When Not To Use It
There are situations where initializing to `undefined` behaves differently than omitting the initialization.
One such case is when a `var` declaration occurs inside of a loop. For example:
Example of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-undef-init: "error"*/
for (i = 0; i < 10; i++) {
var x = undefined;
console.log(x);
x = i;
}
```
:::
In this case, the `var x` is hoisted out of the loop, effectively creating:
```js
var x;
for (i = 0; i < 10; i++) {
x = undefined;
console.log(x);
x = i;
}
```
If you were to remove the initialization, then the behavior of the loop changes:
```js
for (i = 0; i < 10; i++) {
var x;
console.log(x);
x = i;
}
```
This code is equivalent to:
```js
var x;
for (i = 0; i < 10; i++) {
console.log(x);
x = i;
}
```
This produces a different outcome than defining `var x = undefined` in the loop, as `x` is no longer reset to `undefined` each time through the loop.
If you're using such an initialization inside of a loop, then you should disable this rule.
Example of **correct** code for this rule, because it is disabled on a specific line:
::: correct
```js
/*eslint no-undef-init: "error"*/
for (i = 0; i < 10; i++) {
var x = undefined; // eslint-disable-line no-undef-init
console.log(x);
x = i;
}
```
:::
Another such case is when a variable is redeclared using `var`. For example:
```js
function foo() {
var x = 1;
console.log(x); // output: 1
var x;
console.log(x); // output: 1
var x = undefined;
console.log(x); // output: undefined
}
foo();
```
In this case, you can avoid redeclaration by changing it to an assignment (`x = undefined;`), or use an eslint disable comment on a specific line.
---
---
title: no-undef
rule_type: problem
handled_by_typescript: true
related_rules:
- no-global-assign
- no-redeclare
---
This rule can help you locate potential ReferenceErrors resulting from misspellings of variable and parameter names, or accidental implicit globals (for example, from forgetting the `var` keyword in a `for` loop initializer).
## Rule Details
Any reference to an undeclared variable causes a warning, unless the variable is explicitly mentioned in a `/*global ...*/` comment, or specified in the [`globals` key in the configuration file](../use/configure/language-options#specifying-globals). A common use case for these is if you intentionally use globals that are defined elsewhere (e.g. in a script sourced from HTML).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-undef: "error"*/
const foo = someFunction();
const bar = a + 1;
```
:::
Examples of **correct** code for this rule with `global` declaration:
::: correct
```js
/*global someFunction, a*/
/*eslint no-undef: "error"*/
const foo = someFunction();
const bar = a + 1;
```
:::
Note that this rule does not disallow assignments to read-only global variables.
See [no-global-assign](no-global-assign) if you also want to disallow those assignments.
This rule also does not disallow redeclarations of global variables.
See [no-redeclare](no-redeclare) if you also want to disallow those redeclarations.
## Options
* `typeof` set to true will warn for variables used inside typeof check (Default false).
### typeof
Examples of **correct** code for the default `{ "typeof": false }` option:
::: correct
```js
/*eslint no-undef: "error"*/
if (typeof UndefinedIdentifier === "undefined") {
// do something ...
}
```
:::
You can use this option if you want to prevent `typeof` check on a variable which has not been declared.
Examples of **incorrect** code for the `{ "typeof": true }` option:
::: incorrect
```js
/*eslint no-undef: ["error", { "typeof": true }] */
if(typeof a === "string"){}
```
:::
Examples of **correct** code for the `{ "typeof": true }` option with `global` declaration:
::: correct
```js
/*global a*/
/*eslint no-undef: ["error", { "typeof": true }] */
if(typeof a === "string"){}
```
:::
## When Not To Use It
If explicit declaration of global variables is not to your taste.
## Compatibility
This rule provides compatibility with treatment of global variables in [JSHint](http://jshint.com/) and [JSLint](http://www.jslint.com).
---
---
title: no-undefined
rule_type: suggestion
related_rules:
- no-undef-init
- no-void
- no-shadow-restricted-names
- no-global-assign
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined
- https://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/
- https://es5.github.io/#x15.1.1.3
---
The `undefined` variable in JavaScript is actually a property of the global object. As such, in ECMAScript 3 it was possible to overwrite the value of `undefined`. While ECMAScript 5 disallows overwriting `undefined`, it's still possible to shadow `undefined`, such as:
```js
function doSomething(data) {
const undefined = "hi";
// doesn't do what you think it does
if (data === undefined) {
// ...
}
}
```
Because `undefined` can be overwritten or shadowed, reading `undefined` can give an unexpected value. (This is not the case for `null`, which is a keyword that always produces the same value.) To guard against this, you can avoid all uses of `undefined`, which is what some style guides recommend and what this rule enforces. Those style guides then also recommend:
* Variables that should be `undefined` are simply left uninitialized. (All uninitialized variables automatically get the value of `undefined` in JavaScript.)
* Checking if a value is `undefined` should be done with `typeof`.
* Using the `void` operator to generate the value of `undefined` if necessary.
As an alternative, you can use the [no-global-assign](no-global-assign) and [no-shadow-restricted-names](no-shadow-restricted-names) rules to prevent `undefined` from being shadowed or assigned a different value. This ensures that `undefined` will always hold its original, expected value.
## Rule Details
This rule aims to eliminate the use of `undefined`, and as such, generates a warning whenever it is used.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-undefined: "error"*/
const foo = undefined;
const undefined = "foo";
if (foo === undefined) {
// ...
}
function baz(undefined) {
// ...
}
bar(undefined, "lorem");
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-undefined: "error"*/
const foo = void 0;
const Undefined = "foo";
if (typeof foo === "undefined") {
// ...
}
global.undefined = "foo";
bar(void 0, "lorem");
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow the use of `undefined` in your code, then you can safely turn this rule off.
---
---
title: no-underscore-dangle
rule_type: suggestion
---
As far as naming conventions for identifiers go, dangling underscores may be the most polarizing in JavaScript. Dangling underscores are underscores at either the beginning or end of an identifier, such as:
```js
let _foo;
```
There is a long history of marking "private" members with dangling underscores in JavaScript, beginning with SpiderMonkey adding nonstandard methods such as `__defineGetter__()`. Since that time, using a single underscore prefix has become the most popular convention for indicating a member is not part of the public interface of an object.
It is recommended to use the formal [private class features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields) introduced in ECMAScript 2022 for encapsulating private data and methods rather than relying on naming conventions.
Allowing dangling underscores in identifiers is purely a convention and has no effect on performance, readability, or complexity. They do not have the same encapsulation benefits as private class features, even with this rule enabled.
## Rule Details
This rule disallows dangling underscores in identifiers.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-underscore-dangle: "error"*/
let foo_;
const __proto__ = {};
foo._bar();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-underscore-dangle: "error"*/
const _ = require('underscore');
const obj = _.contains(items, item);
obj.__proto__ = {};
const file = __filename;
function foo(_bar) {};
const bar = { onClick(_bar) {} };
const baz = (_bar) => {};
```
:::
## Options
This rule has an object option:
* `"allow"` allows specified identifiers to have dangling underscores
* `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object
* `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object
* `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object
* `"enforceInMethodNames": false` (default) allows dangling underscores in method names
* `"enforceInClassFields": false` (default) allows dangling underscores in es2022 class fields names
* `"allowInArrayDestructuring": true` (default) allows dangling underscores in variable names assigned by array destructuring
* `"allowInObjectDestructuring": true` (default) allows dangling underscores in variable names assigned by object destructuring
* `"allowFunctionParams": true` (default) allows dangling underscores in function parameter names
### allow
Examples of additional **correct** code for this rule with the `{ "allow": ["foo_", "_bar"] }` option:
::: correct
```js
/*eslint no-underscore-dangle: ["error", { "allow": ["foo_", "_bar"] }]*/
let foo_;
foo._bar();
```
:::
### allowAfterThis
Examples of **correct** code for this rule with the `{ "allowAfterThis": true }` option:
::: correct
```js
/*eslint no-underscore-dangle: ["error", { "allowAfterThis": true }]*/
const a = this.foo_;
this._bar();
```
:::
### allowAfterSuper
Examples of **correct** code for this rule with the `{ "allowAfterSuper": true }` option:
::: correct
```js
/*eslint no-underscore-dangle: ["error", { "allowAfterSuper": true }]*/
class Foo extends Bar {
doSomething() {
const a = super.foo_;
super._bar();
}
}
```
:::
### allowAfterThisConstructor
Examples of **correct** code for this rule with the `{ "allowAfterThisConstructor": true }` option:
::: correct
```js
/*eslint no-underscore-dangle: ["error", { "allowAfterThisConstructor": true }]*/
const a = this.constructor.foo_;
this.constructor._bar();
```
:::
### enforceInMethodNames
Examples of **incorrect** code for this rule with the `{ "enforceInMethodNames": true }` option:
::: incorrect
```js
/*eslint no-underscore-dangle: ["error", { "enforceInMethodNames": true }]*/
class Foo {
_bar() {}
}
class Bar {
bar_() {}
}
const o1 = {
_bar() {}
};
const o2 = {
bar_() {}
};
```
:::
### enforceInClassFields
Examples of **incorrect** code for this rule with the `{ "enforceInClassFields": true }` option:
::: incorrect
```js
/*eslint no-underscore-dangle: ["error", { "enforceInClassFields": true }]*/
class Foo {
_bar;
}
class Bar {
_bar = () => {};
}
class Baz {
bar_;
}
class Qux {
#_bar;
}
class FooBar {
#bar_;
}
```
:::
### allowInArrayDestructuring
Examples of **incorrect** code for this rule with the `{ "allowInArrayDestructuring": false }` option:
::: incorrect
```js
/*eslint no-underscore-dangle: ["error", { "allowInArrayDestructuring": false }]*/
const [_foo, _bar] = list;
const [foo_, ..._qux] = list;
const [foo, [bar, _baz]] = list;
```
:::
### allowInObjectDestructuring
Examples of **incorrect** code for this rule with the `{ "allowInObjectDestructuring": false }` option:
::: incorrect
```js
/*eslint no-underscore-dangle: ["error", { "allowInObjectDestructuring": false }]*/
const { foo, bar: _bar } = collection;
const { qux, xyz, _baz } = collection;
```
:::
Examples of **correct** code for this rule with the `{ "allowInObjectDestructuring": false }` option:
::: correct
```js
/*eslint no-underscore-dangle: ["error", { "allowInObjectDestructuring": false }]*/
const { foo, bar, _baz: { a, b } } = collection;
const { qux, xyz, _baz: baz } = collection;
```
:::
### allowFunctionParams
Examples of **incorrect** code for this rule with the `{ "allowFunctionParams": false }` option:
::: incorrect
```js
/*eslint no-underscore-dangle: ["error", { "allowFunctionParams": false }]*/
function foo1 (_bar) {}
function foo2 (_bar = 0) {}
function foo3 (..._bar) {}
const foo4 = function onClick (_bar) {}
const foo5 = function onClick (_bar = 0) {}
const foo6 = function onClick (..._bar) {}
const foo7 = (_bar) => {};
const foo8 = (_bar = 0) => {};
const foo9 = (..._bar) => {};
```
:::
## When Not To Use It
If you want to allow dangling underscores in identifiers, then you can safely turn this rule off.
---
---
title: no-unexpected-multiline
rule_type: problem
related_rules:
- func-call-spacing
- semi
- space-unary-ops
---
Semicolons are usually optional in JavaScript, because of automatic semicolon insertion (ASI). You can require or disallow semicolons with the [semi](./semi) rule.
The rules for ASI are relatively straightforward: As once described by Isaac Schlueter, a newline character always ends a statement, just like a semicolon, **except** where one of the following is true:
* The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with `.` or `,`.)
* The line is `--` or `++` (in which case it will decrement/increment the next token.)
* It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{`
* The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other binary operator that can only be found between two tokens in a single expression.
In the exceptions where a newline does **not** end a statement, a typing mistake to omit a semicolon causes two unrelated consecutive lines to be interpreted as one expression. Especially for a coding style without semicolons, readers might overlook the mistake. Although syntactically correct, the code might throw exceptions when it is executed.
## Rule Details
This rule disallows confusing multiline expressions where a newline looks like it is ending a statement, but is not.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unexpected-multiline: "error"*/
const foo = bar
(1 || 2).baz();
const hello = 'world'
[1, 2, 3].forEach(addNumber);
const x = function() {}
`hello`
const y = function() {}
y
`hello`
const z = foo
/regex/g.test(bar)
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unexpected-multiline: "error"*/
const foo = bar;
(1 || 2).baz();
const baz = bar
;(1 || 2).baz()
const hello = 'world';
[1, 2, 3].forEach(addNumber);
const hi = 'world'
void [1, 2, 3].forEach(addNumber);
const x = function() {};
`hello`
const tag = function() {}
tag `hello`
```
:::
## Options
This rule has no options.
## When Not To Use It
You can turn this rule off if you are confident that you will not accidentally introduce code like this.
Note that the patterns considered problems are **not** flagged by the [semi](semi) rule.
---
---
title: no-unmodified-loop-condition
rule_type: problem
---
Variables in a loop condition often are modified in the loop.
If not, it's possibly a mistake.
```js
while (node) {
doSomething(node);
}
```
```js
while (node) {
doSomething(node);
node = node.parent;
}
```
## Rule Details
This rule finds references which are inside of loop conditions, then checks the
variables of those references are modified in the loop.
If a reference is inside of a binary expression or a ternary expression, this rule checks the result of
the expression instead.
If a reference is inside of a dynamic expression (e.g. `CallExpression`,
`YieldExpression`, ...), this rule ignores it.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unmodified-loop-condition: "error"*/
let node = something;
while (node) {
doSomething(node);
}
node = other;
for (let j = 0; j < 5;) {
doSomething(j);
}
while (node !== root) {
doSomething(node);
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unmodified-loop-condition: "error"*/
while (node) {
doSomething(node);
node = node.parent;
}
for (let j = 0; j < items.length; ++j) {
doSomething(items[j]);
}
// OK, the result of this binary expression is changed in this loop.
while (node !== root) {
doSomething(node);
node = node.parent;
}
// OK, the result of this ternary expression is changed in this loop.
while (node ? A : B) {
doSomething(node);
node = node.parent;
}
// A property might be a getter which has side effect...
// Or "doSomething" can modify "obj.foo".
while (obj.foo) {
doSomething(obj);
}
// A function call can return various values.
while (check(obj)) {
doSomething(obj);
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to notified about references inside of loop conditions, then it's safe to disable this rule.
---
---
title: no-unneeded-ternary
rule_type: suggestion
related_rules:
- no-ternary
- no-nested-ternary
---
It's a common mistake in JavaScript to use a conditional expression to select between two Boolean values instead of using `!` to convert the test to a Boolean.
Here are some examples:
```js
// Bad
const isYes = answer === 1 ? true : false;
// Good
const isYes = answer === 1;
// Bad
const isNo = answer === 1 ? false : true;
// Good
const isNo = answer !== 1;
```
Another common mistake is using a single variable as both the conditional test and the consequent. In such cases, the logical `OR` can be used to provide the same functionality.
Here is an example:
```js
// Bad
foo(bar ? bar : 1);
// Good
foo(bar || 1);
```
## Rule Details
This rule disallow ternary operators when simpler alternatives exist.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unneeded-ternary: "error"*/
const a = x === 2 ? true : false;
const b = x ? true : false;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unneeded-ternary: "error"*/
const a = x === 2 ? "Yes" : "No";
const b = x !== false;
const c = x ? "Yes" : "No";
const d = x ? y : x;
f(x ? x : 1); // default assignment - would be disallowed if defaultAssignment option set to false. See option details below.
```
:::
## Options
This rule has an object option:
* `"defaultAssignment": true` (default) allows the conditional expression as a default assignment pattern
* `"defaultAssignment": false` disallows the conditional expression as a default assignment pattern
### defaultAssignment
When set to `true`, which it is by default, The `defaultAssignment` option allows expressions of the form `x ? x : expr` (where `x` is any identifier and `expr` is any expression).
Examples of additional **incorrect** code for this rule with the `{ "defaultAssignment": false }` option:
::: incorrect
```js
/*eslint no-unneeded-ternary: ["error", { "defaultAssignment": false }]*/
const a = x ? x : 1;
f(x ? x : 1);
```
:::
Note that `defaultAssignment: false` still allows expressions of the form `x ? expr : x` (where the identifier is on the right hand side of the ternary).
## When Not To Use It
You can turn this rule off if you are not concerned with unnecessary complexity in conditional expressions.
---
---
title: no-unreachable-loop
rule_type: problem
related_rules:
- no-unreachable
- no-constant-condition
- no-unmodified-loop-condition
- for-direction
---
A loop that can never reach the second iteration is a possible error in the code.
```js
for (let i = 0; i < arr.length; i++) {
if (arr[i].name === myName) {
doSomething(arr[i]);
// break was supposed to be here
}
break;
}
```
In rare cases where only one iteration (or at most one iteration) is intended behavior, the code should be refactored to use `if` conditionals instead of `while`, `do-while` and `for` loops. It's considered a best practice to avoid using loop constructs for such cases.
## Rule Details
This rule aims to detect and disallow loops that can have at most one iteration, by performing static code path analysis on loop bodies.
In particular, this rule will disallow a loop with a body that exits the loop in all code paths. If all code paths in the loop's body will end with either a `break`, `return` or a `throw` statement, the second iteration of such loop is certainly unreachable, regardless of the loop's condition.
This rule checks `while`, `do-while`, `for`, `for-in` and `for-of` loops. You can optionally disable checks for each of these constructs.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unreachable-loop: "error"*/
while (foo) {
doSomething(foo);
foo = foo.parent;
break;
}
function verifyList(head) {
let item = head;
do {
if (verify(item)) {
return true;
} else {
return false;
}
} while (item);
}
function findSomething(arr) {
for (let i = 0; i < arr.length; i++) {
if (isSomething(arr[i])) {
return arr[i];
} else {
throw new Error("Doesn't exist.");
}
}
}
for (key in obj) {
if (key.startsWith("_")) {
break;
}
firstKey = key;
firstValue = obj[key];
break;
}
for (foo of bar) {
if (foo.id === id) {
doSomething(foo);
}
break;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unreachable-loop: "error"*/
while (foo) {
doSomething(foo);
foo = foo.parent;
}
function verifyList(head) {
let item = head;
do {
if (verify(item)) {
item = item.next;
} else {
return false;
}
} while (item);
return true;
}
function findSomething(arr) {
for (let i = 0; i < arr.length; i++) {
if (isSomething(arr[i])) {
return arr[i];
}
}
throw new Error("Doesn't exist.");
}
for (key in obj) {
if (key.startsWith("_")) {
continue;
}
firstKey = key;
firstValue = obj[key];
break;
}
for (foo of bar) {
if (foo.id === id) {
doSomething(foo);
break;
}
}
```
:::
Please note that this rule is not designed to check loop conditions, and will not warn in cases such as the following examples.
Examples of additional **correct** code for this rule:
::: correct
```js
/*eslint no-unreachable-loop: "error"*/
do {
doSomething();
} while (false)
for (let i = 0; i < 1; i++) {
doSomething(i);
}
for (const a of [1]) {
doSomething(a);
}
```
:::
## Options
This rule has an object option, with one option:
* `"ignore"` - an optional array of loop types that will be ignored by this rule.
### ignore
You can specify up to 5 different elements in the `"ignore"` array:
* `"WhileStatement"` - to ignore all `while` loops.
* `"DoWhileStatement"` - to ignore all `do-while` loops.
* `"ForStatement"` - to ignore all `for` loops (does not apply to `for-in` and `for-of` loops).
* `"ForInStatement"` - to ignore all `for-in` loops.
* `"ForOfStatement"` - to ignore all `for-of` loops.
Examples of **correct** code for this rule with the `"ignore"` option:
::: correct
```js
/*eslint no-unreachable-loop: ["error", { "ignore": ["ForInStatement", "ForOfStatement"] }]*/
for (let key in obj) {
hasEnumerableProperties = true;
break;
}
for (const a of b) break;
```
:::
## Known Limitations
Static code path analysis, in general, does not evaluate conditions. Due to this fact, this rule might miss reporting cases such as the following:
```js
for (let i = 0; i < 10; i++) {
doSomething(i);
if (true) {
break;
}
}
```
---
---
title: no-unreachable
rule_type: problem
handled_by_typescript: true
extra_typescript_info: >-
TypeScript must be configured with
[`allowUnreachableCode: false`](https://www.typescriptlang.org/tsconfig#allowUnreachableCode)
for it to consider unreachable code an error.
---
Because the `return`, `throw`, `continue`, and `break` statements unconditionally exit a block of code, any statements after them cannot be executed. Unreachable statements are usually a mistake.
```js
function fn() {
x = 1;
return x;
x = 3; // this will never execute
}
```
Another kind of mistake is defining instance fields in a subclass whose constructor doesn't call `super()`. Instance fields of a subclass are only added to the instance after `super()`. If there are no `super()` calls, their definitions are never applied and therefore are unreachable code.
```js
class C extends B {
#x; // this will never be added to instances
constructor() {
return {};
}
}
```
## Rule Details
This rule disallows unreachable code after `return`, `throw`, `continue`, and `break` statements. This rule also flags definitions of instance fields in subclasses whose constructors don't have `super()` calls.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unreachable: "error"*/
function foo() {
return true;
console.log("done");
}
function bar() {
throw new Error("Oops!");
console.log("done");
}
while(value) {
break;
console.log("done");
}
throw new Error("Oops!");
console.log("done");
function baz() {
if (Math.random() < 0.5) {
return;
} else {
throw new Error();
}
console.log("done");
}
for (;;) {}
console.log("done");
```
:::
Examples of **correct** code for this rule, because of JavaScript function and variable hoisting:
::: correct
```js
/*eslint no-unreachable: "error"*/
function foo() {
return bar();
function bar() {
return 1;
}
}
function bar() {
return x;
var x;
}
switch (foo) {
case 1:
break;
var x;
}
```
:::
Examples of additional **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unreachable: "error"*/
class C extends B {
#x; // unreachable
#y = 1; // unreachable
a; // unreachable
b = 1; // unreachable
constructor() {
return {};
}
}
```
:::
Examples of additional **correct** code for this rule:
::: correct
```js
/*eslint no-unreachable: "error"*/
class D extends B {
#x;
#y = 1;
a;
b = 1;
constructor() {
super();
}
}
class E extends B {
#x;
#y = 1;
a;
b = 1;
// implicit constructor always calls `super()`
}
class F extends B {
static #x;
static #y = 1;
static a;
static b = 1;
constructor() {
return {};
}
}
```
:::
## Options
This rule has no options.
---
---
title: no-unsafe-finally
rule_type: problem
---
JavaScript suspends the control flow statements of `try` and `catch` blocks until the execution of `finally` block finishes. So, when `return`, `throw`, `break`, or `continue` is used in `finally`, control flow statements inside `try` and `catch` are overwritten, which is considered as unexpected behavior. Such as:
```js
// We expect this function to return 1;
(() => {
try {
return 1; // 1 is returned but suspended until finally block ends
} catch(err) {
return 2;
} finally {
return 3; // 3 is returned before 1, which we did not expect
}
})();
// > 3
```
```js
// We expect this function to throw an error, then return
(() => {
try {
throw new Error("Try"); // error is thrown but suspended until finally block ends
} finally {
return 3; // 3 is returned before the error is thrown, which we did not expect
}
})();
// > 3
```
```js
// We expect this function to throw Try(...) error from the catch block
(() => {
try {
throw new Error("Try")
} catch(err) {
throw err; // The error thrown from try block is caught and rethrown
} finally {
throw new Error("Finally"); // Finally(...) is thrown, which we did not expect
}
})();
// > Uncaught Error: Finally(...)
```
```js
// We expect this function to return 0 from try block.
(() => {
label: try {
return 0; // 0 is returned but suspended until finally block ends
} finally {
break label; // It breaks out the try-finally block, before 0 is returned.
}
return 1;
})();
// > 1
```
## Rule Details
This rule disallows `return`, `throw`, `break`, and `continue` statements inside `finally` blocks. It allows indirect usages, such as in `function` or `class` definitions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unsafe-finally: "error"*/
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
return 3;
}
};
```
:::
::: incorrect
```js
/*eslint no-unsafe-finally: "error"*/
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
throw new Error;
}
};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unsafe-finally: "error"*/
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
console.log("hola!");
}
};
```
:::
::: correct
```js
/*eslint no-unsafe-finally: "error"*/
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
let a = function() {
return "hola!";
}
}
};
```
:::
::: correct
```js
/*eslint no-unsafe-finally: "error"*/
let foo = function(a) {
try {
return 1;
} catch(err) {
return 2;
} finally {
switch(a) {
case 1: {
console.log("hola!")
break;
}
}
}
};
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow control flow operations in `finally` blocks, you can turn this rule off.
Note that [using `return` with `try`/`finally` in generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/return#using_return_with_try...finally) can be used to override the value returned.
If you want to use this feature of generator functions, you can disable this rule using an `eslint-disable` comment.
---
---
title: no-unsafe-negation
rule_type: problem
handled_by_typescript: true
---
Just as developers might type `-a + b` when they mean `-(a + b)` for the negative of a sum, they might type `!key in object` by mistake when they almost certainly mean `!(key in object)` to test that a key is not in an object. `!obj instanceof Ctor` is similar.
## Rule Details
This rule disallows negating the left operand of the following relational operators:
* [`in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in).
* [`instanceof` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unsafe-negation: "error"*/
if (!key in object) {
// operator precedence makes it equivalent to (!key) in object
// and type conversion makes it equivalent to (key ? "false" : "true") in object
}
if (!obj instanceof Ctor) {
// operator precedence makes it equivalent to (!obj) instanceof Ctor
// and it equivalent to always false since boolean values are not objects.
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unsafe-negation: "error"*/
if (!(key in object)) {
// key is not in object
}
if (!(obj instanceof Ctor)) {
// obj is not an instance of Ctor
}
```
:::
### Exception
For rare situations when negating the left operand is intended, this rule allows an exception.
If the whole negation is explicitly wrapped in parentheses, the rule will not report a problem.
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unsafe-negation: "error"*/
if ((!foo) in object) {
// allowed, because the negation is explicitly wrapped in parentheses
// it is equivalent to (foo ? "false" : "true") in object
// this is allowed as an exception for rare situations when that is the intended meaning
}
if(("" + !foo) in object) {
// you can also make the intention more explicit, with type conversion
}
```
:::
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unsafe-negation: "error"*/
if (!(foo) in object) {
// this is not an allowed exception
}
```
:::
## Options
This rule has an object option:
* `"enforceForOrderingRelations": false` (default) allows negation of the left-hand side of ordering relational operators (`<`, `>`, `<=`, `>=`)
* `"enforceForOrderingRelations": true` disallows negation of the left-hand side of ordering relational operators
### enforceForOrderingRelations
With this option set to `true` the rule is additionally enforced for:
* `<` operator.
* `>` operator.
* `<=` operator.
* `>=` operator.
The purpose is to avoid expressions such as `! a < b` (which is equivalent to `(a ? 0 : 1) < b`) when what is really intended is `!(a < b)`.
Examples of additional **incorrect** code for this rule with the `{ "enforceForOrderingRelations": true }` option:
::: incorrect
```js
/*eslint no-unsafe-negation: ["error", { "enforceForOrderingRelations": true }]*/
if (! a < b) {}
while (! a > b) {}
foo = ! a <= b;
foo = ! a >= b;
```
:::
## When Not To Use It
If you don't want to notify unsafe logical negations, then it's safe to disable this rule.
---
---
title: no-unsafe-optional-chaining
rule_type: problem
---
The optional chaining (`?.`) expression can short-circuit with a return value of `undefined`. Therefore, treating an evaluated optional chaining expression as a function, object, number, etc., can cause TypeError or unexpected results. For example:
```js
const obj = undefined;
1 in obj?.foo; // TypeError
with (obj?.foo); // TypeError
for (bar of obj?.foo); // TypeError
bar instanceof obj?.foo; // TypeError
const { bar } = obj?.foo; // TypeError
```
Also, parentheses limit the scope of short-circuiting in chains. For example:
```js
const obj = undefined;
(obj?.foo)(); // TypeError
(obj?.foo).bar; // TypeError
```
## Rule Details
This rule aims to detect some cases where the use of optional chaining doesn't prevent runtime errors. In particular, it flags optional chaining expressions in positions where short-circuiting to `undefined` causes throwing a TypeError afterward.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-unsafe-optional-chaining: "error"*/
(obj?.foo)();
(obj?.foo).bar;
(foo?.()).bar;
(foo?.()).bar();
(obj?.foo ?? obj?.bar)();
(foo || obj?.foo)();
(obj?.foo && foo)();
(foo ? obj?.foo : bar)();
(foo, obj?.bar).baz;
(obj?.foo)`template`;
new (obj?.foo)();
[...obj?.foo];
bar(...obj?.foo);
1 in obj?.foo;
bar instanceof obj?.foo;
for (bar of obj?.foo);
const { bar } = obj?.foo;
[{ bar } = obj?.foo] = [];
with (obj?.foo);
class A extends obj?.foo {}
const a = class A extends obj?.foo {};
async function foo () {
const { bar } = await obj?.foo;
(await obj?.foo)();
(await obj?.foo).bar;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unsafe-optional-chaining: "error"*/
(obj?.foo)?.();
obj?.foo();
(obj?.foo ?? bar)();
obj?.foo.bar;
obj.foo?.bar;
foo?.()?.bar;
(obj?.foo ?? bar)`template`;
new (obj?.foo ?? bar)();
const baz = {...obj?.foo};
const { bar } = obj?.foo || baz;
async function foo () {
const { bar } = await obj?.foo || baz;
(await obj?.foo)?.();
(await obj?.foo)?.bar;
}
```
:::
## Options
This rule has an object option:
* `disallowArithmeticOperators`: Disallow arithmetic operations on optional chaining expressions (Default `false`). If this is `true`, this rule warns arithmetic operations on optional chaining expressions, which possibly result in `NaN`.
### disallowArithmeticOperators
With this option set to `true` the rule is enforced for:
* Unary operators: `-`, `+`
* Arithmetic operators: `+`, `-`, `/`, `*`, `%`, `**`
* Assignment operators: `+=`, `-=`, `/=`, `*=`, `%=`, `**=`
Examples of additional **incorrect** code for this rule with the `{ "disallowArithmeticOperators": true }` option:
::: incorrect
```js
/*eslint no-unsafe-optional-chaining: ["error", { "disallowArithmeticOperators": true }]*/
+obj?.foo;
-obj?.foo;
obj?.foo + bar;
obj?.foo - bar;
obj?.foo / bar;
obj?.foo * bar;
obj?.foo % bar;
obj?.foo ** bar;
baz += obj?.foo;
baz -= obj?.foo;
baz /= obj?.foo;
baz *= obj?.foo;
baz %= obj?.foo;
baz **= obj?.foo;
async function foo () {
+await obj?.foo;
await obj?.foo + bar;
baz += await obj?.foo;
}
```
:::
---
---
title: no-unused-expressions
rule_type: suggestion
---
An unused expression which has no effect on the state of the program indicates a logic error.
For example, `n + 1;` is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement `n += 1;` instead. Sometimes, such unused expressions may be eliminated by some build tools in production environment, which possibly breaks application logic.
## Rule Details
This rule aims to eliminate unused expressions which have no effect on the state of the program.
This rule does not apply to function calls or constructor calls with the `new` operator, because they could have *side effects* on the state of the program.
```js
let i = 0;
function increment() { i += 1; }
increment(); // return value is unused, but i changed as a side effect
let nThings = 0;
function Thing() { nThings += 1; }
new Thing(); // constructed object is unused, but nThings changed as a side effect
```
This rule does not apply to directives (which are in the form of literal string expressions such as `"use strict";` at the beginning of a script, module, or function) when using ES5+ environments. In ES3 environments, directives are treated as unused expressions by default, but this behavior can be changed using the `ignoreDirectives` option.
Sequence expressions (those using a comma, such as `a = 1, b = 2`) are always considered unused unless their return value is assigned or used in a condition evaluation, or a function call is made with the sequence expression value.
## Options
This rule, in its default state, does not require any arguments. If you would like to enable one or more of the following you may pass an object with the options set as follows:
* `allowShortCircuit` set to `true` will allow you to use short circuit evaluations in your expressions (Default: `false`).
* `allowTernary` set to `true` will enable you to use ternary operators in your expressions similarly to short circuit evaluations (Default: `false`).
* `allowTaggedTemplates` set to `true` will enable you to use tagged template literals in your expressions (Default: `false`).
* `enforceForJSX` set to `true` will flag unused JSX element expressions (Default: `false`).
* `ignoreDirectives` set to `true` will prevent directives from being reported as unused expressions when linting with `ecmaVersion: 3` (Default: `false`).
These options allow unused expressions *only if all* of the code paths either directly change the state (for example, assignment statement) or could have *side effects* (for example, function call).
Examples of **incorrect** code for the default `{ "allowShortCircuit": false, "allowTernary": false }` options:
::: incorrect
```js
/*eslint no-unused-expressions: "error"*/
0
if(0) 0
{0}
f(0), {}
a && b()
a, b()
c = a, b;
a() && function namedFunctionInExpressionContext () {f();}
(function anIncompleteIIFE () {});
injectGlobal`body{ color: red; }`
```
:::
Examples of **correct** code for the default `{ "allowShortCircuit": false, "allowTernary": false }` options:
::: correct
```js
/*eslint no-unused-expressions: "error"*/
{} // In this context, this is a block statement, not an object literal
{ myLabel: foo() } // In this context, this is a block statement with a label and expression, not an object literal
function namedFunctionDeclaration () {}
(function aGenuineIIFE () {}());
f()
a = 0
new C
delete a.b
void a
```
:::
Note that one or more string expression statements (with or without semi-colons) will only be considered as unused if they are not in the beginning of a script, module, or function (alone and uninterrupted by other statements). Otherwise, they will be treated as part of a "directive prologue", a section potentially usable by JavaScript engines. This includes "strict mode" directives.
Examples of **correct** code for this rule in regard to directives:
::: correct
```js
/*eslint no-unused-expressions: "error"*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
class Foo {
someMethod() {
"use strict";
}
}
```
:::
Examples of **incorrect** code for this rule in regard to directives:
::: incorrect
```js
/*eslint no-unused-expressions: "error"*/
doSomething();
"use strict"; // this isn't in a directive prologue, because there is a non-directive statement before it
function foo() {
"bar" + 1;
}
class Foo {
static {
"use strict"; // class static blocks do not have directive prologues
}
}
```
:::
### allowShortCircuit
Examples of **incorrect** code for the `{ "allowShortCircuit": true }` option:
::: incorrect
```js
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/
a || b
```
:::
Examples of **correct** code for the `{ "allowShortCircuit": true }` option:
::: correct
```js
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/
a && b()
a() || (b = c)
```
:::
### allowTernary
Examples of **incorrect** code for the `{ "allowTernary": true }` option:
::: incorrect
```js
/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/
a ? b : 0
a ? b : c()
```
:::
Examples of **correct** code for the `{ "allowTernary": true }` option:
::: correct
```js
/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/
a ? b() : c()
a ? (b = c) : d()
```
:::
### allowShortCircuit and allowTernary
Examples of **correct** code for the `{ "allowShortCircuit": true, "allowTernary": true }` options:
::: correct
```js
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true, "allowTernary": true }]*/
a ? b() || (c = d) : e()
```
:::
### allowTaggedTemplates
Examples of **incorrect** code for the `{ "allowTaggedTemplates": true }` option:
::: incorrect
```js
/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/
`some untagged template string`;
```
:::
Examples of **correct** code for the `{ "allowTaggedTemplates": true }` option:
::: correct
```js
/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/
tag`some tagged template string`;
```
:::
### enforceForJSX
JSX is most-commonly used in the React ecosystem, where it is compiled to `React.createElement` expressions. Though free from side-effects, these calls are not automatically flagged by the `no-unused-expression` rule. If you're using React, or any other side-effect-free JSX pragma, this option can be enabled to flag these expressions.
Examples of **incorrect** code for the `{ "enforceForJSX": true }` option:
::: incorrect { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/
;
<>>;
```
:::
Examples of **correct** code for the `{ "enforceForJSX": true }` option:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/
const myComponentPartial = ;
const myFragment = <>>;
```
:::
### ignoreDirectives
When set to `false` (default), this rule reports directives (like `"use strict"`) as unused expressions when linting with `ecmaVersion: 3`. This default behavior exists because ES3 environments do not formally support directives, meaning such strings are effectively unused expressions in that specific context.
Set this option to `true` to prevent directives from being reported as unused, even when `ecmaVersion: 3` is specified. This option is primarily useful for projects that need to maintain a single codebase containing directives while supporting both older ES3 environments and modern (ES5+) environments.
**Note:** In ES5+ environments, directives are always ignored regardless of this setting.
Examples of **incorrect** code for the `{ "ignoreDirectives": false }` option and `ecmaVersion: 3`:
::: incorrect { "ecmaVersion": 3, "sourceType": "script" }
```js
/*eslint no-unused-expressions: ["error", { "ignoreDirectives": false }]*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
```
:::
Examples of **correct** code for the `{ "ignoreDirectives": true }` option and `ecmaVersion: 3`:
::: correct { "ecmaVersion": 3, "sourceType": "script" }
```js
/*eslint no-unused-expressions: ["error", { "ignoreDirectives": true }]*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
```
:::
### TypeScript Support
This rule supports TypeScript-specific expressions and follows these guidelines:
1. Directives (like `'use strict'`) are allowed in module and namespace declarations
2. Type-related expressions are treated as unused if their wrapped value expressions are unused:
* Type assertions (`x as number`, `x`)
* Non-null assertions (`x!`)
* Type instantiations (`Set`)
**Note**: Although type expressions never have runtime side effects (e.g., `x!` is equivalent to `x` at runtime), they can be used to assert types for testing purposes.
Examples of **correct** code for this rule when using TypeScript:
::: correct
```ts
/* eslint no-unused-expressions: "error" */
// Type expressions wrapping function calls are allowed
function getSet() {
return Set;
}
getSet();
getSet() as Set;
getSet()!;
// Directives in modules and namespaces
module Foo {
'use strict';
'hello world';
}
namespace Bar {
'use strict';
export class Baz {}
}
```
:::
Examples of **incorrect** code for this rule when using TypeScript:
::: incorrect
```ts
/* eslint no-unused-expressions: "error" */
// Standalone type expressions
Set;
1 as number;
window!;
// Expressions inside namespaces
namespace Bar {
123;
}
```
:::
---
---
title: no-unused-labels
rule_type: suggestion
related_rules:
- no-extra-label
- no-labels
- no-label-var
---
Labels that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring.
```js
OUTER_LOOP:
for (const student of students) {
if (checkScores(student.scores)) {
continue;
}
doSomething(student);
}
```
In this case, probably removing `OUTER_LOOP:` had been forgotten.
Such labels take up space in the code and can lead to confusion by readers.
## Rule Details
This rule is aimed at eliminating unused labels.
Problems reported by this rule can be fixed automatically, except when there are any comments between the label and the following statement, or when removing a label would cause the following statement to become a directive such as `"use strict"`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unused-labels: "error"*/
A: var foo = 0;
B: {
foo();
}
C:
for (let i = 0; i < 10; ++i) {
foo();
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unused-labels: "error"*/
A: {
if (foo()) {
break A;
}
bar();
}
B:
for (let i = 0; i < 10; ++i) {
if (foo()) {
break B;
}
bar();
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about unused labels, then it's safe to disable this rule.
---
---
title: no-unused-private-class-members
rule_type: problem
---
Private class members that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such class members take up space in the code and can lead to confusion by readers.
## Rule Details
This rule reports unused private class members.
* A private field or method is considered to be unused if its value is never read.
* A private accessor is considered to be unused if it is never accessed (read or write).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unused-private-class-members: "error"*/
class A {
#unusedMember = 5;
}
class B {
#usedOnlyInWrite = 5;
method() {
this.#usedOnlyInWrite = 42;
}
}
class C {
#usedOnlyToUpdateItself = 5;
method() {
this.#usedOnlyToUpdateItself++;
}
}
class D {
#unusedMethod() {}
}
class E {
get #unusedAccessor() {}
set #unusedAccessor(value) {}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unused-private-class-members: "error"*/
class A {
#usedMember = 42;
method() {
return this.#usedMember;
}
}
class B {
#usedMethod() {
return 42;
}
anotherMethod() {
return this.#usedMethod();
}
}
class C {
get #usedAccessor() {}
set #usedAccessor(value) {}
method() {
this.#usedAccessor = 42;
}
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to be notified about unused private class members, you can safely turn this rule off.
---
---
title: no-unused-vars
rule_type: problem
related_rules:
- no-unassigned-vars
- no-useless-assignment
---
Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.
## Rule Details
This rule is aimed at eliminating unused variables, functions, and function parameters.
A variable `foo` is considered to be used if any of the following are true:
* It is called (`foo()`) or constructed (`new foo()`)
* It is read (`let bar = foo`)
* It is passed into a function as an argument (`doSomething(foo)`)
* It is read inside of a function that is passed to another function (`doSomething(function() { foo(); })`)
A variable is *not* considered to be used if it is only ever declared (`let foo = 5`) or assigned to (`foo = 7`).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-unused-vars: "error"*/
/*global some_unused_var*/
// It checks variables you have defined as global
some_unused_var = 42;
let x;
// Write-only variables are not considered as used.
let y = 10;
y = 5;
// A read for a modification of itself is not considered as used.
let z = 0;
z = z + 1;
// By default, unused arguments cause warnings.
(function(foo) {
return 5;
})();
// Unused recursive functions also cause warnings.
function fact(n) {
if (n < 2) return 1;
return n * fact(n - 1);
}
// When a function definition destructures an array, unused entries from the array also cause warnings.
function getY([x, y]) {
return y;
}
getY(["a", "b"]);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-unused-vars: "error"*/
const x = 10;
alert(x);
// foo is considered used here
myFunc(function foo() {
// ...
}.bind(this));
(function(foo) {
return foo;
})();
var myFunc;
myFunc = setTimeout(function() {
// myFunc is considered used
myFunc();
}, 50);
// Only the second argument from the destructured array is used.
function getY([, y]) {
return y;
}
getY(["a", "b"]);
```
:::
### exported
In environments outside of CommonJS or ECMAScript modules, you may use `var` to create a global variable that may be used by other scripts. You can use the `/* exported variableName */` comment block to indicate that this variable is being exported and therefore should not be considered unused.
Note that `/* exported */` has no effect for any of the following:
* when `languageOptions.sourceType` is `module` (default) or `commonjs`
* when `languageOptions.parserOptions.ecmaFeatures.globalReturn` is `true`
The line comment `// exported variableName` will not work as `exported` is not line-specific.
```js
/* exported global_var */
var global_var = 42;
```
Examples of **correct** code for `/* exported variableName */` operation with `no-unused-vars`:
::: correct { "sourceType": "script" }
```js
/*eslint no-unused-vars: "error"*/
/* exported global_var */
var global_var = 42;
```
:::
## Options
This rule takes one argument which can be a string or an object. The string settings are the same as those of the `vars` property (explained below).
By default this rule is enabled with `all` option for caught errors and variables, and `after-used` for arguments.
```json
{
"rules": {
"no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"caughtErrors": "all",
"ignoreRestSiblings": false,
"ignoreUsingDeclarations": false,
"reportUsedIgnorePattern": false
}]
}
}
```
### vars
The `vars` option has two settings:
* `"all"` checks all variables for usage, including those in the global scope. However, it excludes variables targeted by other options like `args` and `caughtErrors`. This is the default setting.
* `"local"` allows variables in the global scope to be unused.
#### vars: local
Examples of **correct** code for the `{ "vars": "local" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "vars": "local" }]*/
/*global some_unused_var */
some_unused_var = 42;
```
:::
Examples of **correct** code for the `{ "vars": "local" }` option with `"languageOptions": { "sourceType": "script" }`:
::: correct { "sourceType": "script" }
```js
/*eslint no-unused-vars: ["error", { "vars": "local" }]*/
const foo = 42;
let bar;
let baz = 42;
var qux;
var quux = 42;
```
:::
### varsIgnorePattern
The `varsIgnorePattern` option specifies exceptions not to check for usage: variables whose names match a regexp pattern. For example, variables whose names contain `ignored` or `Ignored`. However, it excludes variables targeted by other options like `argsIgnorePattern` and `caughtErrorsIgnorePattern`.
Examples of **correct** code for the `{ "varsIgnorePattern": "[iI]gnored" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "varsIgnorePattern": "[iI]gnored" }]*/
const firstVarIgnored = 1;
const secondVar = 2;
console.log(secondVar);
```
:::
### args
The `args` option has three settings:
* `after-used` - unused positional arguments that occur before the last used argument will not be checked, but all named arguments and all positional arguments after the last used argument will be checked.
* `all` - all named arguments must be used.
* `none` - do not check arguments.
#### args: after-used
Examples of **incorrect** code for the default `{ "args": "after-used" }` option:
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "args": "after-used" }]*/
// 2 errors, for the parameters after the last used parameter (bar)
// "baz" is defined but never used
// "qux" is defined but never used
(function(foo, bar, baz, qux) {
return bar;
})();
```
:::
Examples of **correct** code for the default `{ "args": "after-used" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", {"args": "after-used"}]*/
(function(foo, bar, baz, qux) {
return qux;
})();
```
:::
#### args: all
Examples of **incorrect** code for the `{ "args": "all" }` option:
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "args": "all" }]*/
// 2 errors
// "foo" is defined but never used
// "baz" is defined but never used
(function(foo, bar, baz) {
return bar;
})();
```
:::
#### args: none
Examples of **correct** code for the `{ "args": "none" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "args": "none" }]*/
(function(foo, bar, baz) {
return bar;
})();
```
:::
### argsIgnorePattern
The `argsIgnorePattern` option specifies exceptions not to check for usage: arguments whose names match a regexp pattern. For example, variables whose names begin with an underscore.
Examples of **correct** code for the `{ "argsIgnorePattern": "^_" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }]*/
function foo(x, _y) {
return x + 1;
}
foo();
```
:::
### caughtErrors
The `caughtErrors` option is used for `catch` block arguments validation.
It has two settings:
* `all` - all named arguments must be used. This is the default setting.
* `none` - do not check error objects.
#### caughtErrors: all
Not specifying this option is equivalent of assigning it to `all`.
Examples of **incorrect** code for the `{ "caughtErrors": "all" }` option:
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "caughtErrors": "all" }]*/
// 1 error
// "err" is defined but never used
try {
//...
} catch (err) {
console.error("errors");
}
```
:::
#### caughtErrors: none
Examples of **correct** code for the `{ "caughtErrors": "none" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "caughtErrors": "none" }]*/
try {
//...
} catch (err) {
console.error("errors");
}
```
:::
### caughtErrorsIgnorePattern
The `caughtErrorsIgnorePattern` option specifies exceptions not to check for usage: catch arguments whose names match a regexp pattern. For example, variables whose names begin with a string 'ignore'.
Examples of **correct** code for the `{ "caughtErrorsIgnorePattern": "^ignore" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "caughtErrors": "all", "caughtErrorsIgnorePattern": "^ignore" }]*/
try {
//...
} catch (ignoreErr) {
console.error("errors");
}
```
:::
### destructuredArrayIgnorePattern
The `destructuredArrayIgnorePattern` option specifies exceptions not to check for usage: elements of array destructuring patterns whose names match a regexp pattern. For example, variables whose names begin with an underscore.
Examples of **correct** code for the `{ "destructuredArrayIgnorePattern": "^_" }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "destructuredArrayIgnorePattern": "^_" }]*/
const [a, _b, c] = ["a", "b", "c"];
console.log(a+c);
const { x: [_a, foo] } = bar;
console.log(foo);
function baz([_c, x]) {
x;
}
baz();
function test({p: [_q, r]}) {
r;
}
test();
let _m, n;
foo.forEach(item => {
[_m, n] = item;
console.log(n);
});
let _o, p;
_o = 1;
[_o, p] = foo;
p;
```
:::
### ignoreRestSiblings
The `ignoreRestSiblings` option is a boolean (default: `false`). Using a [Rest Property](https://github.com/tc39/proposal-object-rest-spread) it is possible to "omit" properties from an object, but by default the sibling properties are marked as "unused". With this option enabled the rest property's siblings are ignored.
Examples of **correct** code for the `{ "ignoreRestSiblings": true }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/
// 'foo' and 'bar' were ignored because they have a rest property sibling.
const { foo, ...rest } = data;
console.log(rest);
// OR
let bar;
({ bar, ...rest } = data);
```
:::
### ignoreClassWithStaticInitBlock
The `ignoreClassWithStaticInitBlock` option is a boolean (default: `false`). Static initialization blocks allow you to initialize static variables and execute code during the evaluation of a class definition, meaning the static block code is executed without creating a new instance of the class. When set to `true`, this option ignores classes containing static initialization blocks.
Examples of **incorrect** code for the `{ "ignoreClassWithStaticInitBlock": true }` option
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static myProperty = "some string";
static mymethod() {
return "some string";
}
}
class Bar {
static {
let baz; // unused variable
}
}
```
:::
Examples of **correct** code for the `{ "ignoreClassWithStaticInitBlock": true }` option
::: correct
```js
/*eslint no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static {
let bar = "some string";
console.log(bar);
}
}
```
:::
### ignoreUsingDeclarations
The `ignoreUsingDeclarations` option is a boolean (default: `false`). Explicit resource management allows automatic teardown of disposables by calling `Symbol.dispose` or `Symbol.asyncDispose` method implicitly at the end of the variable's scope. When this option is set to `true`, this rule ignores variables declared with `using` or `await using`.
Examples of **incorrect** code for the `{ "ignoreUsingDeclarations": true }` option:
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/
const resource = getResource();
```
:::
Examples of **correct** code for the `{ "ignoreUsingDeclarations": true }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/
using syncResource = getSyncResource();
await using asyncResource = getAsyncResource();
```
:::
### reportUsedIgnorePattern
The `reportUsedIgnorePattern` option is a boolean (default: `false`).
Using this option will report variables that match any of the valid ignore
pattern options (`varsIgnorePattern`, `argsIgnorePattern`, `caughtErrorsIgnorePattern`, or
`destructuredArrayIgnorePattern`) if they have been used.
Examples of **incorrect** code for the `{ "reportUsedIgnorePattern": true }` option:
::: incorrect
```js
/*eslint no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
const firstVarIgnored = 1;
const secondVar = 2;
console.log(firstVarIgnored, secondVar);
```
:::
Examples of **correct** code for the `{ "reportUsedIgnorePattern": true }` option:
::: correct
```js
/*eslint no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
const firstVar = 1;
const secondVar = 2;
console.log(firstVar, secondVar);
```
:::
## When Not To Use It
If you don't want to be notified about unused variables or function arguments, you can safely turn this rule off.
---
---
title: no-use-before-define
rule_type: problem
---
In JavaScript, prior to ES6, variable and function declarations are hoisted to the top of a scope, so it's possible to use identifiers before their formal declarations in code. This can be confusing and some believe it is best to always declare variables and functions before using them.
In ES6, block-level bindings (`let` and `const`) introduce a "temporal dead zone" where a `ReferenceError` will be thrown with any attempt to access the variable before its declaration.
## Rule Details
This rule will warn when it encounters a reference to an identifier that has not yet been declared.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-use-before-define: "error"*/
alert(a);
var a = 10;
f();
function f() {}
function g() {
return b;
}
var b = 1;
{
alert(c);
let c = 1;
}
{
class C extends C {}
}
{
class C {
static x = "foo";
[C.x]() {}
}
}
{
const C = class {
static x = C;
}
}
{
const C = class {
static {
C.x = "foo";
}
}
}
export { foo };
const foo = 1;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-use-before-define: "error"*/
var a;
a = 10;
alert(a);
function f() {}
f(1);
var b = 1;
function g() {
return b;
}
{
let c;
c++;
}
{
class C {
static x = C;
}
}
{
const C = class C {
static x = C;
}
}
{
const C = class {
x = C;
}
}
{
const C = class C {
static {
C.x = "foo";
}
}
}
const foo = 1;
export { foo };
```
:::
## Options
```json
{
"no-use-before-define": ["error", {
"functions": true,
"classes": true,
"variables": true,
"allowNamedExports": false,
"enums": true,
"typedefs": true,
"ignoreTypeReferences": true
}]
}
```
* `functions` (`boolean`) -
This flag determines whether or not the rule checks function declarations.
If this is `true`, the rule warns on every reference to a function before the function declaration.
Otherwise, the rule ignores those references.
Function declarations are hoisted, so it's safe to disable this option (note that some idiomatic patterns, such as [mutual recursion](https://en.wikipedia.org/wiki/Mutual_recursion), are incompatible with enabling this option).
Default is `true`.
* `classes` (`boolean`) -
This flag determines whether or not the rule checks class declarations of upper scopes.
If this is `true`, the rule warns on every reference to a class before the class declaration.
Otherwise, the rule ignores such references, provided the declaration is in an upper function scope.
Class declarations are not hoisted, so it might be dangerous to disable this option.
Default is `true`.
* `variables` (`boolean`) -
This flag determines whether or not the rule checks variable declarations in upper scopes.
If this is `true`, the rule warns on every reference to a variable before the variable declaration.
Otherwise, the rule ignores a reference if the declaration is in an upper scope, while still reporting the reference if it's in the same scope as the declaration.
Default is `true`.
* `allowNamedExports` (`boolean`) -
If this flag is set to `true`, the rule always allows references in `export {};` declarations.
These references are safe even if the variables are declared later in the code.
Default is `false`.
This rule additionally supports TypeScript type syntax. The following options enable checking for the references to `type`, `interface` and `enum` declarations:
* `enums` (`boolean`) -
If it is `true`, the rule warns every reference to an `enum` before it is defined.
Default is `true`.
* `typedefs` (`boolean`) -
If it is `true`, this rule warns every reference to a type `alias` or `interface` before its declaration. If `false`, the rule allows using type `alias`es and `interface`s before they are defined.
Default is `true`.
* `ignoreTypeReferences` (`boolean`) -
If it is `true`, rule will ignore all type references, such as in type annotations and assertions.
Default is `true`.
This rule accepts `"nofunc"` string as an option.
`"nofunc"` is the same as `{ "functions": false, "classes": true, "variables": true, "allowNamedExports": false, "enums": true, "typedefs": true, "ignoreTypeReferences": true }`.
### functions
Examples of **correct** code for the `{ "functions": false }` option:
::: correct
```js
/*eslint no-use-before-define: ["error", { "functions": false }]*/
f();
function f() {}
```
:::
This option allows references to function declarations. For function expressions and arrow functions, please see the [`variables`](#variables) option.
### classes
Examples of **incorrect** code for the `{ "classes": false }` option:
::: incorrect
```js
/*eslint no-use-before-define: ["error", { "classes": false }]*/
new A();
class A {
}
{
class C extends C {}
}
{
class C extends D {}
class D {}
}
{
class C {
static x = "foo";
[C.x]() {}
}
}
{
class C {
static {
new D();
}
}
class D {}
}
```
:::
Examples of **correct** code for the `{ "classes": false }` option:
::: correct
```js
/*eslint no-use-before-define: ["error", { "classes": false }]*/
function foo() {
return new A();
}
class A {
}
```
:::
### variables
Examples of **incorrect** code for the `{ "variables": false }` option:
::: incorrect
```js
/*eslint no-use-before-define: ["error", { "variables": false }]*/
console.log(foo);
var foo = 1;
f();
const f = () => {};
g();
const g = function() {};
{
const C = class {
static x = C;
}
}
{
const C = class {
static x = foo;
}
const foo = 1;
}
{
class C {
static {
this.x = foo;
}
}
const foo = 1;
}
```
:::
Examples of **correct** code for the `{ "variables": false }` option:
::: correct
```js
/*eslint no-use-before-define: ["error", { "variables": false }]*/
function baz() {
console.log(foo);
}
var foo = 1;
const a = () => f();
function b() { return f(); }
const c = function() { return f(); }
const f = () => {};
const e = function() { return g(); }
const g = function() {}
{
const C = class {
x = foo;
}
const foo = 1;
}
```
:::
### allowNamedExports
Examples of **correct** code for the `{ "allowNamedExports": true }` option:
::: correct
```js
/*eslint no-use-before-define: ["error", { "allowNamedExports": true }]*/
export { a, b, f, C };
const a = 1;
let b;
function f () {}
class C {}
```
:::
Examples of **incorrect** code for the `{ "allowNamedExports": true }` option:
::: incorrect
```js
/*eslint no-use-before-define: ["error", { "allowNamedExports": true }]*/
export default a;
const a = 1;
const b = c;
export const c = 1;
export function foo() {
return d;
}
const d = 1;
```
:::
### enums (TypeScript only)
Examples of **incorrect** code for the `{ "enums": true }` option:
::: incorrect
```ts
/*eslint no-use-before-define: ["error", { "enums": true }]*/
const x = Foo.FOO;
enum Foo {
FOO,
}
```
:::
Examples of **correct** code for the `{ "enums": true }` option:
::: correct
```ts
/*eslint no-use-before-define: ["error", { "enums": true }]*/
enum Foo {
FOO,
}
const x = Foo.FOO;
```
:::
### typedefs (TypeScript only)
Examples of **incorrect** code for the `{ "enums": true }` with `{ "ignoreTypeReferences": false }` option:
::: incorrect
```ts
/*eslint no-use-before-define: ["error", { "typedefs": true, "ignoreTypeReferences": false }]*/
let myVar: StringOrNumber;
type StringOrNumber = string | number;
const x: Foo = {};
interface Foo {}
```
:::
Examples of **correct** code for the `{ "typedefs": true }` with `{ "ignoreTypeReferences": false }` option:
::: correct
```ts
/*eslint no-use-before-define: ["error", { "typedefs": true, "ignoreTypeReferences": false }]*/
type StringOrNumber = string | number;
let myVar: StringOrNumber;
interface Foo {}
const x: Foo = {};
```
:::
### ignoreTypeReferences (TypeScript only)
Examples of **incorrect** code for the `{ "ignoreTypeReferences": false }` option:
::: incorrect
```ts
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/
let var1: StringOrNumber;
type StringOrNumber = string | number;
let var2: Enum;
enum Enum {}
```
:::
Examples of **correct** code for the `{ "ignoreTypeReferences": false }` option:
::: correct
```ts
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/
type StringOrNumber = string | number;
let myVar: StringOrNumber;
enum Enum {}
let var2: Enum;
```
Examples of **correct** code for the `{ "ignoreTypeReferences": false }` with `{ "typedefs": false }` option:
::: correct
```ts
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false, "typedefs": false, }]*/
let myVar: StringOrNumber;
type StringOrNumber = string | number;
const x: Foo = {};
interface Foo {}
```
:::
### nofunc
Examples of **incorrect** code for the `"nofunc"` option:
::: incorrect
```js
/*eslint no-use-before-define: ["error", "nofunc"]*/
a();
var a = function() {};
console.log(foo);
var foo = 1;
function f() {
return b;
}
var b = 1;
new A();
class A {
}
function g() {
return new B();
}
class B {
}
export default bar;
const bar = 1;
export { baz };
const baz = 1;
```
:::
::: incorrect
```ts
/*eslint no-use-before-define: ["error", "nofunc"]*/
function foo(): Foo {
return Foo.FOO;
}
enum Foo {
FOO,
}
```
:::
Examples of **correct** code for the `"nofunc"` option:
::: correct
```js
/*eslint no-use-before-define: ["error", "nofunc"]*/
f();
function f() {}
class A {
}
new A();
var a = 10;
alert(a);
const foo = 1;
export { foo };
const bar = 1;
export default bar;
```
:::
::: correct
```ts
/*eslint no-use-before-define: ["error", "nofunc"]*/
enum Foo {
FOO,
}
const foo = Foo.Foo;
```
:::
---
---
title: no-useless-assignment
rule_type: suggestion
related_rules:
- no-unused-vars
further_reading:
- https://en.wikipedia.org/wiki/Dead_store
- https://rules.sonarsource.com/javascript/RSPEC-1854/
- https://cwe.mitre.org/data/definitions/563.html
- https://wiki.sei.cmu.edu/confluence/display/c/MSC13-C.+Detect+and+remove+unused+values
- https://wiki.sei.cmu.edu/confluence/display/java/MSC56-J.+Detect+and+remove+superfluous+code+and+values
---
[Wikipedia describes a "dead store"](https://en.wikipedia.org/wiki/Dead_store) as follows:
> In computer programming, a local variable that is assigned a value but is not read by any subsequent instruction is referred to as a **dead store**.
"Dead stores" waste processing and memory, so it is better to remove unnecessary assignments to variables.
Also, if the author intended the variable to be used, there is likely a mistake around the dead store.
For example,
* you should have used a stored value but forgot to do so.
* you made a mistake in the name of the variable to be stored.
```js
let id = "x1234"; // this is a "dead store" - this value ("x1234") is never read
id = generateId();
doSomethingWith(id);
```
## Rule Details
This rule aims to report variable assignments when the value is not used.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint no-useless-assignment: "error" */
function fn1() {
let v = 'used';
doSomething(v);
v = 'unused';
}
function fn2() {
let v = 'used';
if (condition) {
v = 'unused';
return
}
doSomething(v);
}
function fn3() {
let v = 'used';
if (condition) {
doSomething(v);
} else {
v = 'unused';
}
}
function fn4() {
let v = 'unused';
if (condition) {
v = 'used';
doSomething(v);
return
}
}
function fn5() {
let v = 'used';
if (condition) {
let v = 'used';
console.log(v);
v = 'unused';
}
console.log(v);
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint no-useless-assignment: "error" */
function fn1() {
let v = 'used';
doSomething(v);
v = 'used-2';
doSomething(v);
}
function fn2() {
let v = 'used';
if (condition) {
v = 'used-2';
doSomething(v);
return
}
doSomething(v);
}
function fn3() {
let v = 'used';
if (condition) {
doSomething(v);
} else {
v = 'used-2';
doSomething(v);
}
}
function fn4() {
let v = 'used';
for (let i = 0; i < 10; i++) {
doSomething(v);
v = 'used in next iteration';
}
}
```
:::
This rule will not report variables that are never read.
Because it's clearly an unused variable. If you want it reported, please enable the [no-unused-vars](./no-unused-vars) rule.
::: correct
```js
/* eslint no-useless-assignment: "error" */
function fn() {
let v = 'unused';
v = 'unused-2'
doSomething();
}
```
:::
## Options
This rule has no options.
## Known Limitations
This rule does not report certain variable reassignments when they occur inside the `try` block. This is intentional because such assignments may still be observed within the corresponding `catch` block or after the `try-catch` structure, due to potential early exits or error handling logic.
```js
function foo() {
let bar;
try {
bar = 2;
unsafeFn();
return { error: undefined };
} catch {
return { bar }; // `bar` is observed in the catch block
}
}
function unsafeFn() {
throw new Error();
}
function foo() {
let bar;
try {
bar = 2; // This assignment is relevant if unsafeFn() throws an error
unsafeFn();
bar = 4;
} catch {
// Error handling
}
return bar;
}
function unsafeFn() {
throw new Error();
}
```
## When Not To Use It
If you don't want to be notified about values that are never read, you can safely disable this rule.
---
---
title: no-useless-backreference
rule_type: problem
related_rules:
- no-control-regex
- no-empty-character-class
- no-invalid-regexp
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
---
In JavaScript regular expressions, it's syntactically valid to define a backreference to a group that belongs to another alternative part of the pattern, a backreference to a group that appears after the backreference, a backreference to a group that contains that backreference, or a backreference to a group that is inside a negative lookaround. However, by the specification, in any of these cases the backreference always ends up matching only zero-length (the empty string), regardless of the context in which the backreference and the group appear.
Backreferences that always successfully match zero-length and cannot match anything else are useless. They are basically ignored and can be removed without changing the behavior of the regular expression.
```js
const regex = /^(?:(a)|\1b)$/;
regex.test("a"); // true
regex.test("b"); // true!
regex.test("ab"); // false
const equivalentRegex = /^(?:(a)|b)$/;
equivalentRegex.test("a"); // true
equivalentRegex.test("b"); // true
equivalentRegex.test("ab"); // false
```
Useless backreference is a possible error in the code. It usually indicates that the regular expression does not work as intended.
## Rule Details
This rule aims to detect and disallow the following backreferences in regular expression:
* Backreference to a group that is in another alternative, e.g., `/(a)|\1b/`. In such constructed regular expression, the backreference is expected to match what's been captured in, at that point, a non-participating group.
* Backreference to a group that appears later in the pattern, e.g., `/\1(a)/`. The group hasn't captured anything yet, and ECMAScript doesn't support forward references. Inside lookbehinds, which match backward, the opposite applies and this rule disallows backreference to a group that appears before in the same lookbehind, e.g., `/(?<=(a)\1)b/`.
* Backreference to a group from within the same group, e.g., `/(\1)/`. Similar to the previous, the group hasn't captured anything yet, and ECMAScript doesn't support nested references.
* Backreference to a group that is in a negative lookaround, if the backreference isn't in the same negative lookaround, e.g., `/a(?!(b)).\1/`. A negative lookaround (lookahead or lookbehind) succeeds only if its pattern cannot match, meaning that the group has failed.
By the ECMAScript specification, all backreferences listed above are valid, always succeed to match zero-length, and cannot match anything else. Consequently, they don't produce parsing or runtime errors, but also don't affect the behavior of their regular expressions. They are syntactically valid but useless.
This might be surprising to developers coming from other languages where some of these backreferences can be used in a meaningful way.
```js
// in some other languages, this pattern would successfully match "aab"
/^(?:(a)(?=a)|\1b)+$/.test("aab"); // false
```
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-useless-backreference: "error"*/
/^(?:(a)|\1b)$/; // reference to (a) into another alternative
/^(?:(a)|b(?:c|\1))$/; // reference to (a) into another alternative
/^(?:a|b(?:(c)|\1))$/; // reference to (c) into another alternative
/\1(a)/; // forward reference to (a)
RegExp('(a)\\2(b)'); // forward reference to (b)
/(?:a)(b)\2(c)/; // forward reference to (c)
/\k(?a)/; // forward reference to (?a)
/(?<=(a)\1)b/; // backward reference to (a) from within the same lookbehind
/(?(.)b\1)/; // nested reference to (?(.)b\1)
/a(?!(b)).\1/; // reference to (b) into a negative lookahead
/(?a)\k/; // reference to (?a)
/(?<=\1(a))b/; // reference to (a), correctly before the group as they're in the same lookbehind
/(?<=(a))b\1/; // reference to (a), correctly after the group as the backreference isn't in the lookbehind
new RegExp('(.)\\1'); // reference to (.)
/^(?:(a)\1)$/; // reference to (a)
/^((a)\2)$/; // reference to (a)
/a(?(.)b\2)/; // reference to (.)
/a(?!(b|c)\1)./; // reference to (b|c), correct as it's from within the same negative lookahead
/(? foo = "hola"
let bar = `${foo}\!`; // > bar = "hola!"
let baz = /\:/ // same functionality with /:/
```
## Rule Details
This rule flags escapes that can be safely removed without changing behavior.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-useless-escape: "error"*/
"\'";
'\"';
"\#";
"\e";
`\"`;
`\"${foo}\"`;
`\#{foo}`;
/\!/;
/\@/;
/[\[]/;
/[a-z\-]/;
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-useless-escape: "error"*/
"\"";
'\'';
"\x12";
"\u00a9";
"\371";
"xs\u2111";
`\``;
`\${${foo}}`;
`$\{${foo}}`;
/\\/g;
/\t/g;
/\w\$\*\^\./;
/[[]/;
/[\]]/;
/[a-z-]/;
```
:::
## Options
This rule has an object option:
* `allowRegexCharacters` - An array of characters that should be allowed to have unnecessary escapes in regular expressions. This is useful for characters like `-` where escaping can prevent accidental character ranges. For example, in `/[0\-]/`, the escape is technically unnecessary but helps prevent the pattern from becoming a range if another character is added later (e.g., `/[0\-9]/` vs `/[0-9]/`).
### allowRegexCharacters
Examples of **incorrect** code for the `{ "allowRegexCharacters": ["-"] }` option:
::: incorrect
```js
/*eslint no-useless-escape: ["error", { "allowRegexCharacters": ["-"] }]*/
/\!/;
/\@/;
/[a-z\^]/;
```
:::
Examples of **correct** code for the `{ "allowRegexCharacters": ["-"] }` option:
::: correct
```js
/*eslint no-useless-escape: ["error", { "allowRegexCharacters": ["-"] }]*/
/[0\-]/;
/[\-9]/;
/a\-b/;
```
:::
## When Not To Use It
If you don't want to be notified about unnecessary escapes, you can safely disable this rule.
---
---
title: no-useless-rename
rule_type: suggestion
related_rules:
- object-shorthand
---
ES2015 allows for the renaming of references in import and export statements as well as destructuring assignments. This gives programmers a concise syntax for performing these operations while renaming these references:
```js
import { foo as bar } from "baz";
export { foo as bar };
let { foo: bar } = baz;
```
With this syntax, it is possible to rename a reference to the same name. This is a completely redundant operation, as this is the same as not renaming at all. For example, this:
```js
import { foo as foo } from "bar";
export { foo as foo };
let { foo: foo } = bar;
```
is the same as:
```js
import { foo } from "bar";
export { foo };
let { foo } = bar;
```
## Rule Details
This rule disallows the renaming of import, export, and destructured assignments to the same name.
## Options
This rule allows for more fine-grained control with the following options:
* `ignoreImport`: When set to `true`, this rule does not check imports
* `ignoreExport`: When set to `true`, this rule does not check exports
* `ignoreDestructuring`: When set to `true`, this rule does not check destructuring assignments
By default, all options are set to `false`:
```json
"no-useless-rename": ["error", {
"ignoreDestructuring": false,
"ignoreImport": false,
"ignoreExport": false
}]
```
Examples of **incorrect** code for this rule by default:
::: incorrect
```js
/*eslint no-useless-rename: "error"*/
import { foo1 as foo1 } from "bar";
import { "foo2" as foo2 } from "bar";
export { foo1 as foo1 };
export { foo2 as "foo2" };
export { foo3 as foo3 } from "bar";
export { "foo4" as "foo4" } from "bar";
let { foo3: foo3 } = bar;
let { 'foo4': foo4 } = bar;
function foo({ bar: bar }) {}
({ foo: foo }) => {}
```
:::
Examples of **correct** code for this rule by default:
::: correct
```js
/*eslint no-useless-rename: "error"*/
import * as foo1 from "foo";
import { foo2 } from "bar";
import { foo as bar1 } from "baz";
import { "foo" as bar2 } from "baz";
export { foo };
export { foo as bar1 };
export { foo as "bar2" };
export { foo as bar3 } from "foo";
export { "foo" as "bar4" } from "foo";
let { foo } = bar;
let { foo: bar } = baz;
let { [qux]: qux } = bar;
function foo3({ bar }) {}
function foo4({ bar: baz }) {}
({ foo }) => {}
({ foo: bar }) => {}
```
:::
Examples of **correct** code for this rule with `{ ignoreImport: true }`:
::: correct
```js
/*eslint no-useless-rename: ["error", { ignoreImport: true }]*/
import { foo as foo } from "bar";
```
:::
Examples of **correct** code for this rule with `{ ignoreExport: true }`:
::: correct
```js
/*eslint no-useless-rename: ["error", { ignoreExport: true }]*/
const foo = 1;
export { foo as foo };
export { bar as bar } from "bar";
```
:::
Examples of **correct** code for this rule with `{ ignoreDestructuring: true }`:
::: correct
```js
/*eslint no-useless-rename: ["error", { ignoreDestructuring: true }]*/
let { foo: foo } = bar;
function baz({ bar: bar }) {}
({ foo: foo }) => {}
```
:::
## When Not To Use It
You can safely disable this rule if you do not care about redundantly renaming import, export, and destructuring assignments.
## Compatibility
* **JSCS**: [disallowIdenticalDestructuringNames](https://jscs-dev.github.io/rule/disallowIdenticalDestructuringNames)
---
---
title: no-useless-return
rule_type: suggestion
---
A `return;` statement with nothing after it is redundant, and has no effect on the runtime behavior of a function. This can be confusing, so it's better to disallow these redundant statements.
## Rule Details
This rule aims to report redundant `return` statements.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint no-useless-return: "error" */
const foo = function() { return; }
const bar = function() {
doSomething();
return;
}
const baz = function() {
if (condition) {
qux();
return;
} else {
quux();
}
}
const item = function() {
switch (bar) {
case 1:
doSomething();
default:
doSomethingElse();
return;
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint no-useless-return: "error" */
const foo = function() { return 5; }
const bar = function() {
return doSomething();
}
const baz = function() {
if (condition) {
qux();
return;
} else {
quux();
}
qux();
}
const item = function() {
switch (bar) {
case 1:
doSomething();
return;
default:
doSomethingElse();
}
}
const func = function() {
for (const foo of bar) {
return;
}
}
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't care about disallowing redundant return statements, you can turn off this rule.
---
---
title: no-var
rule_type: suggestion
---
ECMAScript 6 allows programmers to create variables with block scope instead of function scope using the `let`
and `const` keywords. Block scope is common in many other programming languages and helps programmers avoid mistakes
such as:
```js
var count = people.length;
var enoughFood = sandwiches.length >= count;
if (enoughFood) {
var count = sandwiches.length; // accidentally overriding the count variable
console.log("We have " + count + " sandwiches for everyone. Plenty for all!");
}
// our count variable is no longer accurate
console.log("We have " + count + " people and " + sandwiches.length + " sandwiches!");
```
## Rule Details
This rule is aimed at discouraging the use of `var` and encouraging the use of `const` or `let` instead.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-var: "error"*/
var x = "y";
var CONFIG = {};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-var: "error"*/
let x = "y";
const CONFIG = {};
```
:::
This rule additionally supports TypeScript type syntax. There are multiple ways to declare global variables in TypeScript. Only using `var` works for all cases. See this [TypeScript playground](https://www.typescriptlang.org/play/?#code/PQgEB4CcFMDNpgOwMbVAGwJYCMC8AiAEwHsBbfUYAPgFgAoew6ZdAQxlAHN1jtX1QAb3qhRGaABdQAGUkAuUAGcJkTIk4ixAN3agAauwXLV6+ptFqJCWK1SgA6mpIB3IebGjHiIyrUa6HgC+9MEMdGDcvPygtqiKivSyEvQGkPReZuHAoM5OxK6ckvS5iC4AdEnFec5lqVWl+WUZYWAlLkpFdG2NSaC4oADkA-XlqX2Dw13VTWrjQ5kRPHzoACoAFpiKXJ2Ry+ubFTtL-PuKtez0uycbZ830i1GrNx3JdFdPB73982-HH2djb6Td6nGaIOaTe7ZRTQdCwbavGFww6I2Gwc5pOhI9F3LIdOEvejYlEQolojGkrHkryU+jQAAeAAdiJApIJAkA) for reference.
Examples of **incorrect** TypeScript code for this rule:
:::incorrect
```ts
/*eslint no-var: "error"*/
declare var x: number
declare namespace ns {
var x: number
}
declare module 'module' {
var x: number
}
```
:::
Examples of **correct** TypeScript code for this rule:
:::correct
```ts
/*eslint no-var: "error"*/
declare global {
declare var x: number
}
```
:::
## Options
This rule has no options.
## When Not To Use It
In addition to non-ES6 environments, existing JavaScript projects that are beginning to introduce ES6 into their
codebase may not want to apply this rule if the cost of migrating from `var` to `let` is too costly.
---
---
title: no-void
rule_type: suggestion
related_rules:
- no-undef-init
- no-undefined
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
- https://oreilly.com/javascript/excerpts/javascript-good-parts/bad-parts.html
---
The `void` operator takes an operand and returns `undefined`: `void expression` will evaluate `expression` and return `undefined`. It can be used to ignore any side effects `expression` may produce:
The common case of using `void` operator is to get a "pure" `undefined` value as prior to ES5 the `undefined` variable was mutable:
```js
// will always return undefined
(function(){
return void 0;
})();
// will return 1 in ES3 and undefined in ES5+
(function(){
undefined = 1;
return undefined;
})();
// will throw TypeError in ES5+
(function(){
'use strict';
undefined = 1;
})();
```
Another common case is to minify code as `void 0` is shorter than `undefined`:
```js
foo = void 0;
foo = undefined;
```
When used with IIFE (immediately-invoked function expression), `void` can be used to force the function keyword to be treated as an expression instead of a declaration:
```js
let foo = 1;
void function(){ foo = 1; }() // will assign foo a value of 1
+function(){ foo = 1; }() // same as above
```
```js
function(){ foo = 1; }() // will throw SyntaxError
```
Some code styles prohibit `void` operator, marking it as non-obvious and hard to read.
## Rule Details
This rule aims to eliminate use of `void` operator.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-void: "error"*/
void foo
void someFunction();
const foo = void bar();
function baz() {
return void 0;
}
```
:::
## Options
This rule has an object option:
* `allowAsStatement` set to `true` allows the `void` operator to be used as a statement (Default `false`).
### allowAsStatement
When `allowAsStatement` is set to true, the rule will not error on cases that the `void` operator is used as a statement, i.e. when it's not used in an expression position, like in a variable assignment or a function return.
Examples of **incorrect** code for `{ "allowAsStatement": true }`:
::: incorrect
```js
/*eslint no-void: ["error", { "allowAsStatement": true }]*/
const foo = void bar();
function baz() {
return void 0;
}
```
:::
Examples of **correct** code for `{ "allowAsStatement": true }`:
::: correct
```js
/*eslint no-void: ["error", { "allowAsStatement": true }]*/
void foo;
void someFunction();
```
:::
## When Not To Use It
If you intentionally use the `void` operator then you can disable this rule.
---
---
title: no-warning-comments
rule_type: suggestion
---
Developers often add comments to code which is not complete or needs review. Most likely you want to fix or review the code, and then remove the comment, before you consider the code to be production ready.
```js
// TODO: do something
// FIXME: this is not a good idea
```
## Rule Details
This rule reports comments that include any of the predefined terms specified in its configuration.
## Options
This rule has an options object literal:
* `"terms"`: optional array of terms to match. Defaults to `["todo", "fixme", "xxx"]`. Terms are matched case-insensitively and as whole words: `fix` would match `FIX` but not `fixing`. Terms can consist of multiple words: `really bad idea`.
* `"location"`: optional string that configures where in your comments to check for matches. Defaults to `"start"`. The start is from the first non-decorative character, ignoring whitespace, new lines and characters specified in `decoration`. The other value is match `anywhere` in comments.
* `"decoration"`: optional array of characters that are ignored at the start of a comment, when location is `"start"`. Defaults to `[]`. Any sequence of whitespace or the characters from this property are ignored. This option is ignored when location is `"anywhere"`.
Example of **incorrect** code for the default `{ "terms": ["todo", "fixme", "xxx"], "location": "start" }` options:
::: incorrect
```js
/*eslint no-warning-comments: "error"*/
/*
FIXME
*/
function callback(err, results) {
if (err) {
console.error(err);
return;
}
// TODO
}
```
:::
Example of **correct** code for the default `{ "terms": ["todo", "fixme", "xxx"], "location": "start" }` options:
::: correct
```js
/*eslint no-warning-comments: "error"*/
function callback(err, results) {
if (err) {
console.error(err);
return;
}
// NOT READY FOR PRIME TIME
// but too bad, it is not a predefined warning term
}
```
:::
### terms and location
Examples of **incorrect** code for the `{ "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }` options:
::: incorrect
```js
/*eslint no-warning-comments: ["error", { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/
// TODO: this
// todo: this too
// Even this: TODO
/*
* The same goes for this TODO comment
* Or a fixme
* as well as any other term
*/
```
:::
Examples of **correct** code for the `{ "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }` options:
::: correct
```js
/*eslint no-warning-comments: ["error", { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/
// This is to do
// even not any other term
// any other terminal
/*
* The same goes for block comments
* with any other interesting term
* or fix me this
*/
```
:::
### Decoration Characters
Examples of **incorrect** code for the `{ "decoration": ["*"] }` options:
::: incorrect
```js
/*eslint no-warning-comments: ["error", { "decoration": ["*"] }]*/
//***** todo decorative asterisks are ignored *****//
/**
* TODO new lines and asterisks are also ignored in block comments.
*/
```
:::
Examples of **incorrect** code for the `{ "decoration": ["/", "*"] }` options:
::: incorrect
```js
/*eslint no-warning-comments: ["error", { "decoration": ["/", "*"] }]*/
////// TODO decorative slashes and whitespace are ignored //////
//***** todo decorative asterisks are also ignored *****//
/**
* TODO new lines are also ignored in block comments.
*/
```
:::
Examples of **correct** code for the `{ "decoration": ["/", "*"] }` options:
::: correct
```js
/*eslint no-warning-comments: ["error", { "decoration": ["/", "*"] }]*/
//!TODO preceded by non-decoration character
/**
*!TODO preceded by non-decoration character in a block comment
*/
```
:::
## When Not To Use It
* If you have a large code base that was not developed with a policy to not use such warning terms, you might get hundreds of warnings / errors which might be counter-productive if you can't fix all of them (e.g. if you don't get the time to do it) as you might overlook other warnings / errors or get used to many of them and don't pay attention on it anymore.
* Same reason as the point above: You shouldn't configure terms that are used very often (e.g. central parts of the native language used in your comments).
---
---
title: no-whitespace-before-property
rule_type: layout
---
JavaScript allows whitespace between objects and their properties. However, inconsistent spacing can make code harder to read and can lead to errors.
```js
foo. bar .baz . quz
```
## Rule Details
This rule disallows whitespace around the dot or before the opening bracket before properties of objects if they are on the same line. This rule allows whitespace when the object and property are on separate lines, as it is common to add newlines to longer chains of properties:
```js
foo
.bar()
.baz()
.qux()
```
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint no-whitespace-before-property: "error"*/
foo [bar]
foo. bar
foo .bar
foo. bar. baz
foo. bar()
.baz()
foo
.bar(). baz()
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint no-whitespace-before-property: "error"*/
foo.bar
foo[bar]
foo[ bar ]
foo.bar.baz
foo
.bar().baz()
foo
.bar()
.baz()
foo.
bar().
baz()
```
:::
## When Not To Use It
Turn this rule off if you do not care about allowing whitespace around the dot or before the opening bracket before properties of objects if they are on the same line.
---
---
title: no-with
rule_type: suggestion
further_reading:
- https://web.archive.org/web/20200717110117/https://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/
---
The `with` statement is potentially problematic because it adds members of an object to the current scope, making it impossible to tell what a variable inside the block actually refers to.
## Rule Details
This rule disallows `with` statements.
If ESLint parses code in strict mode, the parser (instead of this rule) reports the error.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint no-with: "error"*/
with (point) {
r = Math.sqrt(x * x + y * y); // is r a member of point?
}
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint no-with: "error"*/
const r = ({x, y}) => Math.sqrt(x * x + y * y);
```
:::
## Options
This rule has no options.
## When Not To Use It
If you intentionally use `with` statements then you can disable this rule.
---
---
title: no-wrap-func
---
Disallows unnecessary parentheses around function expressions.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [no-extra-parens](no-extra-parens) rule. The `"functions"` option in the new rule is equivalent to the removed rule.
:::
Although it's possible to wrap functions in parentheses, this can be confusing when the code also contains immediately-invoked function expressions (IIFEs) since parentheses are often used to make this distinction. For example:
```js
var foo = (function() {
// IIFE
}());
var bar = (function() {
// not an IIFE
});
```
## Rule Details
This rule will raise a warning when it encounters a function expression wrapped in parentheses with no following invoking parentheses.
Example of **incorrect** code for this rule:
::: incorrect
```js
var a = (function() {/*...*/});
```
:::
Examples of **correct** code for this rule:
::: correct
```js
var a = function() {/*...*/};
(function() {/*...*/})();
```
:::
---
---
title: nonblock-statement-body-position
rule_type: layout
further_reading:
- https://jscs-dev.github.io/rule/requireNewlineBeforeSingleStatementsInIf
---
When writing `if`, `else`, `while`, `do-while`, and `for` statements, the body can be a single statement instead of a block. It can be useful to enforce a consistent location for these single statements.
For example, some developers avoid writing code like this:
```js
if (foo)
bar();
```
If another developer attempts to add `baz();` to the `if` statement, they might mistakenly change the code to
```js
if (foo)
bar();
baz(); // this line is not in the `if` statement!
```
To avoid this issue, one might require all single-line `if` statements to appear directly after the conditional, without a linebreak:
```js
if (foo) bar();
```
## Rule Details
This rule aims to enforce a consistent location for single-line statements.
Note that this rule does not enforce the usage of single-line statements in general. If you would like to disallow single-line statements, use the [`curly`](curly) rule instead.
### Options
This rule accepts a string option:
* `"beside"` (default) disallows a newline before a single-line statement.
* `"below"` requires a newline before a single-line statement.
* `"any"` does not enforce the position of a single-line statement.
Additionally, the rule accepts an optional object option with an `"overrides"` key. This can be used to specify a location for particular statements that override the default. For example:
* `"beside", { "overrides": { "while": "below" } }` requires all single-line statements to appear on the same line as their parent, unless the parent is a `while` statement, in which case the single-line statement must not be on the same line.
* `"below", { "overrides": { "do": "any" } }` disallows all single-line statements from appearing on the same line as their parent, unless the parent is a `do-while` statement, in which case the position of the single-line statement is not enforced.
Examples of **incorrect** code for this rule with the default `"beside"` option:
::: incorrect
```js
/* eslint nonblock-statement-body-position: ["error", "beside"] */
if (foo)
bar();
else
baz();
while (foo)
bar();
for (let i = 1; i < foo; i++)
bar();
do
bar();
while (foo)
```
:::
Examples of **correct** code for this rule with the default `"beside"` option:
::: correct
```js
/* eslint nonblock-statement-body-position: ["error", "beside"] */
if (foo) bar();
else baz();
while (foo) bar();
for (let i = 1; i < foo; i++) bar();
do bar(); while (foo)
if (foo) { // block statements are always allowed with this rule
bar();
} else {
baz();
}
```
:::
Examples of **incorrect** code for this rule with the `"below"` option:
::: incorrect
```js
/* eslint nonblock-statement-body-position: ["error", "below"] */
if (foo) bar();
else baz();
while (foo) bar();
for (let i = 1; i < foo; i++) bar();
do bar(); while (foo)
```
:::
Examples of **correct** code for this rule with the `"below"` option:
::: correct
```js
/* eslint nonblock-statement-body-position: ["error", "below"] */
if (foo)
bar();
else
baz();
while (foo)
bar();
for (let i = 1; i < foo; i++)
bar();
do
bar();
while (foo)
if (foo) {
// Although the second `if` statement is on the same line as the `else`, this is a very common
// pattern, so it's not checked by this rule.
} else if (bar) {
}
```
:::
Examples of **incorrect** code for this rule with the `"beside", { "overrides": { "while": "below" } }` rule:
::: incorrect
```js
/* eslint nonblock-statement-body-position: ["error", "beside", { "overrides": { "while": "below" } }] */
if (foo)
bar();
while (foo) bar();
```
:::
Examples of **correct** code for this rule with the `"beside", { "overrides": { "while": "below" } }` rule:
::: correct
```js
/* eslint nonblock-statement-body-position: ["error", "beside", { "overrides": { "while": "below" } }] */
if (foo) bar();
while (foo)
bar();
```
:::
## When Not To Use It
If you're not concerned about consistent locations of single-line statements, you should not turn on this rule. You can also disable this rule if you're using the `"all"` option for the [`curly`](curly) rule, because this will disallow single-line statements entirely.
---
---
title: object-curly-newline
rule_type: layout
related_rules:
- comma-spacing
- key-spacing
- object-curly-spacing
- object-property-newline
---
A number of style guides require or disallow line breaks inside of object braces and other tokens.
## Rule Details
This rule requires or disallows a line break between `{` and its following token, and between `}` and its preceding token of object literals or destructuring assignments.
## Options
This rule has either a string option:
* `"always"` requires line breaks after opening and before closing braces
* `"never"` disallows line breaks after opening and before closing braces
Or an object option:
* `"multiline": true` requires line breaks if there are line breaks inside properties or between properties. Otherwise, it disallows line breaks.
* `"minProperties"` requires line breaks if the number of properties is at least the given integer. By default, an error will also be reported if an object contains linebreaks and has fewer properties than the given integer. However, the second behavior is disabled if the `consistent` option is set to `true`
* `"consistent": true` (default) requires that either both curly braces, or neither, directly enclose newlines. Note that enabling this option will also change the behavior of the `minProperties` option. (See `minProperties` above for more information)
You can specify different options for object literals, destructuring assignments, and named imports and exports:
```json
{
"object-curly-newline": ["error", {
"ObjectExpression": "always",
"ObjectPattern": { "multiline": true },
"ImportDeclaration": "never",
"ExportDeclaration": { "multiline": true, "minProperties": 3 }
}]
}
```
* `"ObjectExpression"` configuration for object literals
* `"ObjectPattern"` configuration for object patterns of destructuring assignments
* `"ImportDeclaration"` configuration for named imports
* `"ExportDeclaration"` configuration for named exports
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint object-curly-newline: ["error", "always"]*/
let a = {};
let b = {foo: 1};
let c = {foo: 1, bar: 2};
let d = {foo: 1,
bar: 2};
let e = {foo() {
dosomething();
}};
let {} = obj;
let {f} = obj;
let {g, h} = obj;
let {i,
j} = obj;
let {k = function() {
dosomething();
}} = obj;
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint object-curly-newline: ["error", "always"]*/
let a = {
};
let b = {
foo: 1
};
let c = {
foo: 1, bar: 2
};
let d = {
foo: 1,
bar: 2
};
let e = {
foo: function() {
dosomething();
}
};
let {
} = obj;
let {
f
} = obj;
let {
g, h
} = obj;
let {
i,
j
} = obj;
let {
k = function() {
dosomething();
}
} = obj;
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint object-curly-newline: ["error", "never"]*/
let a = {
};
let b = {
foo: 1
};
let c = {
foo: 1, bar: 2
};
let d = {
foo: 1,
bar: 2
};
let e = {
foo: function() {
dosomething();
}
};
let {
} = obj;
let {
f
} = obj;
let {
g, h
} = obj;
let {
i,
j
} = obj;
let {
k = function() {
dosomething();
}
} = obj;
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint object-curly-newline: ["error", "never"]*/
let a = {};
let b = {foo: 1};
let c = {foo: 1, bar: 2};
let d = {foo: 1,
bar: 2};
let e = {foo: function() {
dosomething();
}};
let {} = obj;
let {f} = obj;
let {g, h} = obj;
let {i,
j} = obj;
let {k = function() {
dosomething();
}} = obj;
```
:::
### multiline
Examples of **incorrect** code for this rule with the `{ "multiline": true }` option:
::: incorrect
```js
/*eslint object-curly-newline: ["error", { "multiline": true }]*/
let a = {
};
let b = {
foo: 1
};
let c = {
foo: 1, bar: 2
};
let d = {foo: 1,
bar: 2};
let e = {foo: function() {
dosomething();
}};
let {
} = obj;
let {
f
} = obj;
let {
g, h
} = obj;
let {i,
j} = obj;
let {k = function() {
dosomething();
}} = obj;
```
:::
Examples of **correct** code for this rule with the `{ "multiline": true }` option:
::: correct
```js
/*eslint object-curly-newline: ["error", { "multiline": true }]*/
let a = {};
let b = {foo: 1};
let c = {foo: 1, bar: 2};
let d = {
foo: 1,
bar: 2
};
let e = {
foo: function() {
dosomething();
}
};
let {} = obj;
let {f} = obj;
let {g, h} = obj;
let {
i,
j
} = obj;
let {
k = function() {
dosomething();
}
} = obj;
```
:::
### minProperties
Examples of **incorrect** code for this rule with the `{ "minProperties": 2 }` option:
::: incorrect
```js
/*eslint object-curly-newline: ["error", { "minProperties": 2 }]*/
let a = {
};
let b = {
foo: 1
};
let c = {foo: 1, bar: 2};
let d = {foo: 1,
bar: 2};
let e = {
foo: function() {
dosomething();
}
};
let {
} = obj;
let {
f
} = obj;
let {g, h} = obj;
let {i,
j} = obj;
let {
k = function() {
dosomething();
}
} = obj;
```
:::
Examples of **correct** code for this rule with the `{ "minProperties": 2 }` option:
::: correct
```js
/*eslint object-curly-newline: ["error", { "minProperties": 2 }]*/
let a = {};
let b = {foo: 1};
let c = {
foo: 1, bar: 2
};
let d = {
foo: 1,
bar: 2
};
let e = {foo: function() {
dosomething();
}};
let {} = obj;
let {f} = obj;
let {
g, h
} = obj;
let {
i,
j
} = obj;
let {k = function() {
dosomething();
}} = obj;
```
:::
### consistent
Examples of **incorrect** code for this rule with the default `{ "consistent": true }` option:
::: incorrect
```js
/*eslint object-curly-newline: ["error", { "consistent": true }]*/
let a = {foo: 1
};
let b = {
foo: 1};
let c = {foo: 1, bar: 2
};
let d = {
foo: 1, bar: 2};
let e = {foo: function() {
dosomething();
}
};
let f = {
foo: function() {
dosomething();}};
let {g
} = obj;
let {
h} = obj;
let {i, j
} = obj;
let {k, l
} = obj;
let {
m, n} = obj;
let {
o, p} = obj;
let {q = function() {
dosomething();
}
} = obj;
let {
r = function() {
dosomething();
}} = obj;
```
:::
Examples of **correct** code for this rule with the default `{ "consistent": true }` option:
::: correct
```js
/*eslint object-curly-newline: ["error", { "consistent": true }]*/
let empty1 = {};
let empty2 = {
};
let a = {foo: 1};
let b = {
foo: 1
};
let c = {
foo: 1, bar: 2
};
let d = {
foo: 1,
bar: 2
};
let e = {foo: function() {dosomething();}};
let f = {
foo: function() {
dosomething();
}
};
let {} = obj;
let {
} = obj;
let {g} = obj;
let {
h
} = obj;
let {i, j} = obj;
let {
k, l
} = obj;
let {m,
n} = obj;
let {
o,
p
} = obj;
let {q = function() {dosomething();}} = obj;
let {
r = function() {
dosomething();
}
} = obj;
```
:::
### ObjectExpression and ObjectPattern
Examples of **incorrect** code for this rule with the `{ "ObjectExpression": "always", "ObjectPattern": "never" }` options:
::: incorrect
```js
/*eslint object-curly-newline: ["error", { "ObjectExpression": "always", "ObjectPattern": "never" }]*/
let a = {};
let b = {foo: 1};
let c = {foo: 1, bar: 2};
let d = {foo: 1,
bar: 2};
let e = {foo: function() {
dosomething();
}};
let {
} = obj;
let {
f
} = obj;
let {
g, h
} = obj;
let {
i,
j
} = obj;
let {
k = function() {
dosomething();
}
} = obj;
```
:::
Examples of **correct** code for this rule with the `{ "ObjectExpression": "always", "ObjectPattern": "never" }` options:
::: correct
```js
/*eslint object-curly-newline: ["error", { "ObjectExpression": "always", "ObjectPattern": "never" }]*/
let a = {
};
let b = {
foo: 1
};
let c = {
foo: 1, bar: 2
};
let d = {
foo: 1,
bar: 2
};
let e = {
foo: function() {
dosomething();
}
};
let {} = obj;
let {f} = obj;
let {g, h} = obj;
let {i,
j} = obj;
let {k = function() {
dosomething();
}} = obj;
```
:::
### ImportDeclaration and ExportDeclaration
Examples of **incorrect** code for this rule with the `{ "ImportDeclaration": "always", "ExportDeclaration": "never" }` options:
::: incorrect
```js
/*eslint object-curly-newline: ["error", { "ImportDeclaration": "always", "ExportDeclaration": "never" }]*/
import {foo, bar} from 'foo-bar';
import {foo as f, baz} from 'foo-bar';
import {qux,
foobar} from 'foo-bar';
export {
foo,
bar
};
export {
foo as f,
baz
} from 'foo-bar';
```
:::
Examples of **correct** code for this rule with the `{ "ImportDeclaration": "always", "ExportDeclaration": "never" }` options:
::: correct
```js
/*eslint object-curly-newline: ["error", { "ImportDeclaration": "always", "ExportDeclaration": "never" }]*/
import {
foo,
bar
} from 'foo-bar';
import {
baz, qux
} from 'foo-bar';
import {
foo as f,
foobar
} from 'foo-bar';
export { foo, bar } from 'foo-bar';
export { foo as f, baz } from 'foo-bar';
```
:::
## When Not To Use It
If you don't want to enforce consistent line breaks after opening and before closing braces, then it's safe to disable this rule.
## Compatibility
* **JSCS**: [requirePaddingNewLinesInObjects](https://jscs-dev.github.io/rule/requirePaddingNewLinesInObjects)
* **JSCS**: [disallowPaddingNewLinesInObjects](https://jscs-dev.github.io/rule/disallowPaddingNewLinesInObjects)
---
---
title: object-curly-spacing
rule_type: layout
related_rules:
- array-bracket-spacing
- comma-spacing
- computed-property-spacing
- space-in-parens
---
While formatting preferences are very personal, a number of style guides require
or disallow spaces between curly braces in the following situations:
```js
// simple object literals
var obj = { foo: "bar" };
// nested object literals
var obj = { foo: { zoo: "bar" } };
// destructuring assignment (EcmaScript 6)
var { x, y } = y;
// import/export declarations (EcmaScript 6)
import { foo } from "bar";
export { foo };
```
## Rule Details
This rule enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers.
## Options
This rule has two options, a string option and an object option.
String option:
* `"never"` (default) disallows spacing inside of braces
* `"always"` requires spacing inside of braces (except `{}`)
Object option:
* `"arraysInObjects": true` requires spacing inside of braces of objects beginning and/or ending with an array element (applies when the first option is set to `never`)
* `"arraysInObjects": false` disallows spacing inside of braces of objects beginning and/or ending with an array element (applies when the first option is set to `always`)
* `"objectsInObjects": true` requires spacing inside of braces of objects beginning and/or ending with an object element (applies when the first option is set to `never`)
* `"objectsInObjects": false` disallows spacing inside of braces of objects beginning and/or ending with an object element (applies when the first option is set to `always`)
### never
Examples of **incorrect** code for this rule with the default `"never"` option:
::: incorrect
```js
/*eslint object-curly-spacing: ["error", "never"]*/
var obj = { 'foo': 'bar' };
var obj = {'foo': 'bar' };
var obj = { baz: {'foo': 'qux'}, bar};
var obj = {baz: { 'foo': 'qux'}, bar};
var {x } = y;
import { foo } from 'bar';
```
:::
Examples of **correct** code for this rule with the default `"never"` option:
::: correct
```js
/*eslint object-curly-spacing: ["error", "never"]*/
var obj = {'foo': 'bar'};
var obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'};
var obj = {
'foo': 'bar'
};
var obj = {'foo': 'bar'
};
var obj = {
'foo':'bar'};
var obj = {};
var {x} = y;
import {foo} from 'bar';
```
:::
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint object-curly-spacing: ["error", "always"]*/
var obj = {'foo': 'bar'};
var obj = {'foo': 'bar' };
var obj = { baz: {'foo': 'qux'}, bar};
var obj = {baz: { 'foo': 'qux' }, bar};
var obj = {'foo': 'bar'
};
var obj = {
'foo':'bar'};
var {x} = y;
import {foo } from 'bar';
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint object-curly-spacing: ["error", "always"]*/
var obj = {};
var obj = { 'foo': 'bar' };
var obj = { 'foo': { 'bar': 'baz' }, 'qux': 'quxx' };
var obj = {
'foo': 'bar'
};
var { x } = y;
import { foo } from 'bar';
```
:::
#### arraysInObjects
Examples of additional **correct** code for this rule with the `"never", { "arraysInObjects": true }` options:
::: correct
```js
/*eslint object-curly-spacing: ["error", "never", { "arraysInObjects": true }]*/
var obj = {"foo": [ 1, 2 ] };
var obj = {"foo": [ "baz", "bar" ] };
```
:::
Examples of additional **correct** code for this rule with the `"always", { "arraysInObjects": false }` options:
::: correct
```js
/*eslint object-curly-spacing: ["error", "always", { "arraysInObjects": false }]*/
var obj = { "foo": [ 1, 2 ]};
var obj = { "foo": [ "baz", "bar" ]};
```
:::
#### objectsInObjects
Examples of additional **correct** code for this rule with the `"never", { "objectsInObjects": true }` options:
::: correct
```js
/*eslint object-curly-spacing: ["error", "never", { "objectsInObjects": true }]*/
var obj = {"foo": {"baz": 1, "bar": 2} };
```
:::
Examples of additional **correct** code for this rule with the `"always", { "objectsInObjects": false }` options:
::: correct
```js
/*eslint object-curly-spacing: ["error", "always", { "objectsInObjects": false }]*/
var obj = { "foo": { "baz": 1, "bar": 2 }};
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing between curly braces.
---
---
title: object-property-newline
rule_type: layout
related_rules:
- brace-style
- comma-dangle
- key-spacing
- object-curly-spacing
---
This rule permits you to restrict the locations of property specifications in object literals. You may prohibit any part of any property specification from appearing on the same line as any part of any other property specification. You may make this prohibition absolute, or, by invoking an object option, you may allow an exception, permitting an object literal to have all parts of all of its property specifications on a single line.
## Rule Details
### Motivations
This rule makes it possible to ensure, as some style guides require, that property specifications appear on separate lines for better readability. For example, you can prohibit all of these:
```js
const newObject = {a: 1, b: [2, {a: 3, b: 4}]};
const newObject = {
a: 1, b: [2, {a: 3, b: 4}]
};
const newObject = {
a: 1,
b: [2, {a: 3, b: 4}]
};
const newObject = {
a: 1,
b: [
2,
{a: 3, b: 4}
]
};
```
Instead of those, you can comply with the rule by writing
```js
const newObject = {
a: 1,
b: [2, {
a: 3,
b: 4
}]
};
```
or
```js
const newObject = {
a: 1,
b: [
2,
{
a: 3,
b: 4
}
]
};
```
Another benefit of this rule is specificity of diffs when a property is changed:
```diff
// More specific
var obj = {
foo: "foo",
- bar: "bar",
+ bar: "bazz",
baz: "baz"
};
```
```diff
// Less specific
-var obj = { foo: "foo", bar: "bar", baz: "baz" };
+var obj = { foo: "foo", bar: "bazz", baz: "baz" };
```
### Optional Exception
The rule offers one object option, `allowAllPropertiesOnSameLine` (a deprecated synonym is `allowMultiplePropertiesPerLine`). If you set it to `true`, object literals such as the first two above, with all property specifications on the same line, will be permitted, but one like
```js
const newObject = {
a: 'a.m.', b: 'p.m.',
c: 'daylight saving time'
};
```
will be prohibited, because two properties, but not all properties, appear on the same line.
### Notations
This rule applies equally to all property specifications, regardless of notation, including:
* `a: 1` (ES5)
* `a` (ES2015 shorthand property)
* ``[`prop${a}`]`` (ES2015 computed property name)
Thus, the rule (without the optional exception) prohibits both of these:
```js
const newObject = {
a: 1, [
process.argv[4]
]: '01'
};
const newObject = {
a: 1, [process.argv[4]]: '01'
};
```
(This behavior differs from that of the JSCS rule cited below, which does not treat the leading `[` of a computed property name as part of that property specification. The JSCS rule prohibits the second of these formats but permits the first.)
### Multiline Properties
The rule prohibits the colocation on any line of at least 1 character of one property specification with at least 1 character of any other property specification. For example, the rule prohibits
```js
const newObject = {a: [
'Officiële website van de Europese Unie',
'Официален уебсайт на Европейския съюз'
], b: 2};
```
because 1 character of the specification of `a` (i.e. the trailing `]` of its value) is on the same line as the specification of `b`.
The optional exception does not excuse this case, because the entire collection of property specifications spans 4 lines, not 1.
### Inter-property Delimiters
The comma and any whitespace that delimit property specifications are not considered parts of them. Therefore, the rule permits both of these formats:
```js
const newFunction = multiplier => ({
a: 2 * multiplier,
b: 4 * multiplier,
c: 8 * multiplier
});
const newFunction = multiplier => ({
a: 2 * multiplier
, b: 4 * multiplier
, c: 8 * multiplier
});
```
(This behavior differs from that of the JSCS rule cited below, which permits the first but prohibits the second format.)
### --fix
If this rule is invoked with the command-line `--fix` option, object literals that violate the rule are generally modified to comply with it. The modification in each case is to move a property specification to the next line whenever there is part or all of a previous property specification on the same line. For example,
```js
const newObject = {
a: 'a.m.', b: 'p.m.',
c: 'daylight saving time'
};
```
is converted to
```js
const newObject = {
a: 'a.m.',
b: 'p.m.',
c: 'daylight saving time'
};
```
The modification does not depend on whether the object option is set to `true`. In other words, ESLint never collects all the property specifications onto a single line, even when the object option would permit that.
ESLint does not correct a violation of this rule if a comment immediately precedes the second or subsequent property specification on a line, since ESLint cannot determine which line to put the comment onto.
As illustrated above, the `--fix` option, applied to this rule, does not comply with other rules, such as `indent`, but, if those other rules are also in effect, the option applies them, too.
Examples of **incorrect** code for this rule, with no object option or with `allowAllPropertiesOnSameLine` set to `false`:
::: incorrect
```js
/*eslint object-property-newline: "error"*/
const obj0 = { foo: "foo", bar: "bar", baz: "baz" };
const obj1 = {
foo: "foo", bar: "bar", baz: "baz"
};
const obj2 = {
foo: "foo", bar: "bar",
baz: "baz"
};
const obj3 = {
[process.argv[3] ? "foo" : "bar"]: 0, baz: [
1,
2,
4,
8
]
};
const a = "antidisestablishmentarianistically";
const b = "yugoslavyalılaştırabildiklerimizdenmişsiniz";
const obj4 = {a, b};
const domain = process.argv[4];
const obj5 = {
foo: "foo", [
domain.includes(":") ? "complexdomain" : "simpledomain"
]: true};
```
:::
Examples of **correct** code for this rule, with no object option or with `allowAllPropertiesOnSameLine` set to `false`:
::: correct
```js
/*eslint object-property-newline: "error"*/
const obj1 = {
foo: "foo",
bar: "bar",
baz: "baz"
};
const obj2 = {
foo: "foo"
, bar: "bar"
, baz: "baz"
};
const user = process.argv[2];
const obj3 = {
user,
[process.argv[3] ? "foo" : "bar"]: 0,
baz: [
1,
2,
4,
8
]
};
```
:::
Examples of additional **correct** code for this rule with the `{ "allowAllPropertiesOnSameLine": true }` option:
::: correct
```js
/*eslint object-property-newline: ["error", { "allowAllPropertiesOnSameLine": true }]*/
const obj = { foo: "foo", bar: "bar", baz: "baz" };
const obj2 = {
foo: "foo", bar: "bar", baz: "baz"
};
const user = process.argv[2];
const obj3 = {
user, [process.argv[3] ? "foo" : "bar"]: 0, baz: [1, 2, 4, 8]
};
```
:::
## When Not To Use It
You can turn this rule off if you want to decide, case-by-case, whether to place property specifications on separate lines.
## Compatibility
* **JSCS**: This rule provides partial compatibility with [requireObjectKeysOnNewLine](https://jscs-dev.github.io/rule/requireObjectKeysOnNewLine).
---
---
title: object-shorthand
rule_type: suggestion
related_rules:
- no-useless-rename
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
---
ECMAScript 6 provides a concise form for defining object literal methods and properties. This
syntax can make defining complex object literals much cleaner.
Here are a few common examples using the ES5 syntax:
```js
// properties
const foo = {
x: x,
y: y,
z: z,
};
// methods
const bar = {
a: function() {},
b: function() {}
};
```
Now here are ES6 equivalents:
```js
// properties
const foo = {x, y, z};
// methods
const bar = {
a() {},
b() {}
};
```
## Rule Details
This rule enforces the use of the shorthand syntax. This applies
to all methods (including generators) defined in object literals and any
properties defined where the key name matches name of the assigned variable.
Each of the following properties would warn:
```js
/*eslint object-shorthand: "error"*/
const foo = {
w: function() {},
x: function *() {},
[y]: function() {},
z: z
};
```
In that case the expected syntax would have been:
```js
/*eslint object-shorthand: "error"*/
const foo = {
w() {},
*x() {},
[y]() {},
z
};
```
This rule does not flag arrow functions inside of object literals.
The following will *not* warn:
```js
/*eslint object-shorthand: "error"*/
const foo = {
x: (y) => y
};
```
## Options
The rule takes an option which specifies when it should be applied. It can be set to one of the following values:
* `"always"` (default) expects that the shorthand will be used whenever possible.
* `"methods"` ensures the method shorthand is used (also applies to generators).
* `"properties"` ensures the property shorthand is used (where the key and variable name match).
* `"never"` ensures that no property or method shorthand is used in any object literal.
* `"consistent"` ensures that either all shorthand or all long-form will be used in an object literal.
* `"consistent-as-needed"` ensures that either all shorthand or all long-form will be used in an object literal, but ensures all shorthand whenever possible.
You can set the option in configuration like this:
```json
{
"object-shorthand": ["error", "always"]
}
```
Additionally, the rule takes an optional object configuration:
* `"avoidQuotes": true` indicates that long-form syntax is preferred whenever the object key is a string literal (default: `false`). Note that this option can only be enabled when the string option is set to `"always"`, `"methods"`, or `"properties"`.
* `"ignoreConstructors": true` can be used to prevent the rule from reporting errors for constructor functions. (By default, the rule treats constructors the same way as other functions.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`.
* `"methodsIgnorePattern"` (`string`) for methods whose names match this regex pattern, the method shorthand will not be enforced. Note that this option can only be used when the string option is set to `"always"` or `"methods"`.
* `"avoidExplicitReturnArrows": true` indicates that methods are preferred over explicit-return arrow functions for function properties. (By default, the rule allows either of these.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`.
### avoidQuotes
```json
{
"object-shorthand": ["error", "always", { "avoidQuotes": true }]
}
```
Example of **incorrect** code for this rule with the `"always", { "avoidQuotes": true }` option:
::: incorrect
```js
/*eslint object-shorthand: ["error", "always", { "avoidQuotes": true }]*/
const foo = {
"bar-baz"() {}
};
```
:::
Example of **correct** code for this rule with the `"always", { "avoidQuotes": true }` option:
::: correct
```js
/*eslint object-shorthand: ["error", "always", { "avoidQuotes": true }]*/
const foo = {
"bar-baz": function() {},
"qux": qux
};
```
:::
### ignoreConstructors
```json
{
"object-shorthand": ["error", "always", { "ignoreConstructors": true }]
}
```
Example of **correct** code for this rule with the `"always", { "ignoreConstructors": true }` option:
::: correct
```js
/*eslint object-shorthand: ["error", "always", { "ignoreConstructors": true }]*/
const foo = {
ConstructorFunction: function() {}
};
```
:::
### methodsIgnorePattern
Example of **correct** code for this rule with the `"always", { "methodsIgnorePattern": "^bar$" }` option:
::: correct
```js
/*eslint object-shorthand: ["error", "always", { "methodsIgnorePattern": "^bar$" }]*/
const foo = {
bar: function() {}
};
```
:::
### avoidExplicitReturnArrows
```json
{
"object-shorthand": ["error", "always", { "avoidExplicitReturnArrows": true }]
}
```
Example of **incorrect** code for this rule with the `"always", { "avoidExplicitReturnArrows": true }` option:
::: incorrect
```js
/*eslint object-shorthand: ["error", "always", { "avoidExplicitReturnArrows": true }]*/
const foo = {
foo: (bar, baz) => {
return bar + baz;
},
qux: (foobar) => {
return foobar * 2;
}
};
```
:::
Example of **correct** code for this rule with the `"always", { "avoidExplicitReturnArrows": true }` option:
::: correct
```js
/*eslint object-shorthand: ["error", "always", { "avoidExplicitReturnArrows": true }]*/
const foo = {
foo(bar, baz) {
return bar + baz;
},
qux: foobar => foobar * 2
};
```
:::
Example of **incorrect** code for this rule with the `"consistent"` option:
::: incorrect
```js
/*eslint object-shorthand: [2, "consistent"]*/
const foo = {
a,
b: "foo",
};
```
:::
Examples of **correct** code for this rule with the `"consistent"` option:
::: correct
```js
/*eslint object-shorthand: [2, "consistent"]*/
const foo = {
a: a,
b: "foo"
};
const bar = {
a,
b,
};
```
:::
Example of **incorrect** code with the `"consistent-as-needed"` option, which is very similar to `"consistent"`:
::: incorrect
```js
/*eslint object-shorthand: [2, "consistent-as-needed"]*/
const foo = {
a: a,
b: b,
};
```
:::
## When Not To Use It
Anyone not yet in an ES6 environment would not want to apply this rule. Others may find the terseness of the shorthand
syntax harder to read and may not want to encourage it with this rule.
---
---
title: one-var-declaration-per-line
rule_type: suggestion
related_rules:
- one-var
---
Some developers declare multiple var statements on the same line:
```js
var foo, bar, baz;
```
Others prefer to declare one var per line.
```js
var foo,
bar,
baz;
```
Keeping to one of these styles across a project's codebase can help with maintaining code consistency.
## Rule Details
This rule enforces a consistent newlines around variable declarations. This rule ignores variable declarations inside `for` loop conditionals.
## Options
This rule has a single string option:
* `"initializations"` (default) enforces a newline around variable initializations
* `"always"` enforces a newline around variable declarations
### initializations
Examples of **incorrect** code for this rule with the default `"initializations"` option:
::: incorrect
```js
/*eslint one-var-declaration-per-line: ["error", "initializations"]*/
var a, b, c = 0;
let d,
e = 0, f;
```
:::
Examples of **correct** code for this rule with the default `"initializations"` option:
::: correct
```js
/*eslint one-var-declaration-per-line: ["error", "initializations"]*/
var a, b;
let c,
d;
let e,
f = 0;
```
:::
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint one-var-declaration-per-line: ["error", "always"]*/
var a, b;
let c, d = 0;
const e = 0, f = 0;
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint one-var-declaration-per-line: ["error", "always"]*/
var a,
b;
let c,
d = 0;
```
:::
---
---
title: one-var
rule_type: suggestion
---
Variables can be declared at any point in JavaScript code using `var`, `let`, `const`, `using`, or `await using`. There are many styles and preferences related to the declaration of variables, and one of those is deciding on how many variable declarations should be allowed in a single function.
There are two schools of thought in this regard:
1. There should be just one variable declaration for all variables in the function. That declaration typically appears at the top of the function.
1. You should use one variable declaration for each variable you want to define.
For instance:
```js
// one variable declaration per function
function foo() {
var bar, baz;
}
// multiple variable declarations per function
function foo() {
var bar;
var baz;
}
```
The single-declaration school of thought is based in pre-ECMAScript 6 behaviors, where there was no such thing as block scope, only function scope. Since all `var` statements are hoisted to the top of the function anyway, some believe that declaring all variables in a single declaration at the top of the function removes confusion around scoping rules.
## Rule Details
This rule enforces variables to be declared either together or separately per function ( for `var`) or block (for `let`, `const`, `using`, and `await using`) scope.
## Options
This rule has one option, which can be a string option or an object option.
String option:
* `"always"` (default) requires one variable declaration per scope
* `"never"` requires multiple variable declarations per scope
* `"consecutive"` allows multiple variable declarations per scope but requires consecutive variable declarations to be combined into a single declaration
Object option:
* `"var": "always"` requires one `var` declaration per function
* `"var": "never"` requires multiple `var` declarations per function
* `"var": "consecutive"` requires consecutive `var` declarations to be a single declaration
* `"let": "always"` requires one `let` declaration per block
* `"let": "never"` requires multiple `let` declarations per block
* `"let": "consecutive"` requires consecutive `let` declarations to be a single declaration
* `"const": "always"` requires one `const` declaration per block
* `"const": "never"` requires multiple `const` declarations per block
* `"const": "consecutive"` requires consecutive `const` declarations to be a single declaration
* `"using": "always"` requires one `using` declaration per block
* `"using": "never"` requires multiple `using` declarations per block
* `"using": "consecutive"` requires consecutive `using` declarations to be a single declaration
* `"awaitUsing": "always"` requires one `await using` declaration per block
* `"awaitUsing": "never"` requires multiple `await using` declarations per block
* `"awaitUsing": "consecutive"` requires consecutive `await using` declarations to be a single declaration
* `"separateRequires": true` enforces `requires` to be separate from declarations
Alternate object option:
* `"initialized": "always"` requires one variable declaration for initialized variables per scope
* `"initialized": "never"` requires multiple variable declarations for initialized variables per scope
* `"initialized": "consecutive"` requires consecutive variable declarations for initialized variables to be a single declaration
* `"uninitialized": "always"` requires one variable declaration for uninitialized variables per scope
* `"uninitialized": "never"` requires multiple variable declarations for uninitialized variables per scope
* `"uninitialized": "consecutive"` requires consecutive variable declarations for uninitialized variables to be a single declaration
### always
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint one-var: ["error", "always"]*/
function foo1() {
var bar;
var baz;
let qux;
let norf;
}
function foo2(){
const bar = false;
const baz = true;
let qux;
let norf;
}
function foo3() {
var bar;
if (baz) {
var qux = true;
}
}
class C {
static {
var foo;
var bar;
}
static {
var foo;
if (bar) {
var baz = true;
}
}
static {
let foo;
let bar;
}
}
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint one-var: ["error", "always"]*/
function foo1() {
var bar,
baz;
let qux,
norf;
}
function foo2(){
const bar = true,
baz = false;
let qux,
norf;
}
function foo3() {
var bar,
qux;
if (baz) {
qux = true;
}
}
function foo4(){
let bar;
if (baz) {
let qux;
}
}
class C {
static {
var foo, bar;
}
static {
var foo, baz;
if (bar) {
baz = true;
}
}
static {
let foo, bar;
}
static {
let foo;
if (bar) {
let baz;
}
}
}
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint one-var: ["error", "never"]*/
function foo1() {
var bar,
baz;
const qux = true,
foobar = false;
}
function foo2() {
var bar,
qux;
if (baz) {
qux = true;
}
}
function foo3(){
let bar = true,
baz = false;
}
class C {
static {
var foo, bar;
let baz, qux;
}
}
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint one-var: ["error", "never"]*/
function foo1() {
var bar;
var baz;
}
function foo2() {
var bar;
if (baz) {
var qux = true;
}
}
function foo3() {
let bar;
if (baz) {
let qux = true;
}
}
class C {
static {
var foo;
var bar;
let baz;
let qux;
}
}
// declarations with multiple variables are allowed in for-loop initializers
for (var i = 0, len = arr.length; i < len; i++) {
doSomething(arr[i]);
}
```
:::
### consecutive
Examples of **incorrect** code for this rule with the `"consecutive"` option:
::: incorrect
```js
/*eslint one-var: ["error", "consecutive"]*/
function foo1() {
var bar;
var baz;
}
function foo2(){
var bar = 1;
var baz = 2;
qux();
var qux = 3;
var quux;
}
class C {
static {
var foo;
var bar;
let baz;
let qux;
}
}
```
:::
Examples of **correct** code for this rule with the `"consecutive"` option:
::: correct
```js
/*eslint one-var: ["error", "consecutive"]*/
function foo1() {
var bar,
baz;
}
function foo2(){
var bar = 1,
baz = 2;
qux();
var qux = 3,
quux;
}
class C {
static {
var foo, bar;
let baz, qux;
doSomething();
let quux;
var quuux;
}
}
```
:::
### var, let, const, using, and awaitUsing
Examples of **incorrect** code for this rule with the `{ var: "always", let: "never", const: "never", using: "never", awaitUsing: "never" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { var: "always", let: "never", const: "never", using: "never", awaitUsing: "never" }]*/
function foo1() {
var bar;
var baz;
let qux,
norf;
}
function foo2() {
const bar = 1,
baz = 2;
let qux,
norf;
}
async function foo3() {
using bar = 1,
baz = 2;
await using qux = 3,
norf = 4;
}
```
:::
Examples of **correct** code for this rule with the `{ var: "always", let: "never", const: "never", using: "never", awaitUsing: "never" }` option:
::: correct
```js
/*eslint one-var: ["error", { var: "always", let: "never", const: "never", using: "never", awaitUsing: "never" }]*/
function foo1() {
var bar,
baz;
let qux;
let norf;
}
function foo2() {
const bar = 1;
const baz = 2;
let qux;
let norf;
}
async function foo3() {
using bar = 1;
using baz = 2;
await using qux = 3;
await using norf = 4;
}
```
:::
Examples of **incorrect** code for this rule with the `{ var: "never" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { var: "never" }]*/
function foo() {
var bar,
baz;
}
```
:::
Examples of **correct** code for this rule with the `{ var: "never" }` option:
::: correct
```js
/*eslint one-var: ["error", { var: "never" }]*/
async function foo() {
var bar;
var baz;
// `const`, `let`, `using` and `await using` declarations are ignored if they are not specified
const foobar = 1;
const foobaz = 2;
const barfoo = 1, bazfoo = 2;
let qux;
let norf;
let fooqux, foonorf;
using foobarfoo = 1;
using foobazfoo = 2;
using bazbarfoo = 1, bazfoobar = 2;
await using foobarbaz = 1;
await using foobazqux = 2;
await using bazbarqux = 1, bazfooqux = 2;
}
```
:::
Examples of **incorrect** code for this rule with the `{ separateRequires: true }` option:
::: incorrect
```js
/*eslint one-var: ["error", { separateRequires: true, var: "always" }]*/
var foo = require("foo"),
bar = "bar";
```
:::
Examples of **correct** code for this rule with the `{ separateRequires: true }` option:
::: correct
```js
/*eslint one-var: ["error", { separateRequires: true, var: "always" }]*/
var foo = require("foo");
var bar = "bar";
```
:::
::: correct
```js
/*eslint one-var: ["error", { separateRequires: true, var: "always" }]*/
var foo = require("foo"),
bar = require("bar");
```
:::
Examples of **incorrect** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive", using: "consecutive", awaitUsing: "consecutive" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive", using: "consecutive", awaitUsing: "consecutive" }]*/
function foo1() {
let a,
b;
let c;
var d,
e;
}
function foo2() {
const a = 1,
b = 2;
const c = 3;
var d,
e;
}
function foo3() {
using a = 1,
b = 2;
using c = 3;
var d,
e;
}
async function foo4() {
await using a = 1,
b = 2;
await using c = 3;
var d,
e;
}
```
:::
Examples of **correct** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive", using: "consecutive", awaitUsing: "consecutive" }` option:
::: correct
```js
/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive", using: "consecutive", awaitUsing: "consecutive" }]*/
function foo1() {
let a,
b;
var d;
var e;
let f;
}
function foo2() {
const a = 1,
b = 2;
var c;
var d;
const e = 3;
}
function foo3() {
using a = 1,
b = 2;
var c;
var d;
using e = 3;
}
async function foo4() {
await using a = 1,
b = 2;
var c;
var d;
await using e = 3;
}
```
:::
Examples of **incorrect** code for this rule with the `{ var: "consecutive" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { var: "consecutive" }]*/
function foo() {
var a;
var b;
}
```
:::
Examples of **correct** code for this rule with the `{ var: "consecutive" }` option:
::: correct
```js
/*eslint one-var: ["error", { var: "consecutive" }]*/
async function foo() {
var a,
b;
// `const`, `let`, `using`, and `await using` declarations are ignored if they are not specified
const c = 1;
const d = 2;
let e;
let f;
using g = 3;
using h = 4;
await using i = 5;
await using j = 6;
}
```
:::
### initialized and uninitialized
Examples of **incorrect** code for this rule with the `{ "initialized": "always", "uninitialized": "never" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/
function foo() {
var a, b, c;
var foo = true;
var bar = false;
}
```
:::
Examples of **correct** code for this rule with the `{ "initialized": "always", "uninitialized": "never" }` option:
::: correct
```js
/*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/
function foo() {
var a;
var b;
var c;
var foo = true,
bar = false;
}
for (let z of foo) {
doSomething(z);
}
let z;
for (z of foo) {
doSomething(z);
}
```
:::
Examples of **incorrect** code for this rule with the `{ "initialized": "never" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { "initialized": "never" }]*/
function foo() {
var foo = true,
bar = false;
}
```
:::
Examples of **correct** code for this rule with the `{ "initialized": "never" }` option:
::: correct
```js
/*eslint one-var: ["error", { "initialized": "never" }]*/
function foo() {
var foo = true;
var bar = false;
var a, b, c; // Uninitialized variables are ignored
}
```
:::
Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/
function foo() {
var a = 1;
var b = 2;
var c,
d;
var e = 3;
var f = 4;
}
```
:::
Examples of **correct** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option:
::: correct
```js
/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/
function foo() {
var a = 1,
b = 2;
var c;
var d;
var e = 3,
f = 4;
}
```
:::
Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive" }` option:
::: incorrect
```js
/*eslint one-var: ["error", { "initialized": "consecutive" }]*/
function foo() {
var a = 1;
var b = 2;
foo();
var c = 3;
var d = 4;
}
```
:::
Examples of **correct** code for this rule with the `{ "initialized": "consecutive" }` option:
::: correct
```js
/*eslint one-var: ["error", { "initialized": "consecutive" }]*/
function foo() {
var a = 1,
b = 2;
foo();
var c = 3,
d = 4;
}
```
:::
## Compatibility
* **JSHint**: This rule maps to the `onevar` JSHint rule, but allows `let` and `const` to be configured separately.
* **JSCS**: This rule roughly maps to [disallowMultipleVarDecl](https://jscs-dev.github.io/rule/disallowMultipleVarDecl).
* **JSCS**: This rule option `separateRequires` roughly maps to [requireMultipleVarDecl](https://jscs-dev.github.io/rule/requireMultipleVarDecl).
---
---
title: operator-assignment
rule_type: suggestion
---
JavaScript provides shorthand operators that combine variable assignment and some simple mathematical operations. For example, `x = x + 4` can be shortened to `x += 4`. The supported shorthand forms are as follows:
```text
Shorthand | Separate
-----------|------------
x += y | x = x + y
x -= y | x = x - y
x *= y | x = x * y
x /= y | x = x / y
x %= y | x = x % y
x **= y | x = x ** y
x <<= y | x = x << y
x >>= y | x = x >> y
x >>>= y | x = x >>> y
x &= y | x = x & y
x ^= y | x = x ^ y
x |= y | x = x | y
```
## Rule Details
This rule requires or disallows assignment operator shorthand where possible.
The rule applies to the operators listed in the above table. It does not report the logical assignment operators `&&=`, `||=`, and `??=` because their short-circuiting behavior is different from the other assignment operators.
## Options
This rule has a single string option:
* `"always"` (default) requires assignment operator shorthand where possible
* `"never"` disallows assignment operator shorthand
### always
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint operator-assignment: ["error", "always"]*/
x = x + y;
x = y * x;
x[0] = x[0] / y;
x.y = x.y << z;
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint operator-assignment: ["error", "always"]*/
x = y;
x += y;
x = y * z;
x = (x * y) * z;
x[0] /= y;
x[foo()] = x[foo()] % 2;
x = y + x; // `+` is not always commutative (e.g. x = "abc")
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint operator-assignment: ["error", "never"]*/
x *= y;
x ^= (y + z) / foo();
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint operator-assignment: ["error", "never"]*/
x = x + y;
x.y = x.y / a.b;
```
:::
## When Not To Use It
Use of operator assignment shorthand is a stylistic choice. Leaving this rule turned off would allow developers to choose which style is more readable on a case-by-case basis.
---
---
title: operator-linebreak
rule_type: layout
related_rules:
- comma-style
---
When a statement is too long to fit on a single line, line breaks are generally inserted next to the operators separating expressions. The first style coming to mind would be to place the operator at the end of the line, following the English punctuation rules.
```js
var fullHeight = borderTop +
innerHeight +
borderBottom;
```
Some developers find that placing operators at the beginning of the line makes the code more readable.
```js
var fullHeight = borderTop
+ innerHeight
+ borderBottom;
```
## Rule Details
This rule enforces a consistent linebreak style for operators.
## Options
This rule has two options, a string option and an object option.
String option:
* `"after"` requires linebreaks to be placed after the operator
* `"before"` requires linebreaks to be placed before the operator
* `"none"` disallows linebreaks on either side of the operator
Object option:
* `"overrides"` overrides the global setting for specified operators
The default configuration is `"after", { "overrides": { "?": "before", ":": "before" } }`
### after
Examples of **incorrect** code for this rule with the `"after"` option:
::: incorrect
```js
/*eslint operator-linebreak: ["error", "after"]*/
foo = 1
+
2;
foo = 1
+ 2;
foo
= 5;
if (someCondition
|| otherCondition) {
}
answer = everything
? 42
: foo;
class Foo {
a
= 1;
[b]
= 2;
[c
]
= 3;
}
```
:::
Examples of **correct** code for this rule with the `"after"` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "after"]*/
foo = 1 + 2;
foo = 1 +
2;
foo =
5;
if (someCondition ||
otherCondition) {
}
answer = everything ?
42 :
foo;
class Foo {
a =
1;
[b] =
2;
[c
] =
3;
d = 4;
}
```
:::
### before
Examples of **incorrect** code for this rule with the `"before"` option:
::: incorrect
```js
/*eslint operator-linebreak: ["error", "before"]*/
foo = 1 +
2;
foo =
5;
if (someCondition ||
otherCondition) {
}
answer = everything ?
42 :
foo;
class Foo {
a =
1;
[b] =
2;
[c
] =
3;
}
```
:::
Examples of **correct** code for this rule with the `"before"` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "before"]*/
foo = 1 + 2;
foo = 1
+ 2;
foo
= 5;
if (someCondition
|| otherCondition) {
}
answer = everything
? 42
: foo;
class Foo {
a
= 1;
[b]
= 2;
[c
]
= 3;
d = 4;
}
```
:::
### none
Examples of **incorrect** code for this rule with the `"none"` option:
::: incorrect
```js
/*eslint operator-linebreak: ["error", "none"]*/
foo = 1 +
2;
foo = 1
+ 2;
if (someCondition ||
otherCondition) {
}
if (someCondition
|| otherCondition) {
}
answer = everything
? 42
: foo;
answer = everything ?
42 :
foo;
class Foo {
a =
1;
[b] =
2;
[c
] =
3;
d
= 4;
[e]
= 5;
[f
]
= 6;
}
```
:::
Examples of **correct** code for this rule with the `"none"` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "none"]*/
foo = 1 + 2;
foo = 5;
if (someCondition || otherCondition) {
}
answer = everything ? 42 : foo;
class Foo {
a = 1;
[b] = 2;
[c
] = 3;
d = 4;
[e] = 5;
[f
] = 6;
}
```
:::
### overrides
Examples of additional **incorrect** code for this rule with the `{ "overrides": { "+=": "before" } }` option:
::: incorrect
```js
/*eslint operator-linebreak: ["error", "after", { "overrides": { "+=": "before" } }]*/
var thing = 'thing';
thing +=
's';
```
:::
Examples of additional **correct** code for this rule with the `{ "overrides": { "+=": "before" } }` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "after", { "overrides": { "+=": "before" } }]*/
var thing = 'thing';
thing
+= 's';
```
:::
Examples of additional **correct** code for this rule with the `{ "overrides": { "?": "ignore", ":": "ignore" } }` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "ignore", ":": "ignore" } }]*/
answer = everything ?
42
: foo;
answer = everything
?
42
:
foo;
```
:::
Examples of **incorrect** code for this rule with the default `"after", { "overrides": { "?": "before", ":": "before" } }` option:
::: incorrect
```js
/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "before", ":": "before" } }]*/
foo = 1
+
2;
foo = 1
+ 2;
foo
= 5;
if (someCondition
|| otherCondition) {
}
answer = everything ?
42 :
foo;
```
:::
Examples of **correct** code for this rule with the default `"after", { "overrides": { "?": "before", ":": "before" } }` option:
::: correct
```js
/*eslint operator-linebreak: ["error", "after", { "overrides": { "?": "before", ":": "before" } }]*/
foo = 1 + 2;
foo = 1 +
2;
foo =
5;
if (someCondition ||
otherCondition) {
}
answer = everything
? 42
: foo;
```
:::
## When Not To Use It
If your project will not be using a common operator line break style, turn this rule off.
---
---
title: padded-blocks
rule_type: layout
related_rules:
- lines-between-class-members
- padding-line-between-statements
---
Some style guides require block statements to start and end with blank lines. The goal is
to improve readability by visually separating the block content and the surrounding code.
```js
if (a) {
b();
}
```
Since it's good to have a consistent code style, you should either always write
padded blocks or never do it.
## Rule Details
This rule enforces consistent empty line padding within blocks.
## Options
This rule has two options, the first one can be a string option or an object option.
The second one is an object option, it can allow exceptions.
### First option
String option:
* `"always"` (default) requires empty lines at the beginning and ending of block statements, function bodies, class static blocks, classes, and `switch` statements.
* `"never"` disallows empty lines at the beginning and ending of block statements, function bodies, class static blocks, classes, and `switch` statements.
Object option:
* `"blocks"` require or disallow padding within block statements, function bodies, and class static blocks
* `"classes"` require or disallow padding within classes
* `"switches"` require or disallow padding within `switch` statements
### Second option
* `"allowSingleLineBlocks": true` allows single-line blocks
### always
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", "always"]*/
if (a) {
b();
}
if (a) { b(); }
if (a)
{
b();
}
if (a) {
b();
}
if (a) {
// comment
b();
}
class C {
static {
a();
}
}
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint padded-blocks: ["error", "always"]*/
if (a) {
b();
}
if (a)
{
b();
}
if (a) {
// comment
b();
}
class C {
static {
a();
}
}
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", "never"]*/
if (a) {
b();
}
if (a)
{
b();
}
if (a) {
b();
}
if (a) {
b();
}
class C {
static {
a();
}
}
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint padded-blocks: ["error", "never"]*/
if (a) {
b();
}
if (a)
{
b();
}
class C {
static {
a();
}
}
```
:::
### blocks
Examples of **incorrect** code for this rule with the `{ "blocks": "always" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "blocks": "always" }]*/
if (a) {
b();
}
if (a) { b(); }
if (a)
{
b();
}
if (a) {
b();
}
if (a) {
b();
}
if (a) {
// comment
b();
}
class C {
static {
a();
}
}
```
:::
Examples of **correct** code for this rule with the `{ "blocks": "always" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "blocks": "always" }]*/
if (a) {
b();
}
if (a)
{
b();
}
if (a) {
// comment
b();
}
class C {
static {
a();
}
}
class D {
static {
a();
}
}
```
:::
Examples of **incorrect** code for this rule with the `{ "blocks": "never" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "blocks": "never" }]*/
if (a) {
b();
}
if (a)
{
b();
}
if (a) {
b();
}
if (a) {
b();
}
class C {
static {
a();
}
}
```
:::
Examples of **correct** code for this rule with the `{ "blocks": "never" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "blocks": "never" }]*/
if (a) {
b();
}
if (a)
{
b();
}
class C {
static {
a();
}
}
class D {
static {
a();
}
}
```
:::
### classes
Examples of **incorrect** code for this rule with the `{ "classes": "always" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "classes": "always" }]*/
class A {
constructor(){
}
}
```
:::
Examples of **correct** code for this rule with the `{ "classes": "always" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "classes": "always" }]*/
class A {
constructor(){
}
}
```
:::
Examples of **incorrect** code for this rule with the `{ "classes": "never" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "classes": "never" }]*/
class A {
constructor(){
}
}
```
:::
Examples of **correct** code for this rule with the `{ "classes": "never" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "classes": "never" }]*/
class A {
constructor(){
}
}
```
:::
### switches
Examples of **incorrect** code for this rule with the `{ "switches": "always" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "switches": "always" }]*/
switch (a) {
case 0: foo();
}
```
:::
Examples of **correct** code for this rule with the `{ "switches": "always" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "switches": "always" }]*/
switch (a) {
case 0: foo();
}
if (a) {
b();
}
```
:::
Examples of **incorrect** code for this rule with the `{ "switches": "never" }` option:
::: incorrect
```js
/*eslint padded-blocks: ["error", { "switches": "never" }]*/
switch (a) {
case 0: foo();
}
```
:::
Examples of **correct** code for this rule with the `{ "switches": "never" }` option:
::: correct
```js
/*eslint padded-blocks: ["error", { "switches": "never" }]*/
switch (a) {
case 0: foo();
}
if (a) {
b();
}
```
:::
### always + allowSingleLineBlocks
Examples of **incorrect** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options:
::: incorrect
```js
/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/
if (a) {
b();
}
if (a) {
b();
}
if (a) {
b();
}
```
:::
Examples of **correct** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options:
::: correct
```js
/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/
if (a) { b(); }
if (a) {
b();
}
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of padding within blocks.
---
---
title: padding-line-between-statements
rule_type: layout
---
This rule requires or disallows blank lines between the given 2 kinds of statements.
Properly blank lines help developers to understand the code.
For example, the following configuration requires a blank line between a variable declaration and a `return` statement.
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "var", next: "return" }
]*/
function foo() {
var a = 1;
return a;
}
```
## Rule Details
This rule does nothing if no configurations are provided.
A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "var", next: "return" }` means "one or more blank lines are required between a variable declaration and a `return` statement."
You can supply any number of configurations. If a statement pair matches multiple configurations, the last matched configuration will be used.
```json
{
"padding-line-between-statements": [
"error",
{ "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE },
{ "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE },
{ "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE },
{ "blankLine": LINEBREAK_TYPE, "prev": STATEMENT_TYPE, "next": STATEMENT_TYPE },
...
]
}
```
* `LINEBREAK_TYPE` is one of the following.
* `"any"` just ignores the statement pair.
* `"never"` disallows blank lines.
* `"always"` requires one or more blank lines. Note it does not count lines that comments exist as blank lines.
* `STATEMENT_TYPE` is one of the following, or an array of the following.
* `"*"` is wildcard. This matches any statements.
* `"block"` is lonely blocks.
* `"block-like"` is block like statements. This matches statements that the last token is the closing brace of blocks; e.g. `{ }`, `if (a) { }`, and `while (a) { }`. Also matches immediately invoked function expression statements.
* `"break"` is `break` statements.
* `"case"` is `case` clauses in `switch` statements.
* `"cjs-export"` is `export` statements of CommonJS; e.g. `module.exports = 0`, `module.exports.foo = 1`, and `exports.foo = 2`. This is a special case of assignment.
* `"cjs-import"` is `import` statements of CommonJS; e.g. `const foo = require("foo")`. This is a special case of variable declarations.
* `"class"` is `class` declarations.
* `"const"` is `const` variable declarations, both single-line and multiline.
* `"continue"` is `continue` statements.
* `"debugger"` is `debugger` statements.
* `"default"` is `default` clauses in `switch` statements.
* `"directive"` is directive prologues. This matches directives; e.g. `"use strict"`.
* `"do"` is `do-while` statements. This matches all statements that the first token is `do` keyword.
* `"empty"` is empty statements.
* `"export"` is `export` declarations.
* `"expression"` is expression statements.
* `"for"` is `for` loop families. This matches all statements that the first token is `for` keyword.
* `"function"` is function declarations.
* `"if"` is `if` statements.
* `"iife"` is immediately invoked function expression statements. This matches calls on a function expression, optionally prefixed with a unary operator.
* `"import"` is `import` declarations.
* `"let"` is `let` variable declarations, both single-line and multiline.
* `"multiline-block-like"` is block like statements. This is the same as `block-like` type, but only if the block is multiline.
* `"multiline-const"` is multiline `const` variable declarations.
* `"multiline-expression"` is expression statements. This is the same as `expression` type, but only if the statement is multiline.
* `"multiline-let"` is multiline `let` variable declarations.
* `"multiline-var"` is multiline `var` variable declarations.
* `"return"` is `return` statements.
* `"singleline-const"` is single-line `const` variable declarations.
* `"singleline-let"` is single-line `let` variable declarations.
* `"singleline-var"` is single-line `var` variable declarations.
* `"switch"` is `switch` statements.
* `"throw"` is `throw` statements.
* `"try"` is `try` statements.
* `"var"` is `var` variable declarations, both single-line and multiline.
* `"while"` is `while` loop statements.
* `"with"` is `with` statements.
This configuration would require blank lines before all `return` statements, like the [newline-before-return](newline-before-return) rule.
Examples of **incorrect** code for the `[{ blankLine: "always", prev: "*", next: "return" }]` configuration:
::: incorrect
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "*", next: "return" }
]*/
function foo() {
bar();
return;
}
```
:::
Examples of **correct** code for the `[{ blankLine: "always", prev: "*", next: "return" }]` configuration:
::: correct
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "*", next: "return" }
]*/
function foo1() {
bar();
return;
}
function foo2() {
return;
}
```
:::
----
This configuration would require blank lines after every sequence of variable declarations, like the [newline-after-var](newline-after-var) rule.
Examples of **incorrect** code for the `[{ blankLine: "always", prev: ["const", "let", "var"], next: "*"}, { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}]` configuration:
::: incorrect
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: ["const", "let", "var"], next: "*"},
{ blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}
]*/
function foo1() {
var a = 0;
bar();
}
function foo2() {
let a = 0;
bar();
}
function foo3() {
const a = 0;
bar();
}
class C {
static {
let a = 0;
bar();
}
}
```
:::
Examples of **correct** code for the `[{ blankLine: "always", prev: ["const", "let", "var"], next: "*"}, { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}]` configuration:
::: correct
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: ["const", "let", "var"], next: "*"},
{ blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}
]*/
function foo1() {
var a = 0;
var b = 0;
bar();
}
function foo2() {
let a = 0;
const b = 0;
bar();
}
function foo3() {
const a = 0;
const b = 0;
bar();
}
class C {
static {
let a = 0;
let b = 0;
bar();
}
}
```
:::
----
This configuration would require blank lines after all directive prologues, like the [lines-around-directive](lines-around-directive) rule.
Examples of **incorrect** code for the `[{ blankLine: "always", prev: "directive", next: "*" }, { blankLine: "any", prev: "directive", next: "directive" }]` configuration:
::: incorrect
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "directive", next: "*" },
{ blankLine: "any", prev: "directive", next: "directive" }
]*/
"use strict";
foo();
```
:::
Examples of **correct** code for the `[{ blankLine: "always", prev: "directive", next: "*" }, { blankLine: "any", prev: "directive", next: "directive" }]` configuration:
::: correct
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "directive", next: "*" },
{ blankLine: "any", prev: "directive", next: "directive" }
]*/
"use strict";
"use asm";
foo();
```
:::
----
This configuration would require blank lines between clauses in `switch` statements.
Examples of **incorrect** code for the `[{ blankLine: "always", prev: ["case", "default"], next: "*" }]` configuration:
::: incorrect
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: ["case", "default"], next: "*" }
]*/
switch (foo) {
case 1:
bar();
break;
case 2:
case 3:
baz();
break;
default:
quux();
}
```
:::
Examples of **correct** code for the `[{ blankLine: "always", prev: ["case", "default"], next: "*" }]` configuration:
::: correct
```js
/*eslint padding-line-between-statements: [
"error",
{ blankLine: "always", prev: ["case", "default"], next: "*" }
]*/
switch (foo) {
case 1:
bar();
break;
case 2:
case 3:
baz();
break;
default:
quux();
}
```
:::
## When Not To Use It
If you don't want to notify warnings about linebreaks, then it's safe to disable this rule.
## Compatibility
* **JSCS:** [requirePaddingNewLineAfterVariableDeclaration](https://jscs-dev.github.io/rule/requirePaddingNewLineAfterVariableDeclaration)
* **JSCS:** [requirePaddingNewLinesAfterBlocks](https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterBlocks)
* **JSCS:** [disallowPaddingNewLinesAfterBlocks](https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterBlocks)
* **JSCS:** [requirePaddingNewLinesAfterUseStrict](https://jscs-dev.github.io/rule/requirePaddingNewLinesAfterUseStrict)
* **JSCS:** [disallowPaddingNewLinesAfterUseStrict](https://jscs-dev.github.io/rule/disallowPaddingNewLinesAfterUseStrict)
* **JSCS:** [requirePaddingNewLinesBeforeExport](https://jscs-dev.github.io/rule/requirePaddingNewLinesBeforeExport)
* **JSCS:** [disallowPaddingNewLinesBeforeExport](https://jscs-dev.github.io/rule/disallowPaddingNewLinesBeforeExport)
* **JSCS:** [requirePaddingNewlinesBeforeKeywords](https://jscs-dev.github.io/rule/requirePaddingNewlinesBeforeKeywords)
* **JSCS:** [disallowPaddingNewlinesBeforeKeywords](https://jscs-dev.github.io/rule/disallowPaddingNewlinesBeforeKeywords)
---
---
title: prefer-arrow-callback
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
---
Arrow functions can be an attractive alternative to function expressions for callbacks or function arguments.
For example, arrow functions are automatically bound to their surrounding scope/context. This provides an alternative to the pre-ES6 standard of explicitly binding function expressions to achieve similar behavior.
Additionally, arrow functions are:
* less verbose, and easier to reason about.
* bound lexically regardless of where or when they are invoked.
## Rule Details
This rule locates function expressions used as callbacks or function arguments. An error will be produced for any that could be replaced by an arrow function without changing the result.
The following examples **will** be flagged:
::: incorrect
```js
/* eslint prefer-arrow-callback: "error" */
foo(function(a) { return a; }); // ERROR
// prefer: foo(a => a)
foo(function() { return this.a; }.bind(this)); // ERROR
// prefer: foo(() => this.a)
```
:::
Instances where an arrow function would not produce identical results will be ignored.
The following examples **will not** be flagged:
::: correct
```js
/* eslint prefer-arrow-callback: "error" */
// arrow function callback
foo(a => a); // OK
// generator as callback
foo(function*() { yield; }); // OK
// function expression not used as callback or function argument
const foo = function foo(a) { return a; }; // OK
// unbound function expression callback
foo(function() { return this.a; }); // OK
// recursive named function callback
foo(function bar(n) { return n && n + bar(n - 1); }); // OK
```
:::
This rule additionally supports TypeScript type syntax.
Examples of **incorrect** TypeScript code for this rule:
::: incorrect
```ts
/*eslint prefer-arrow-callback: "error"*/
foo(function bar(a: string) { a; });
test('foo', function (this: any) {});
```
:::
Examples of **correct** TypeScript code for this rule:
::: correct
```ts
/*eslint prefer-arrow-callback: "error"*/
foo((a: string) => a);
const foo = function foo(bar: any) {};
```
:::
## Options
Access further control over this rule's behavior via an options object.
Default: `{ allowNamedFunctions: false, allowUnboundThis: true }`
### allowNamedFunctions
By default `{ "allowNamedFunctions": false }`, this `boolean` option prohibits using named functions as callbacks or function arguments.
Changing this value to `true` will reverse this option's behavior by allowing use of named functions without restriction.
`{ "allowNamedFunctions": true }` **will not** flag the following example:
::: correct
```js
/* eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ] */
foo(function bar() {});
```
:::
Examples of **incorrect** TypeScript code for this rule with `{ "allowNamedFunctions": true }`:
::: incorrect
```ts
/* eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ] */
foo(function(a: string) {});
```
:::
Examples of **correct** TypeScript code for this rule with `{ "allowNamedFunctions": true }`:
::: correct
```ts
/* eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ] */
foo(function bar(a: string) {});
```
:::
### allowUnboundThis
By default `{ "allowUnboundThis": true }`, this `boolean` option allows function expressions containing `this` to be used as callbacks, as long as the function in question has not been explicitly bound.
When set to `false` this option prohibits the use of function expressions as callbacks or function arguments entirely, without exception.
`{ "allowUnboundThis": false }` **will** flag the following examples:
::: incorrect
```js
/* eslint prefer-arrow-callback: [ "error", { "allowUnboundThis": false } ] */
foo(function() { this.a; });
foo(function() { (() => this); });
someArray.map(function(item) { return this.doSomething(item); }, someObject);
```
:::
Examples of **incorrect** TypeScript code for this rule with `{ "allowUnboundThis": false }`:
::: incorrect
```ts
/* eslint prefer-arrow-callback: [ "error", { "allowUnboundThis": false } ] */
foo(function(a: string) { this; });
foo(function(a: string) { (() => this); });
```
:::
## When Not To Use It
* In environments that have not yet adopted ES6 language features (ES3/5).
* In ES6+ environments that allow the use of function expressions when describing callbacks or function arguments.
---
---
title: prefer-const
rule_type: suggestion
related_rules:
- no-var
- no-unassigned-vars
- no-use-before-define
---
If a variable is never reassigned, using the `const` declaration is better.
`const` declaration tells readers, "this variable is never reassigned," reducing cognitive load and improving maintainability.
## Rule Details
This rule is aimed at flagging variables that are declared using `let` keyword, but never reassigned after the initial assignment.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-const: "error"*/
// it's initialized and never reassigned.
let a = 3;
console.log(a);
let b;
b = 0;
console.log(b);
class C {
static {
let a;
a = 0;
console.log(a);
}
}
// `i` is redefined (not reassigned) on each loop step.
for (let i in [1, 2, 3]) {
console.log(i);
}
// `a` is redefined (not reassigned) on each loop step.
for (let a of [1, 2, 3]) {
console.log(a);
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-const: "error"*/
// using const.
const a = 0;
// it's never initialized.
let b;
console.log(b);
// it's reassigned after initialized.
let c;
c = 0;
c = 1;
console.log(c);
// it's initialized in a different block from the declaration.
let d;
if (true) {
d = 0;
}
console.log(d);
// it's initialized in a different scope.
let e;
class C {
#x;
static {
e = obj => obj.#x;
}
}
// it's initialized at a place that we cannot write a variable declaration.
let f;
if (true) f = 0;
console.log(f);
// `i` gets a new binding each iteration
for (const i in [1, 2, 3]) {
console.log(i);
}
// `a` gets a new binding each iteration
for (const a of [1, 2, 3]) {
console.log(a);
}
// `end` is never reassigned, but we cannot separate the declarations without modifying the scope.
for (let i = 0, end = 10; i < end; ++i) {
console.log(i);
}
// `predicate` is only assigned once but cannot be separately declared as `const`
let predicate;
[object.type, predicate] = foo();
// `g` is only assigned once but cannot be separately declared as `const`
let g;
const h = {};
({ g, c: h.c } = func());
// suggest to use `no-var` rule.
var i = 3;
console.log(i);
```
:::
## Options
```json
{
"prefer-const": ["error", {
"destructuring": "any",
"ignoreReadBeforeAssign": false
}]
}
```
### destructuring
The kind of the way to address variables in destructuring.
There are 2 values:
* `"any"` (default) - If any variables in destructuring should be `const`, this rule warns for those variables.
* `"all"` - If all variables in destructuring should be `const`, this rule warns the variables. Otherwise, ignores them.
Examples of **incorrect** code for the default `{"destructuring": "any"}` option:
::: incorrect
```js
/*eslint prefer-const: "error"*/
let {a, b} = obj; /*error 'b' is never reassigned, use 'const' instead.*/
a = a + 1;
```
:::
Examples of **correct** code for the default `{"destructuring": "any"}` option:
::: correct
```js
/*eslint prefer-const: "error"*/
// using const.
const {a: a0, b} = obj;
const a = a0 + 1;
// all variables are reassigned.
let {c, d} = obj;
c = c + 1;
d = d + 1;
```
:::
Examples of **incorrect** code for the `{"destructuring": "all"}` option:
::: incorrect
```js
/*eslint prefer-const: ["error", {"destructuring": "all"}]*/
// all of `a` and `b` should be const, so those are warned.
let {a, b} = obj; /*error 'a' is never reassigned, use 'const' instead.
'b' is never reassigned, use 'const' instead.*/
```
:::
Examples of **correct** code for the `{"destructuring": "all"}` option:
::: correct
```js
/*eslint prefer-const: ["error", {"destructuring": "all"}]*/
// 'b' is never reassigned, but all of `a` and `b` should not be const, so those are ignored.
let {a, b} = obj;
a = a + 1;
```
:::
### ignoreReadBeforeAssign
This is an option to avoid conflicting with `no-use-before-define` rule (without `"nofunc"` option).
If `true` is specified, this rule will ignore variables that are read between the declaration and the first assignment.
Default is `false`.
Examples of **correct** code for the `{"ignoreReadBeforeAssign": true}` option:
::: correct
```js
/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": true}]*/
let timer;
function initialize() {
if (foo()) {
clearInterval(timer);
}
}
timer = setInterval(initialize, 100);
```
:::
Examples of **correct** code for the default `{"ignoreReadBeforeAssign": false}` option:
::: correct
```js
/*eslint prefer-const: ["error", {"ignoreReadBeforeAssign": false}]*/
const timer = setInterval(initialize, 100);
function initialize() {
if (foo()) {
clearInterval(timer);
}
}
```
:::
## When Not To Use It
If you don't want to be notified about variables that are never reassigned after initial assignment, you can safely disable this rule.
---
---
title: prefer-destructuring
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
- https://2ality.com/2015/01/es6-destructuring.html
---
With JavaScript ES6, a new syntax was added for creating variables from an array index or object property, called [destructuring](#further-reading). This rule enforces usage of destructuring instead of accessing a property through a member expression.
## Rule Details
This rule enforces the use of ES6 destructuring to extract values from arrays and objects in variable declarations and assignment expressions, instead of direct property or index access.
## Options
This rule takes two arguments, both of which are objects. The first object parameter determines what types of destructuring the rule applies to.
In the first object, there are two properties, `array` and `object`, that can be used to turn on or off the destructuring requirement for each of those types independently. By default, both are `true`.
```json
{
"rules": {
"prefer-destructuring": ["error", {
"array": true,
"object": true
}]
}
}
```
For example, the following configuration enforces only object destructuring, but not array destructuring:
```json
{
"rules": {
"prefer-destructuring": ["error", {"object": true, "array": false}]
}
}
```
Examples of **incorrect** code for this rule:
::: incorrect
```javascript
/* eslint prefer-destructuring: "error" */
// With `array` enabled
const foo = array[0];
bar.baz = array[0];
// With `object` enabled
const qux = object.qux;
const quux = object['quux'];
```
:::
Examples of **correct** code for this rule:
::: correct
```javascript
/* eslint prefer-destructuring: "error" */
// With `array` enabled
const [ foo ] = array;
const arr = array[someIndex];
[bar.baz] = array;
// With `object` enabled
const { baz } = object;
const obj = object.bar;
let bar;
({ bar } = object);
```
:::
Alternatively, you can use separate configurations for different assignment types. The first argument accepts two other keys instead of `array` and `object`.
One key is `VariableDeclarator` and the other is `AssignmentExpression`, which can be used to control the destructuring requirement for each of those types independently. Each property is an object containing two properties, `array` and `object`, which can be used to control the destructuring requirement for each of `array` and `object` independently for variable declarations and assignment expressions. By default, `array` and `object` are set to `true` for both `VariableDeclarator` and `AssignmentExpression`.
```json
{
"rules": {
"prefer-destructuring": ["error", {
"VariableDeclarator": {
"array": true,
"object": true
},
"AssignmentExpression": {
"array": true,
"object": true
}
}]
}
}
```
Examples of **correct** code when object destructuring in `VariableDeclarator` is enforced:
::: correct
```javascript
/* eslint prefer-destructuring: ["error", {VariableDeclarator: {object: true}}] */
const {bar: foo} = object;
```
:::
Examples of **correct** code when array destructuring in `AssignmentExpression` is enforced:
::: correct
```javascript
/* eslint prefer-destructuring: ["error", {AssignmentExpression: {array: true}}] */
[bar] = array;
```
:::
### enforceForRenamedProperties
The rule has a second object argument with a single key, `enforceForRenamedProperties`, which determines whether the `object` destructuring applies to renamed variables.
```json
{
"rules": {
"prefer-destructuring": ["error",
{
"object": true
},
{
"enforceForRenamedProperties": true
}]
}
}
```
Examples of **incorrect** code when `enforceForRenamedProperties` is enabled:
::: incorrect
```javascript
/* eslint "prefer-destructuring": ["error", { "object": true }, { "enforceForRenamedProperties": true }] */
const foo = object.bar;
```
:::
Examples of **correct** code when `enforceForRenamedProperties` is enabled:
::: correct
```javascript
/* eslint "prefer-destructuring": ["error", { "object": true }, { "enforceForRenamedProperties": true }] */
const { bar: foo } = object;
```
:::
Examples of additional **correct** code when `enforceForRenamedProperties` is enabled:
::: correct
```javascript
/* eslint "prefer-destructuring": ["error", { "object": true }, { "enforceForRenamedProperties": true }] */
class C {
#x;
foo() {
const bar = this.#x; // private identifiers are not allowed in destructuring
}
}
```
:::
**Note**: It is not possible to determine if a variable will be referring to an object or an array at runtime. This rule therefore guesses the assignment type by checking whether the key being accessed is an integer. This can lead to the following possibly confusing situations:
* Accessing an object property whose key is an integer will fall under the category `array` destructuring.
* Accessing an array element through a computed index will fall under the category `object` destructuring.
The `--fix` option on the command line fixes only problems reported in variable declarations, and among them only those that fall under the category `object` destructuring. Furthermore, the name of the declared variable has to be the same as the name used for non-computed member access in the initializer. For example, `const foo = object.foo` can be automatically fixed by this rule. Problems that involve computed member access (e.g., `const foo = object[foo]`) or renamed properties (e.g., `const foo = object.bar`) are not automatically fixed.
## When Not To Use It
If you want to be able to access array indices or object properties directly, you can either configure the rule to your tastes or disable the rule entirely.
Additionally, if you intend to access large array indices directly, like:
```javascript
const foo = array[100];
```
Then the `array` part of this rule is not recommended, as destructuring does not match this use case very well.
Or for non-iterable 'array-like' objects:
```javascript
const $ = require('jquery');
const foo = $('body')[0];
const [bar] = $('body'); // fails with a TypeError
```
---
---
title: prefer-exponentiation-operator
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation
- https://bugs.chromium.org/p/v8/issues/detail?id=5848
---
Introduced in ES2016, the infix exponentiation operator `**` is an alternative for the standard `Math.pow` function.
Infix notation is considered to be more readable and thus more preferable than the function notation.
## Rule Details
This rule disallows calls to `Math.pow` and suggests using the `**` operator instead.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-exponentiation-operator: "error"*/
const foo = Math.pow(2, 8);
const bar = Math.pow(a, b);
let baz = Math.pow(a + b, c + d);
let quux = Math.pow(-1, n);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-exponentiation-operator: "error"*/
const foo = 2 ** 8;
const bar = a ** b;
let baz = (a + b) ** (c + d);
let quux = (-1) ** n;
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used unless ES2016 is supported in your codebase.
---
---
title: prefer-named-capture-group
rule_type: suggestion
related_rules:
- no-invalid-regexp
---
## Rule Details
With the landing of ECMAScript 2018, named capture groups can be used in regular expressions, which can improve their readability.
This rule is aimed at using named capture groups instead of numbered capture groups in regular expressions:
```js
const regex = /(?[0-9]{4})/;
```
Alternatively, if your intention is not to _capture_ the results, but only express the alternative, use a non-capturing group:
```js
const regex = /(?:cauli|sun)flower/;
```
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-named-capture-group: "error"*/
const foo = /(ba[rz])/;
const bar = new RegExp('(ba[rz])');
const baz = RegExp('(ba[rz])');
foo.exec('bar')[1]; // Retrieve the group result.
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-named-capture-group: "error"*/
const foo = /(?ba[rz])/;
const bar = new RegExp('(?ba[rz])');
const baz = RegExp('(?ba[rz])');
const xyz = /xyz(?:zy|abc)/;
foo.exec('bar').groups.id; // Retrieve the group result.
```
:::
## Options
This rule has no options.
## When Not To Use It
If you are targeting ECMAScript 2017 and/or older environments, you should not use this rule, because this ECMAScript feature is only supported in ECMAScript 2018 and/or newer environments.
---
---
title: prefer-numeric-literals
rule_type: suggestion
---
The `parseInt()` and `Number.parseInt()` functions can be used to turn binary, octal, and hexadecimal strings into integers. As binary, octal, and hexadecimal literals are supported in ES6, this rule encourages use of those numeric literals instead of `parseInt()` or `Number.parseInt()`.
```js
0b111110111 === 503;
0o767 === 503;
```
## Rule Details
This rule disallows calls to `parseInt()` or `Number.parseInt()` if called with two arguments: a string; and a radix option of 2 (binary), 8 (octal), or 16 (hexadecimal).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-numeric-literals: "error"*/
parseInt("111110111", 2) === 503;
parseInt(`111110111`, 2) === 503;
parseInt("767", 8) === 503;
parseInt("1F7", 16) === 503;
Number.parseInt("111110111", 2) === 503;
Number.parseInt("767", 8) === 503;
Number.parseInt("1F7", 16) === 503;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-numeric-literals: "error"*/
parseInt(1);
parseInt(1, 3);
Number.parseInt(1);
Number.parseInt(1, 3);
0b111110111 === 503;
0o767 === 503;
0x1F7 === 503;
a[parseInt](1,2);
parseInt(foo);
parseInt(foo, 2);
Number.parseInt(foo);
Number.parseInt(foo, 2);
```
:::
## Options
This rule has no options.
## When Not To Use It
If you want to allow use of `parseInt()` or `Number.parseInt()` for binary, octal, or hexadecimal integers, or if you are not using ES6 (because binary and octal literals are not supported in ES5 and below), you may wish to disable this rule.
## Compatibility
* **JSCS**: [requireNumericLiterals](https://jscs-dev.github.io/rule/requireNumericLiterals)
---
---
title: prefer-object-has-own
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn
---
It is very common to write code like:
```js
if (Object.prototype.hasOwnProperty.call(object, "foo")) {
console.log("has property foo");
}
```
This is a common practice because methods on `Object.prototype` can sometimes be unavailable or redefined (see the [no-prototype-builtins](no-prototype-builtins) rule).
Introduced in ES2022, `Object.hasOwn()` is a shorter alternative to `Object.prototype.hasOwnProperty.call()`:
```js
if (Object.hasOwn(object, "foo")) {
console.log("has property foo")
}
```
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-object-has-own: "error"*/
Object.prototype.hasOwnProperty.call(obj, "a");
Object.hasOwnProperty.call(obj, "a");
({}).hasOwnProperty.call(obj, "a");
const hasProperty = Object.prototype.hasOwnProperty.call(object, property);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-object-has-own: "error"*/
Object.hasOwn(obj, "a");
const hasProperty = Object.hasOwn(object, property);
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used unless ES2022 is supported in your codebase.
---
---
title: prefer-object-spread
rule_type: suggestion
---
When `Object.assign` is called using an object literal as the first argument, this rule requires using the object spread syntax instead. This rule also warns on cases where an `Object.assign` call is made using a single argument that is an object literal, in this case, the `Object.assign` call is not needed.
Introduced in ES2018, object spread is a declarative alternative which may perform better than the more dynamic, imperative `Object.assign`.
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-object-spread: "error"*/
Object.assign({}, foo);
Object.assign({}, {foo: 'bar'});
Object.assign({ foo: 'bar'}, baz);
Object.assign({}, baz, { foo: 'bar' });
Object.assign({}, { ...baz });
// Object.assign with a single argument that is an object literal
Object.assign({});
Object.assign({ foo: bar });
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-object-spread: "error"*/
({ ...foo });
({ ...baz, foo: 'bar' });
// Any Object.assign call without an object literal as the first argument
Object.assign(foo, { bar: baz });
Object.assign(foo, bar);
Object.assign(foo, { bar, baz });
Object.assign(foo, { ...baz });
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used unless ES2018 is supported in your codebase.
---
---
title: prefer-promise-reject-errors
rule_type: suggestion
related_rules:
- no-throw-literal
further_reading:
- http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-rejected-with-a-non-error
---
It is considered good practice to only pass instances of the built-in `Error` object to the `reject()` function for user-defined errors in Promises. `Error` objects automatically store a stack trace, which can be used to debug an error by determining where it came from. If a Promise is rejected with a non-`Error` value, it can be difficult to determine where the rejection occurred.
## Rule Details
This rule aims to ensure that Promises are only rejected with `Error` objects.
## Options
This rule takes one optional object argument:
* `allowEmptyReject: true` (`false` by default) allows calls to `Promise.reject()` with no arguments.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-promise-reject-errors: "error"*/
Promise.reject("something bad happened");
Promise.reject(5);
Promise.reject();
new Promise(function(resolve, reject) {
reject("something bad happened");
});
new Promise(function(resolve, reject) {
reject();
});
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-promise-reject-errors: "error"*/
Promise.reject(new Error("something bad happened"));
Promise.reject(new TypeError("something bad happened"));
new Promise(function(resolve, reject) {
reject(new Error("something bad happened"));
});
const foo = getUnknownValue();
Promise.reject(foo);
```
:::
Examples of **correct** code for this rule with the `allowEmptyReject: true` option:
::: correct
```js
/*eslint prefer-promise-reject-errors: ["error", {"allowEmptyReject": true}]*/
Promise.reject();
new Promise(function(resolve, reject) {
reject();
});
```
:::
## Known Limitations
Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](no-throw-literal#known-limitations) in the `no-throw-literal` rule.
To avoid conflicts between rules, this rule does not report non-error values used in `throw` statements in async functions, even though these lead to Promise rejections. To lint for these cases, use the [`no-throw-literal`](no-throw-literal) rule.
## When Not To Use It
If you're using custom non-error values as Promise rejection reasons, you can turn off this rule.
---
---
title: prefer-reflect
rule_type: suggestion
related_rules:
- no-useless-call
- prefer-spread
- no-delete-var
---
The original intent of this rule now seems misguided as we have come to understand that `Reflect` methods are not actually intended to replace the `Object` counterparts the rule suggests, but rather exist as low-level primitives to be used with proxies in order to replicate the default behavior of various previously existing functionality.
**Please note**: This rule contains an incorrect behavior - it will suggest you to use `Reflect.getOwnPropertyNames` rather than `Object.getOwnPropertyNames`, but the former one doesn't exist in the [specification](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflection). We suggest using the `exceptions` option with `"getOwnPropertyNames"` to avoid this false suggestion.
The ES6 Reflect API comes with a handful of methods which somewhat deprecate methods on old constructors:
* [`Reflect.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.apply) effectively deprecates [`Function.prototype.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.apply) and [`Function.prototype.call`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.call)
* [`Reflect.deleteProperty`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.deleteproperty) effectively deprecates the [`delete` keyword](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-delete-operator-runtime-semantics-evaluation)
* [`Reflect.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getownpropertydescriptor) effectively deprecates [`Object.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getownpropertydescriptor)
* [`Reflect.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getprototypeof) effectively deprecates [`Object.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getprototypeof)
* [`Reflect.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.setprototypeof) effectively deprecates [`Object.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof)
* [`Reflect.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.preventextensions) effectively deprecates [`Object.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.preventextensions)
The prefer-reflect rule will flag usage of any older method, suggesting to instead use the newer Reflect version.
## Rule Details
## Options
### Exceptions
```js
"prefer-reflect": [, { "exceptions": [<...exceptions>] }]
```
The `exceptions` option allows you to pass an array of methods names you'd like to continue to use in the old style.
For example if you wish to use all Reflect methods, except for `Function.prototype.apply` then your config would look like `prefer-reflect: [2, { "exceptions": ["apply"] }]`.
If you want to use Reflect methods, but keep using the `delete` keyword, then your config would look like `prefer-reflect: [2, { "exceptions": ["delete"] }]`.
These can be combined as much as you like. To make all methods exceptions (thereby rendering this rule useless), use `prefer-reflect: [2, { "exceptions": ["apply", "call", "defineProperty", "getOwnPropertyDescriptor", "getPrototypeOf", "setPrototypeOf", "isExtensible", "getOwnPropertyNames", "preventExtensions", "delete"] }]`
### Reflect.apply
Deprecates `Function.prototype.apply()` and `Function.prototype.call()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
myFunction.apply(undefined, args);
myFunction.apply(null, args);
obj.myMethod.apply(obj, args);
obj.myMethod.apply(other, args);
myFunction.call(undefined, arg);
myFunction.call(null, arg);
obj.myMethod.call(obj, arg);
obj.myMethod.call(other, arg);
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.apply(myFunction, undefined, args);
Reflect.apply(myFunction, null, args);
Reflect.apply(obj.myMethod, obj, args);
Reflect.apply(obj.myMethod, other, args);
Reflect.apply(myFunction, undefined, [arg]);
Reflect.apply(myFunction, null, [arg]);
Reflect.apply(obj.myMethod, obj, [arg]);
Reflect.apply(obj.myMethod, other, [arg]);
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["apply"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["apply"] }]*/
// in addition to Reflect.apply(...):
myFunction.apply(undefined, args);
myFunction.apply(null, args);
obj.myMethod.apply(obj, args);
obj.myMethod.apply(other, args);
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["call"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["call"] }]*/
// in addition to Reflect.apply(...):
myFunction.call(undefined, arg);
myFunction.call(null, arg);
obj.myMethod.call(obj, arg);
obj.myMethod.call(other, arg);
```
:::
### Reflect.defineProperty
Deprecates `Object.defineProperty()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.defineProperty({}, 'foo', {value: 1})
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.defineProperty({}, 'foo', {value: 1})
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["defineProperty"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["defineProperty"] }]*/
Object.defineProperty({}, 'foo', {value: 1})
Reflect.defineProperty({}, 'foo', {value: 1})
```
:::
### Reflect.getOwnPropertyDescriptor
Deprecates `Object.getOwnPropertyDescriptor()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.getOwnPropertyDescriptor({}, 'foo')
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.getOwnPropertyDescriptor({}, 'foo')
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["getOwnPropertyDescriptor"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["getOwnPropertyDescriptor"] }]*/
Object.getOwnPropertyDescriptor({}, 'foo')
Reflect.getOwnPropertyDescriptor({}, 'foo')
```
:::
### Reflect.getPrototypeOf
Deprecates `Object.getPrototypeOf()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.getPrototypeOf({}, 'foo')
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.getPrototypeOf({}, 'foo')
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["getPrototypeOf"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["getPrototypeOf"] }]*/
Object.getPrototypeOf({}, 'foo')
Reflect.getPrototypeOf({}, 'foo')
```
:::
### Reflect.setPrototypeOf
Deprecates `Object.setPrototypeOf()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.setPrototypeOf({}, Object.prototype)
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.setPrototypeOf({}, Object.prototype)
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["setPrototypeOf"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["setPrototypeOf"] }]*/
Object.setPrototypeOf({}, Object.prototype)
Reflect.setPrototypeOf({}, Object.prototype)
```
:::
### Reflect.isExtensible
Deprecates `Object.isExtensible`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.isExtensible({})
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.isExtensible({})
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["isExtensible"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["isExtensible"] }]*/
Object.isExtensible({})
Reflect.isExtensible({})
```
:::
### Reflect.preventExtensions
Deprecates `Object.preventExtensions()`
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
Object.preventExtensions({})
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct
```js
/*eslint prefer-reflect: "error"*/
Reflect.preventExtensions({})
```
:::
Examples of **correct** code for this rule with the `{ "exceptions": ["preventExtensions"] }` option:
::: correct
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["preventExtensions"] }]*/
Object.preventExtensions({})
Reflect.preventExtensions({})
```
:::
### Reflect.deleteProperty
Deprecates the `delete` keyword
Examples of **incorrect** code for this rule when used without exceptions:
::: incorrect
```js
/*eslint prefer-reflect: "error"*/
delete foo.bar; // deleting object property
```
:::
Examples of **correct** code for this rule when used without exceptions:
::: correct { "sourceType": "script" }
```js
/*eslint prefer-reflect: "error"*/
delete bar; // deleting variable
Reflect.deleteProperty(foo, 'bar');
```
:::
Note: For a rule preventing deletion of variables, see [no-delete-var instead](no-delete-var)
Examples of **correct** code for this rule with the `{ "exceptions": ["delete"] }` option:
::: correct { "sourceType": "script" }
```js
/*eslint prefer-reflect: ["error", { "exceptions": ["delete"] }]*/
delete bar
delete foo.bar
Reflect.deleteProperty(foo, 'bar');
```
:::
## When Not To Use It
This rule should not be used in ES3/5 environments.
In ES2015 (ES6) or later, if you don't want to be notified about places where Reflect could be used, you can safely disable this rule.
---
---
title: prefer-regex-literals
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
---
There are two ways to create a regular expression:
* Regular expression literals, e.g., `/abc/u`.
* The `RegExp` constructor function, e.g., `new RegExp("abc", "u")` or `RegExp("abc", "u")`.
The constructor function is particularly useful when you want to dynamically generate the pattern,
because it takes string arguments.
When using the constructor function with string literals, don't forget that the string escaping rules still apply.
If you want to put a backslash in the pattern, you need to escape it in the string literal.
Thus, the following are equivalent:
```js
new RegExp("^\\d\\.$");
/^\d\.$/;
// matches "0.", "1.", "2." ... "9."
```
In the above example, the regular expression literal is easier to read and reason about.
Also, it's a common mistake to omit the extra `\` in the string literal, which would produce a completely different regular expression:
```js
new RegExp("^\d\.$");
// equivalent to /^d.$/, matches "d1", "d2", "da", "db" ...
```
When a regular expression is known in advance, it is considered a best practice to avoid the string literal notation on top
of the regular expression notation, and use regular expression literals instead of the constructor function.
## Rule Details
This rule disallows the use of the `RegExp` constructor function with string literals as its arguments.
This rule also disallows the use of the `RegExp` constructor function with template literals without expressions
and `String.raw` tagged template literals without expressions.
The rule does not disallow all use of the `RegExp` constructor. It should be still used for
dynamically generated regular expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-regex-literals: "error"*/
new RegExp("abc");
new RegExp("abc", "u");
RegExp("abc");
RegExp("abc", "u");
new RegExp("\\d\\d\\.\\d\\d\\.\\d\\d\\d\\d");
RegExp(`^\\d\\.$`);
new RegExp(String.raw`^\d\.$`);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-regex-literals: "error"*/
/abc/;
/abc/u;
/\d\d\.\d\d\.\d\d\d\d/;
/^\d\.$/;
// RegExp constructor is allowed for dynamically generated regular expressions
new RegExp(pattern);
RegExp("abc", flags);
new RegExp(prefix + "abc");
RegExp(`${prefix}abc`);
new RegExp(String.raw`^\d\. ${suffix}`);
```
:::
## Options
This rule has an object option:
* `disallowRedundantWrapping` set to `true` additionally checks for unnecessarily wrapped regex literals (Default `false`).
### disallowRedundantWrapping
By default, this rule doesn’t check when a regex literal is unnecessarily wrapped in a `RegExp` constructor call. When the option `disallowRedundantWrapping` is set to `true`, the rule will also disallow such unnecessary patterns.
Examples of `incorrect` code for `{ "disallowRedundantWrapping": true }`
::: incorrect
```js
/*eslint prefer-regex-literals: ["error", {"disallowRedundantWrapping": true}]*/
new RegExp(/abc/);
new RegExp(/abc/, 'u');
```
:::
Examples of `correct` code for `{ "disallowRedundantWrapping": true }`
::: correct
```js
/*eslint prefer-regex-literals: ["error", {"disallowRedundantWrapping": true}]*/
/abc/;
/abc/u;
new RegExp(/abc/, flags);
```
:::
---
---
title: prefer-rest-params
rule_type: suggestion
related_rules:
- prefer-spread
---
There are rest parameters in ES2015.
We can use that feature for variadic functions instead of the `arguments` variable.
`arguments` does not have methods of `Array.prototype`, so it's a bit of an inconvenience.
## Rule Details
This rule is aimed to flag usage of `arguments` variables.
Examples of **incorrect** code for this rule:
::: incorrect { "sourceType": "script" }
```js
/*eslint prefer-rest-params: "error"*/
function foo() {
console.log(arguments);
}
function foo(action) {
const args = Array.prototype.slice.call(arguments, 1);
action.apply(null, args);
}
function foo(action) {
const args = [].slice.call(arguments, 1);
action.apply(null, args);
}
```
:::
Examples of **correct** code for this rule:
::: correct { "sourceType": "script" }
```js
/*eslint prefer-rest-params: "error"*/
function foo(...args) {
console.log(args);
}
function foo(action, ...args) {
action.apply(null, args); // or `action(...args)`, related to the `prefer-spread` rule.
}
// Note: the implicit arguments can be overwritten.
function foo(arguments) {
console.log(arguments); // This is the first argument.
}
function foo() {
const arguments = 0;
console.log(arguments); // This is a local variable.
}
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
In ES2015 (ES6) or later, if you don't want to be notified about `arguments` variables, then it's safe to disable this rule.
---
---
title: prefer-spread
rule_type: suggestion
related_rules:
- no-useless-call
---
Before ES2015, one must use `Function.prototype.apply()` to call variadic functions.
```js
const args = [1, 2, 3, 4];
Math.max.apply(Math, args);
```
In ES2015, one can use spread syntax to call variadic functions.
```js
const args = [1, 2, 3, 4];
Math.max(...args);
```
## Rule Details
This rule is aimed to flag usage of `Function.prototype.apply()` in situations where spread syntax could be used instead.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-spread: "error"*/
foo.apply(undefined, args);
foo.apply(null, args);
obj.foo.apply(obj, args);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-spread: "error"*/
// Using spread syntax
foo(...args);
obj.foo(...args);
// The `this` binding is different.
foo.apply(obj, args);
obj.foo.apply(null, args);
obj.foo.apply(otherObj, args);
// The argument list is not variadic.
// Those are warned by the `no-useless-call` rule.
foo.apply(undefined, [1, 2, 3]);
foo.apply(null, [1, 2, 3]);
obj.foo.apply(obj, [1, 2, 3]);
```
:::
## Options
This rule has no options.
## Known Limitations
This rule analyzes code statically to check whether or not the `this` argument is changed. So, if the `this` argument is computed in a dynamic expression, this rule cannot detect a violation.
```js
/*eslint prefer-spread: "error"*/
// This warns.
a[i++].foo.apply(a[i++], args);
// This does not warn.
a[++i].foo.apply(a[i], args);
```
## When Not To Use It
This rule should not be used in ES3/5 environments.
In ES2015 (ES6) or later, if you don't want to be notified about `Function.prototype.apply()` callings, you can safely disable this rule.
---
---
title: prefer-template
rule_type: suggestion
related_rules:
- no-useless-concat
- quotes
---
In ES2015 (ES6), we can use template literals instead of string concatenation.
```js
const str = "Hello, " + name + "!";
```
```js
const str = `Hello, ${name}!`;
```
## Rule Details
This rule is aimed to flag usage of `+` operators with strings.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint prefer-template: "error"*/
const str = "Hello, " + name + "!";
const str1 = "Time: " + (12 * 60 * 60 * 1000);
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint prefer-template: "error"*/
const str = "Hello World!";
const str1 = `Hello, ${name}!`;
const str2 = `Time: ${12 * 60 * 60 * 1000}`;
// This is reported by `no-useless-concat`.
const str4 = "Hello, " + "World!";
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
In ES2015 (ES6) or later, if you don't want to be notified about string concatenation, you can safely disable this rule.
---
---
title: preserve-caught-error
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
- https://nodejs.org/api/errors.html#errorcause
- https://github.com/tc39/proposal-error-cause/blob/main/README.md
- https://dev.to/amnish04/never-lose-valuable-error-context-in-javascript-3aco
- https://github.com/microsoft/TypeScript/blob/main/src/lib/es2022.error.d.ts
---
JavaScript developers often re-throw errors in `catch` blocks to add context but forget to preserve the original error, resulting in lost debugging information.
Using the `cause` option when throwing new errors helps retain the original error and maintain complete error chains, which improves debuggability and traceability.
```js
try {
await fetch("https://xyz.com/resource");
} catch(error) {
// Throw a more specific error without losing original context
throw new Error("Failed to fetch resource", {
cause: error
});
}
```
## Rule Details
This rule enforces the use of the `cause` property when throwing a new error inside a `catch` block.
Checks for all built-in `error types` that support passing a `cause`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint preserve-caught-error: "error" */
// Not using the `cause` option
try {
// ...
} catch (error) {
throw new Error("Something went wrong: " + error.message);
}
// Throwing a new Error with unrelated cause
try {
doSomething();
} catch (err) {
const unrelated = new Error("other");
throw new Error("Something failed", { cause: unrelated });
}
// Caught error is being lost partially due to destructuring
try {
doSomething();
} catch ({ message, ...rest }) {
throw new Error(message);
}
// Cause error is being shadowed by a closer scoped redeclaration.
try {
doSomething();
} catch (error) {
if (whatever) {
const error = anotherError; // This declaration is the problem.
throw new Error("Something went wrong", { cause: error });
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint preserve-caught-error: "error" */
try {
// ...
} catch (error) {
throw new Error("Something went wrong", { cause: error });
}
// When the thrown error is not directly related to the caught error.
try {
} catch (error) {
foo = {
bar() {
// This throw is not directly related to the caught error.
throw new Error("Something went wrong");
}
};
}
// No throw inside catch
try {
doSomething();
} catch (e) {
console.error(e);
}
// Ignoring the caught error at the parameter level
// This is valid by default, but this behavior can be changed
// by using the `requireCatchParameter` option discussed below.
try {
doSomething();
} catch {
throw new TypeError("Something went wrong");
}
```
:::
## Options
This rule takes a single option — an object with the following optional property:
- `requireCatchParameter`: Requires the catch blocks to always have the caught error parameter when set to `true`. By default, this is `false`.
### requireCatchParameter
Enabling this option mandates for all the catch blocks to have a caught error parameter. This makes sure that the caught error is not discarded at the parameter level.
```js
"preserve-caught-error": ["error", {
"requireCatchParameter": true
}]
```
Example of **incorrect** code for the `{ "requireCatchParameter": true }` option:
::: incorrect
```js
/* eslint preserve-caught-error: ["error", { "requireCatchParameter": true }] */
try {
doSomething();
} catch { // Can't discard the error ❌
throw new Error("Something went wrong");
}
```
:::
Example of **correct** code for the `{ "requireCatchParameter": true }` option:
::: correct
```js
/* eslint preserve-caught-error: ["error", { "requireCatchParameter": true }] */
try {
doSomething();
} catch(error) { // Error is being referenced ✅
// Handling and re-throw logic
}
```
:::
## When Not To Use It
You might not want to enable this rule if:
- You follow a custom error-handling approach where the original error is intentionally omitted from re-thrown errors (e.g., to avoid exposing internal details or to log the original error separately).
- You use a third-party or internal error-handling library that preserves error context using non-standard properties (e.g., [verror](https://www.npmjs.com/package/verror)) instead of the cause option.
- (In rare cases) you are targeting legacy environments where the cause option in `Error` constructors is not supported.
---
---
title: quote-props
rule_type: suggestion
further_reading:
- https://kangax.github.io/compat-table/es5/#Reserved_words_as_property_names
- https://mathiasbynens.be/notes/javascript-properties
---
Object literal property names can be defined in two ways: using literals or using strings. For example, these two objects are equivalent:
```js
var object1 = {
property: true
};
var object2 = {
"property": true
};
```
In many cases, it doesn't matter if you choose to use an identifier instead of a string or vice-versa. Even so, you might decide to enforce a consistent style in your code.
There are, however, some occasions when you must use quotes:
1. If you are using an ECMAScript 3 JavaScript engine (such as IE8) and you want to use a keyword (such as `if`) as a property name. This restriction was removed in ECMAScript 5.
2. You want to use a non-identifier character in your property name, such as having a property with a space like `"one two"`.
Another example where quotes do matter is when using numeric literals as property keys:
```js
var object = {
1e2: 1,
100: 2
};
```
This may look alright at first sight, but this code in fact throws a syntax error in ECMAScript 5 strict mode. This happens because `1e2` and `100` are coerced into strings before getting used as the property name. Both `String(1e2)` and `String(100)` happen to be equal to `"100"`, which causes the "Duplicate data property in object literal not allowed in strict mode" error. Issues like that can be tricky to debug, so some prefer to require quotes around all property names.
## Rule Details
This rule requires quotes around object literal property names.
## Options
This rule has two options, a string option and an object option.
String option:
* `"always"` (default) requires quotes around all object literal property names
* `"as-needed"` disallows quotes around object literal property names that are not strictly required
* `"consistent"` enforces a consistent quote style; in a given object, either all of the properties should be quoted, or none of the properties should be quoted
* `"consistent-as-needed"` requires quotes around all object literal property names if any name strictly requires quotes, otherwise disallows quotes around object property names
Object option:
* `"keywords": true` requires quotes around language keywords used as object property names (only applies when using `as-needed` or `consistent-as-needed`)
* `"unnecessary": true` (default) disallows quotes around object literal property names that are not strictly required (only applies when using `as-needed`)
* `"unnecessary": false` allows quotes around object literal property names that are not strictly required (only applies when using `as-needed`)
* `"numbers": true` requires quotes around numbers used as object property names (only applies when using `as-needed`)
### always
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint quote-props: ["error", "always"]*/
var object = {
foo: "bar",
baz: 42
};
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint quote-props: ["error", "always"]*/
var object1 = {
"foo": "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
'foo': 'bar',
'baz': 42,
'qux-lorem': true
};
var object3 = {
foo() {
return;
}
};
```
:::
### as-needed
Examples of **incorrect** code for this rule with the `"as-needed"` option:
::: incorrect
```js
/*eslint quote-props: ["error", "as-needed"]*/
var object = {
"a": 0,
"0": 0,
"true": 0,
"null": 0
};
```
:::
Examples of **correct** code for this rule with the `"as-needed"` option:
::: correct
```js
/*eslint quote-props: ["error", "as-needed"]*/
var object1 = {
"a-b": 0,
"0x0": 0,
"1e2": 0
};
var object2 = {
foo: 'bar',
baz: 42,
true: 0,
0: 0,
'qux-lorem': true
};
var object3 = {
foo() {
return;
}
};
```
:::
### consistent
Examples of **incorrect** code for this rule with the `"consistent"` option:
::: incorrect
```js
/*eslint quote-props: ["error", "consistent"]*/
var object1 = {
foo: "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
'foo': 'bar',
baz: 42
};
```
:::
Examples of **correct** code for this rule with the `"consistent"` option:
::: correct
```js
/*eslint quote-props: ["error", "consistent"]*/
var object1 = {
"foo": "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
'foo': 'bar',
'baz': 42
};
var object3 = {
foo: 'bar',
baz: 42
};
```
:::
### consistent-as-needed
Examples of **incorrect** code for this rule with the `"consistent-as-needed"` option:
::: incorrect
```js
/*eslint quote-props: ["error", "consistent-as-needed"]*/
var object1 = {
foo: "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
'foo': 'bar',
'baz': 42
};
```
:::
Examples of **correct** code for this rule with the `"consistent-as-needed"` option:
::: correct
```js
/*eslint quote-props: ["error", "consistent-as-needed"]*/
var object1 = {
"foo": "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
foo: 'bar',
baz: 42
};
```
:::
### keywords
Examples of additional **incorrect** code for this rule with the `"as-needed", { "keywords": true }` options:
::: incorrect
```js
/*eslint quote-props: ["error", "as-needed", { "keywords": true }]*/
var x = {
while: 1,
volatile: "foo"
};
```
:::
Examples of additional **incorrect** code for this rule with the `"consistent-as-needed", { "keywords": true }` options:
::: incorrect
```js
/*eslint quote-props: ["error", "consistent-as-needed", { "keywords": true }]*/
var x = {
"prop": 1,
"bar": "foo"
};
```
:::
### unnecessary
Examples of additional **correct** code for this rule with the `"as-needed", { "unnecessary": false }` options:
::: correct
```js
/*eslint quote-props: ["error", "as-needed", { "keywords": true, "unnecessary": false }]*/
var x = {
"while": 1,
"foo": "bar" // Would normally have caused a warning
};
```
:::
### numbers
Examples of additional **incorrect** code for this rule with the `"as-needed", { "numbers": true }` options:
::: incorrect
```js
/*eslint quote-props: ["error", "as-needed", { "numbers": true }]*/
var x = {
100: 1
}
```
:::
## When Not To Use It
If you don't care if property names are consistently wrapped in quotes or not, and you don't target legacy ES3 environments, turn this rule off.
---
---
title: quotes
rule_type: layout
---
JavaScript allows you to define strings in one of three ways: double quotes, single quotes, and backticks (as of ECMAScript 6). For example:
```js
var double = "double";
var single = 'single';
var backtick = `backtick`; // ES6 only
```
Each of these lines creates a string and, in some cases, can be used interchangeably. The choice of how to define strings in a codebase is a stylistic one outside of template literals (which allow embedded expressions to be interpreted).
Many codebases require strings to be defined in a consistent manner.
## Rule Details
This rule enforces the consistent use of either backticks, double, or single quotes.
This rule is aware of directive prologues such as `"use strict"` and will not flag or autofix them if doing so will change how the directive prologue is interpreted.
## Options
This rule has two options, a string option and an object option.
String option:
* `"double"` (default) requires the use of double quotes wherever possible
* `"single"` requires the use of single quotes wherever possible
* `"backtick"` requires the use of backticks wherever possible
Object option:
* `"avoidEscape": true` allows strings to use single-quotes or double-quotes so long as the string contains a quote that would have to be escaped otherwise
* `"allowTemplateLiterals": true` allows strings to use backticks
**Deprecated**: The object property `avoid-escape` is deprecated; please use the object property `avoidEscape` instead.
### double
Examples of **incorrect** code for this rule with the default `"double"` option:
::: incorrect
```js
/*eslint quotes: ["error", "double"]*/
var single = 'single';
var unescaped = 'a string containing "double" quotes';
var backtick = `back\ntick`; // you can use \n in single or double quoted strings
```
:::
Examples of **correct** code for this rule with the default `"double"` option:
::: correct
```js
/*eslint quotes: ["error", "double"]*/
var double = "double";
var backtick = `back
tick`; // backticks are allowed due to newline
var backtick = tag`backtick`; // backticks are allowed due to tag
```
:::
### single
Examples of **incorrect** code for this rule with the `"single"` option:
::: incorrect
```js
/*eslint quotes: ["error", "single"]*/
var double = "double";
var unescaped = "a string containing 'single' quotes";
```
:::
Examples of **correct** code for this rule with the `"single"` option:
::: correct
```js
/*eslint quotes: ["error", "single"]*/
var single = 'single';
var backtick = `back${x}tick`; // backticks are allowed due to substitution
```
:::
### backticks
Examples of **incorrect** code for this rule with the `"backtick"` option:
::: incorrect
```js
/*eslint quotes: ["error", "backtick"]*/
var single = 'single';
var double = "double";
var unescaped = 'a string containing `backticks`';
```
:::
Examples of **correct** code for this rule with the `"backtick"` option:
::: correct
```js
/*eslint quotes: ["error", "backtick"]*/
"use strict"; // directives must use single or double quotes
var backtick = `backtick`;
var obj = { 'prop-name': `value` }; // backticks not allowed for property names
```
:::
### avoidEscape
Examples of additional **correct** code for this rule with the `"double", { "avoidEscape": true }` options:
::: correct
```js
/*eslint quotes: ["error", "double", { "avoidEscape": true }]*/
var single = 'a string containing "double" quotes';
```
:::
Examples of additional **correct** code for this rule with the `"single", { "avoidEscape": true }` options:
::: correct
```js
/*eslint quotes: ["error", "single", { "avoidEscape": true }]*/
var double = "a string containing 'single' quotes";
```
:::
Examples of additional **correct** code for this rule with the `"backtick", { "avoidEscape": true }` options:
::: correct
```js
/*eslint quotes: ["error", "backtick", { "avoidEscape": true }]*/
var double = "a string containing `backtick` quotes"
```
:::
### allowTemplateLiterals
Examples of additional **correct** code for this rule with the `"double", { "allowTemplateLiterals": true }` options:
::: correct
```js
/*eslint quotes: ["error", "double", { "allowTemplateLiterals": true }]*/
var double = "double";
var double = `double`;
```
:::
Examples of additional **correct** code for this rule with the `"single", { "allowTemplateLiterals": true }` options:
::: correct
```js
/*eslint quotes: ["error", "single", { "allowTemplateLiterals": true }]*/
var single = 'single';
var single = `single`;
```
:::
`{ "allowTemplateLiterals": false }` will not disallow the usage of all template literals. If you want to forbid any instance of template literals, use [no-restricted-syntax](no-restricted-syntax) and target the `TemplateLiteral` selector.
## When Not To Use It
If you do not need consistency in your string styles, you can safely disable this rule.
---
---
title: radix
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
- https://davidwalsh.name/parseint-radix
---
When using the `parseInt()` function it is common to omit the second argument, the radix, and let the function try to determine from the first argument what type of number it is. By default, `parseInt()` will autodetect decimal and hexadecimal (via `0x` prefix). Prior to ECMAScript 5, `parseInt()` also autodetected octal literals, which caused problems because many developers assumed a leading `0` would be ignored.
This confusion led to the suggestion that you always use the radix parameter to `parseInt()` to eliminate unintended consequences. So instead of doing this:
```js
const num = parseInt("071"); // 57
```
Do this:
```js
const num = parseInt("071", 10); // 71
```
ECMAScript 5 changed the behavior of `parseInt()` so that it no longer autodetects octal literals and instead treats them as decimal literals. However, the differences between hexadecimal and decimal interpretation of the first parameter causes many developers to continue using the radix parameter to ensure the string is interpreted in the intended way.
## Rule Details
This rule is aimed at preventing the unintended conversion of a string to a number of a different base than intended.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint radix: "error"*/
const num = parseInt("071");
const num1 = parseInt(someValue);
const num2 = parseInt("071", "abc");
const num3 = parseInt("071", 37);
const num4 = parseInt();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint radix: "error"*/
const num = parseInt("071", 10);
const num1 = parseInt("071", 8);
const num2 = parseFloat(someValue);
```
:::
## Options
**Deprecated:** String options `"always"` and `"as-needed"` are deprecated. Setting either of these options doesn't change the behavior of this rule, which now always enforces providing a radix, as it was the case when the `"always"` option was specified. Since the default radix depends on the first argument of `parseInt()`, this rule assumes that the second argument (the radix) is always needed.
## When Not To Use It
If you want to use the default behavior of the `parseInt()` function when the radix argument is not specified, you can turn this rule off.
---
---
title: require-atomic-updates
rule_type: problem
---
When writing asynchronous code, it is possible to create subtle race condition bugs. Consider the following example:
```js
let totalLength = 0;
async function addLengthOfSinglePage(pageNum) {
totalLength += await getPageLength(pageNum);
}
Promise.all([addLengthOfSinglePage(1), addLengthOfSinglePage(2)]).then(() => {
console.log('The combined length of both pages is', totalLength);
});
```
This code looks like it will sum the results of calling `getPageLength(1)` and `getPageLength(2)`, but in reality the final value of `totalLength` will only be the length of one of the two pages. The bug is in the statement `totalLength += await getPageLength(pageNum);`. This statement first reads an initial value of `totalLength`, then calls `getPageLength(pageNum)` and waits for that Promise to fulfill. Finally, it sets the value of `totalLength` to the sum of `await getPageLength(pageNum)` and the *initial* value of `totalLength`. If the `totalLength` variable is updated in a separate function call during the time that the `getPageLength(pageNum)` Promise is pending, that update will be lost because the new value is overwritten without being read.
One way to fix this issue would be to ensure that `totalLength` is read at the same time as it's updated, like this:
```js
async function addLengthOfSinglePage(pageNum) {
const lengthOfThisPage = await getPageLength(pageNum);
totalLength += lengthOfThisPage;
}
```
Another solution would be to avoid using a mutable variable reference at all:
```js
Promise.all([getPageLength(1), getPageLength(2)]).then(pageLengths => {
const totalLength = pageLengths.reduce((accumulator, length) => accumulator + length, 0);
console.log('The combined length of both pages is', totalLength);
});
```
## Rule Details
This rule aims to report assignments to variables or properties in cases where the assignments may be based on outdated values.
### Variables
This rule reports an assignment to a variable when it detects the following execution flow in a generator or async function:
1. The variable is read.
2. A `yield` or `await` pauses the function.
3. After the function is resumed, a value is assigned to the variable from step 1.
The assignment in step 3 is reported because it may be incorrectly resolved because the value of the variable from step 1 may have changed between steps 2 and 3. In particular, if the variable can be accessed from other execution contexts (for example, if it is not a local variable and therefore other functions can change it), the value of the variable may have changed elsewhere while the function was paused in step 2.
Note that the rule does not report the assignment in step 3 in any of the following cases:
* If the variable is read again between steps 2 and 3.
* If the variable cannot be accessed while the function is paused (for example, if it's a local variable).
Examples of **incorrect** code for this rule:
::: incorrect
```js
/* eslint require-atomic-updates: error */
let result;
async function foo() {
result += await something;
}
async function bar() {
result = result + await something;
}
async function baz() {
result = result + doSomething(await somethingElse);
}
async function qux() {
if (!result) {
result = await initialize();
}
}
function* generator() {
result += yield;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/* eslint require-atomic-updates: error */
let result;
async function foobar() {
result = await something + result;
}
async function baz() {
const tmp = doSomething(await somethingElse);
result += tmp;
}
async function qux() {
if (!result) {
const tmp = await initialize();
if (!result) {
result = tmp;
}
}
}
async function quux() {
let localVariable = 0;
localVariable += await something;
}
function* generator() {
result = (yield) + result;
}
```
:::
### Properties
This rule reports an assignment to a property through a variable when it detects the following execution flow in a generator or async function:
1. The variable or object property is read.
2. A `yield` or `await` pauses the function.
3. After the function is resumed, a value is assigned to a property.
This logic is similar to the logic for variables, but stricter because the property in step 3 doesn't have to be the same as the property in step 1. It is assumed that the flow depends on the state of the object as a whole.
Example of **incorrect** code for this rule:
::: incorrect
```js
/* eslint require-atomic-updates: error */
async function foo(obj) {
if (!obj.done) {
obj.something = await getSomething();
}
}
```
:::
Example of **correct** code for this rule:
::: correct
```js
/* eslint require-atomic-updates: error */
async function foo(obj) {
if (!obj.done) {
const tmp = await getSomething();
if (!obj.done) {
obj.something = tmp;
}
}
}
```
:::
## Options
This rule has an object option:
* `"allowProperties"`: When set to `true`, the rule does not report assignments to properties. Default is `false`.
### allowProperties
Example of **correct** code for this rule with the `{ "allowProperties": true }` option:
::: correct
```js
/* eslint require-atomic-updates: ["error", { "allowProperties": true }] */
async function foo(obj) {
if (!obj.done) {
obj.something = await getSomething();
}
}
```
:::
## When Not To Use It
If you don't use async or generator functions, you don't need to enable this rule.
---
---
title: require-await
rule_type: suggestion
related_rules:
- require-yield
---
Asynchronous functions in JavaScript behave differently than other functions in two important ways:
1. The return value is always a `Promise`.
2. You can use the `await` operator inside of them.
The primary reason to use asynchronous functions is typically to use the `await` operator, such as this:
```js
async function fetchData(processDataItem) {
const response = await fetch(DATA_URL);
const data = await response.json();
return data.map(processDataItem);
}
```
Asynchronous functions that don't use `await` might not need to be asynchronous functions and could be the unintentional result of refactoring.
Note: this rule ignores async generator functions. This is because generators yield rather than return a value and async generators might yield all the values of another async generator without ever actually needing to use await.
## Rule Details
This rule warns async functions which have no `await` expression.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint require-await: "error"*/
async function foo() {
doSomething();
}
bar(async () => {
doSomething();
});
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint require-await: "error"*/
async function foo() {
await doSomething();
}
bar(async () => {
await doSomething();
});
function baz() {
doSomething();
}
bar(() => {
doSomething();
});
async function resourceManagement() {
await using resource = getAsyncResource();
resource.use();
}
// Allow empty functions.
async function noop() {}
```
:::
## Options
This rule has no options.
## When Not To Use It
Asynchronous functions are designed to work with promises such that throwing an error will cause a promise's rejection handler (such as `catch()`) to be called. For example:
```js
async function fail() {
throw new Error("Failure!");
}
fail().catch(error => {
console.log(error.message);
});
```
In this case, the `fail()` function throws an error that is intended to be caught by the `catch()` handler assigned later. Converting the `fail()` function into a synchronous function would require the call to `fail()` to be refactored to use a `try-catch` statement instead of a promise.
If you are throwing an error inside of an asynchronous function for this purpose, then you may want to disable this rule.
---
---
title: require-jsdoc
rule_type: suggestion
related_rules:
- valid-jsdoc
---
:::important
This rule was removed in ESLint v9.0.0 and replaced by the [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc) equivalent.
:::
[JSDoc](http://usejsdoc.org) is a JavaScript API documentation generator. It uses specially-formatted comments inside of code to generate API documentation automatically. For example, this is what a JSDoc comment looks like for a function:
```js
/**
* Adds two numbers together.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
* @returns {number} The sum of the two numbers.
*/
function sum(num1, num2) {
return num1 + num2;
}
```
Some style guides require JSDoc comments for all functions as a way of explaining function behavior.
## Rule Details
This rule requires JSDoc comments for specified nodes. Supported nodes:
* `"FunctionDeclaration"`
* `"ClassDeclaration"`
* `"MethodDefinition"`
* `"ArrowFunctionExpression"`
* `"FunctionExpression"`
## Options
This rule has a single object option:
* `"require"` requires JSDoc comments for the specified nodes
Default option settings are:
```json
{
"require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": false,
"ClassDeclaration": false,
"ArrowFunctionExpression": false,
"FunctionExpression": false
}
}]
}
```
### require
Examples of **incorrect** code for this rule with the `{ "require": { "FunctionDeclaration": true, "MethodDefinition": true, "ClassDeclaration": true, "ArrowFunctionExpression": true, "FunctionExpression": true } }` option:
::: incorrect
```js
/*eslint "require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": true,
"ClassDeclaration": true,
"ArrowFunctionExpression": true,
"FunctionExpression": true
}
}]*/
function foo() {
return 10;
}
var bar = () => {
return 10;
};
class Foo {
bar() {
return 10;
}
}
var bar = function() {
return 10;
};
var bar = {
bar: function() {
return 10;
},
baz() {
return 10;
}
};
```
:::
Examples of **correct** code for this rule with the `{ "require": { "FunctionDeclaration": true, "MethodDefinition": true, "ClassDeclaration": true, "ArrowFunctionExpression": true, "FunctionExpression": true } }` option:
::: correct
```js
/*eslint "require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": true,
"ClassDeclaration": true,
"ArrowFunctionExpression": true,
"FunctionExpression": true
}
}]*/
/**
* It returns 10
*/
function foo() {
return 10;
}
/**
* It returns test + 10
* @params {number} test - some number
* @returns {number} sum of test and 10
*/
var bar = (test) => {
return test + 10;
}
/**
* It returns 10
*/
var bar = () => {
return 10;
}
/**
* It returns 10
*/
var bar = function() {
return 10;
}
var array = [1,2,3];
array.filter(function(item) {
return item > 2;
});
/**
* A class that can return the number 10
*/
class Foo {
/**
* It returns 10
*/
bar() {
return 10;
}
}
/**
* It returns 10
*/
var bar = function() {
return 10;
};
var bar = {
/**
* It returns 10
*/
bar: function() {
return 10;
},
/**
* It returns 10
*/
baz() {
return 10;
}
};
setTimeout(() => {}, 10); // since it's an anonymous arrow function
```
:::
## When Not To Use It
If you do not require JSDoc for your functions, then you can leave this rule off.
---
---
title: require-unicode-regexp
rule_type: suggestion
further_reading:
- https://github.com/tc39/proposal-regexp-v-flag
- https://v8.dev/features/regexp-v-flag
---
RegExp `u` flag has two effects:
1. **Make the regular expression handling UTF-16 surrogate pairs correctly.**
Especially, character range syntax gets the correct behavior.
```js
/^[👍]$/.test("👍") //→ false
/^[👍]$/u.test("👍") //→ true
```
2. **Make the regular expression throwing syntax errors early as disabling [Annex B extensions](https://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns).**
Because of historical reason, JavaScript regular expressions are tolerant of syntax errors. For example, `/\w{1, 2/` is a syntax error, but JavaScript doesn't throw the error. It matches strings such as `"a{1, 2"` instead. Such a recovering logic is defined in Annex B.
The `u` flag disables the recovering logic Annex B defined. As a result, you can find errors early. This is similar to [the strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode).
The RegExp `v` flag, introduced in ECMAScript 2024, is a superset of the `u` flag, and offers two more features:
1. **Unicode properties of strings**
With the Unicode property escape, you can use properties of strings.
```js
const re = /^\p{RGI_Emoji}$/v;
// Match an emoji that consists of just 1 code point:
re.test('⚽'); // '\u26BD'
// → true ✅
// Match an emoji that consists of multiple code points:
re.test('👨🏾⚕️'); // '\u{1F468}\u{1F3FE}\u200D\u2695\uFE0F'
// → true ✅
```
2. **Set notation**
It allows for set operations between character classes.
```js
const re = /[\p{White_Space}&&\p{ASCII}]/v;
re.test('\n'); // → true
re.test('\u2028'); // → false
```
Therefore, the `u` and `v` flags let us work better with regular expressions.
## Rule Details
This rule aims to enforce the use of `u` or `v` flag on regular expressions.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint require-unicode-regexp: error */
const a = /aaa/
const b = /bbb/gi
const c = new RegExp("ccc")
const d = new RegExp("ddd", "gi")
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint require-unicode-regexp: error */
const a = /aaa/u
const b = /bbb/giu
const c = new RegExp("ccc", "u")
const d = new RegExp("ddd", "giu")
const e = /aaa/v
const f = /bbb/giv
const g = new RegExp("ccc", "v")
const h = new RegExp("ddd", "giv")
// This rule ignores RegExp calls if the flags could not be evaluated to a static value.
function i(flags) {
return new RegExp("eee", flags)
}
```
:::
## Options
This rule has one object option:
* `"requireFlag": "u"|"v"` requires a particular Unicode regex flag
### requireFlag: "u"
The `u` flag may be preferred in environments that do not support the `v` flag.
Examples of **incorrect** code for this rule with the `{ "requireFlag": "u" }` option:
:::incorrect
```js
/*eslint require-unicode-regexp: ["error", { "requireFlag": "u" }] */
const fooEmpty = /foo/;
const fooEmptyRegexp = new RegExp('foo');
const foo = /foo/v;
const fooRegexp = new RegExp('foo', 'v');
```
:::
Examples of **correct** code for this rule with the `{ "requireFlag": "u" }` option:
:::correct
```js
/*eslint require-unicode-regexp: ["error", { "requireFlag": "u" }] */
const foo = /foo/u;
const fooRegexp = new RegExp('foo', 'u');
```
:::
### requireFlag: "v"
The `v` flag may be a better choice when it is supported because it has more
features than the `u` flag (e.g., the ability to test Unicode properties of strings). It
does have a stricter syntax, however (e.g., the need to escape certain
characters within character classes).
Examples of **incorrect** code for this rule with the `{ "requireFlag": "v" }` option:
:::incorrect
```js
/*eslint require-unicode-regexp: ["error", { "requireFlag": "v" }] */
const fooEmpty = /foo/;
const fooEmptyRegexp = new RegExp('foo');
const foo = /foo/u;
const fooRegexp = new RegExp('foo', 'u');
```
:::
Examples of **correct** code for this rule with the `{ "requireFlag": "v" }` option:
:::correct
```js
/*eslint require-unicode-regexp: ["error", { "requireFlag": "v" }] */
const foo = /foo/v;
const fooRegexp = new RegExp('foo', 'v');
```
:::
## When Not To Use It
If you don't want to warn on regular expressions without either a `u` or a `v` flag, then it's safe to disable this rule.
### Note on `i` flag and `\w`
In some cases, adding the `u` flag to a regular expression using both the `i` flag and the `\w` character class can change its behavior due to Unicode case folding.
For example:
```js
const regexWithoutU = /^\w+$/i;
const regexWithU = /^\w+$/iu;
const str = "\u017f\u212a"; // Example Unicode characters
console.log(regexWithoutU.test(str)); // false
console.log(regexWithU.test(str)); // true
```
If you prefer to use a non-Unicode-aware regex in this specific case, you can disable this rule using an `eslint-disable` comment:
```js
/* eslint-disable require-unicode-regexp */
const regex = /^\w+$/i;
/* eslint-enable require-unicode-regexp */
```
---
---
title: require-yield
rule_type: suggestion
related_rules:
- require-await
---
## Rule Details
This rule generates warnings for generator functions that do not have the `yield` keyword.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint require-yield: "error"*/
function* foo() {
return 10;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint require-yield: "error"*/
function* foo() {
yield 5;
return 10;
}
function bar() {
return 10;
}
// This rule does not warn on empty generator functions.
function* baz() { }
```
:::
## Options
This rule has no options.
## When Not To Use It
If you don't want to notify generator functions that have no `yield` expression, then it's safe to disable this rule.
---
---
title: rest-spread-spacing
rule_type: layout
further_reading:
- https://github.com/tc39/proposal-object-rest-spread
---
ES2015 introduced the rest and spread operators, which expand an iterable structure into its individual parts. Some examples of their usage are as follows:
```js
let numArr = [1, 2, 3];
function add(a, b, c) {
return a + b + c;
}
add(...numArr); // -> 6
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
arr1.push(...arr2); // -> [1, 2, 3, 4, 5, 6]
let [a, b, ...arr] = [1, 2, 3, 4, 5];
a; // -> 1
b // -> 2
arr; // -> [3, 4, 5]
function numArgs(...args) {
return args.length;
}
numArgs(a, b, c); // -> 3
```
In addition to the above, there is currently a proposal to add object rest and spread properties to the spec. They can be used as follows:
```js
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // -> 1
y; // -> 2
z; // -> { a: 3, b: 4 }
let n = { x, y, ...z };
n; // -> { x: 1, y: 2, a: 3, b: 4 }
```
As with other operators, whitespace is allowed between the rest or spread operator and the expression it is operating on, which can lead to inconsistent spacing within a codebase.
## Rule Details
This rule aims to enforce consistent spacing between rest and spread operators and their expressions. The rule also supports object rest and spread properties in ES2018:
```json
{
"languageOptions": {
"ecmaVersion": 2018
}
}
```
Please read the user guide's section on [configuring parser options](../use/configure#specifying-parser-options) to learn more.
## Options
This rule takes one option: a string with the value of `"never"` or `"always"`. The default value is `"never"`.
### "never"
When using the default `"never"` option, whitespace is not allowed between spread operators and their expressions.
```json
rest-spread-spacing: ["error"]
```
or
```json
rest-spread-spacing: ["error", "never"]
```
Examples of **incorrect** code for this rule with `"never"`:
::: incorrect
```js
/*eslint rest-spread-spacing: ["error", "never"]*/
fn(... args);
[... arr, 4, 5, 6];
let [a, b, ... arr] = [1, 2, 3, 4, 5];
function fn(... args) { console.log(args); }
let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ... z };
```
:::
Examples of **correct** code for this rule with `"never"`:
::: correct
```js
/*eslint rest-spread-spacing: ["error", "never"]*/
fn(...args);
[...arr, 4, 5, 6];
let [a, b, ...arr] = [1, 2, 3, 4, 5];
function fn(...args) { console.log(args); }
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ...z };
```
:::
### "always"
When using the `"always"` option, whitespace is required between spread operators and their expressions.
```json
rest-spread-spacing: ["error", "always"]
```
Examples of **incorrect** code for this rule with `"always"`:
::: incorrect
```js
/*eslint rest-spread-spacing:["error", "always"]*/
fn(...args);
[...arr, 4, 5, 6];
let [a, b, ...arr] = [1, 2, 3, 4, 5];
function fn(...args) { console.log(args); }
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ...z };
```
:::
Examples of **correct** code for this rule with `"always"`:
::: correct
```js
/*eslint rest-spread-spacing: ["error", "always"]*/
fn(... args);
[... arr, 4, 5, 6];
let [a, b, ... arr] = [1, 2, 3, 4, 5];
function fn(... args) { console.log(args); }
let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ... z };
```
:::
## When Not To Use It
You can safely disable this rule if you do not care about enforcing consistent spacing between spread operators and their expressions.
---
---
title: semi-spacing
rule_type: layout
related_rules:
- semi
- no-extra-semi
- comma-spacing
- block-spacing
- space-in-parens
---
JavaScript allows you to place unnecessary spaces before or after a semicolon.
Disallowing or enforcing space around a semicolon can improve the readability of your program.
```js
var a = "b" ;
var c = "d";var e = "f";
```
## Rule Details
This rule aims to enforce spacing around a semicolon. This rule prevents the use of spaces before a semicolon in expressions.
This rule doesn't check spacing in the following cases:
* The spacing after the semicolon if it is the first token in the line.
* The spacing before the semicolon if it is after an opening parenthesis (`(` or `{`), or the spacing after the semicolon if it is before a closing parenthesis (`)` or `}`). That spacing is checked by `space-in-parens` or `block-spacing`.
* The spacing around the semicolon in a for loop with an empty condition (`for(;;)`).
## Options
The rule takes one option, an object, which has two keys `before` and `after` having boolean values `true` or `false`.
If `before` is `true`, space is enforced before semicolons and if it's `false`, space is disallowed before semicolons.
If `after` is `true`, space is enforced after semicolons and if it's `false`, space is disallowed after semicolons.
The `after` option will be only applied if a semicolon is not at the end of line.
The default is `{"before": false, "after": true}`.
```json
"semi-spacing": ["error", {"before": false, "after": true}]
```
### `{"before": false, "after": true}`
This is the default option. It enforces spacing after semicolons and disallows spacing before semicolons.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint semi-spacing: "error"*/
var foo ;
var foo;var bar;
throw new Error("error") ;
while (a) { break ; }
for (i = 0 ; i < 10 ; i++) {}
for (i = 0;i < 10;i++) {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint semi-spacing: "error"*/
var foo;
var foo; var bar;
throw new Error("error");
while (a) { break; }
for (i = 0; i < 10; i++) {}
for (;;) {}
if (true) {;}
;foo();
```
:::
### `{"before": true, "after": false}`
This option enforces spacing before semicolons and disallows spacing after semicolons.
Examples of **incorrect** code for this rule with the `{"before": true, "after": false}` option:
::: incorrect
```js
/*eslint semi-spacing: ["error", { "before": true, "after": false }]*/
var foo;
var foo ; var bar;
throw new Error("error");
while (a) { break; }
for (i = 0;i < 10;i++) {}
for (i = 0; i < 10; i++) {}
```
:::
Examples of **correct** code for this rule with the `{"before": true, "after": false}` option:
::: correct
```js
/*eslint semi-spacing: ["error", { "before": true, "after": false }]*/
var foo ;
var foo ;var bar ;
throw new Error("error") ;
while (a) {break ;}
for (i = 0 ;i < 10 ;i++) {}
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing before or after semicolons.
---
---
title: semi-style
rule_type: layout
related_rules:
- no-extra-semi
- semi
- semi-spacing
---
Generally, semicolons are at the end of lines. However, in semicolon-less style, semicolons are at the beginning of lines. This rule enforces that semicolons are at the configured location.
## Rule Details
This rule reports line terminators around semicolons.
This rule has an option.
```json
{
"semi-style": ["error", "last"],
}
```
* `"last"` (Default) enforces that semicolons are at the end of statements.
* `"first"` enforces that semicolons are at the beginning of statements. Semicolons of `for` loop heads (`for(a;b;c){}`) should be at the end of lines even if you use this option.
Examples of **incorrect** code for this rule with `"last"` option:
::: incorrect
```js
/*eslint semi-style: ["error", "last"]*/
foo()
;[1, 2, 3].forEach(bar)
for (
var i = 0
; i < 10
; ++i
) {
foo()
}
class C {
static {
foo()
;bar()
}
}
```
:::
Examples of **correct** code for this rule with `"last"` option:
::: correct
```js
/*eslint semi-style: ["error", "last"]*/
foo();
[1, 2, 3].forEach(bar)
for (
var i = 0;
i < 10;
++i
) {
foo()
}
class C {
static {
foo();
bar()
}
}
```
:::
Examples of **incorrect** code for this rule with `"first"` option:
::: incorrect
```js
/*eslint semi-style: ["error", "first"]*/
foo();
[1, 2, 3].forEach(bar)
for (
var i = 0
; i < 10
; ++i
) {
foo()
}
class C {
static {
foo();
bar()
}
}
```
:::
Examples of **correct** code for this rule with `"first"` option:
::: correct
```js
/*eslint semi-style: ["error", "first"]*/
foo()
;[1, 2, 3].forEach(bar)
for (
var i = 0;
i < 10;
++i
) {
foo()
}
class C {
static {
foo()
;bar()
}
}
```
:::
## When Not To Use It
If you don't want to notify the location of semicolons, then it's safe to disable this rule.
---
---
title: semi
rule_type: layout
related_rules:
- no-extra-semi
- no-unexpected-multiline
- semi-spacing
further_reading:
- https://blog.izs.me/2010/12/an-open-letter-to-javascript-leaders-regarding/
- https://web.archive.org/web/20200420230322/http://inimino.org/~inimino/blog/javascript_semicolons
---
JavaScript doesn't require semicolons at the end of each statement. In many cases, the JavaScript engine can determine that a semicolon should be in a certain spot and will automatically add it. This feature is known as **automatic semicolon insertion (ASI)** and is considered one of the more controversial features of JavaScript. For example, the following lines are both valid:
```js
var name = "ESLint"
var website = "eslint.org";
```
On the first line, the JavaScript engine will automatically insert a semicolon, so this is not considered a syntax error. The JavaScript engine still knows how to interpret the line and knows that the line end indicates the end of the statement.
In the debate over ASI, there are generally two schools of thought. The first is that we should treat ASI as if it didn't exist and always include semicolons manually. The rationale is that it's easier to always include semicolons than to try to remember when they are or are not required, and thus decreases the possibility of introducing an error.
However, the ASI mechanism can sometimes be tricky to people who are using semicolons. For example, consider this code:
```js
return
{
name: "ESLint"
};
```
This may look like a `return` statement that returns an object literal, however, the JavaScript engine will interpret this code as:
```js
return;
{
name: "ESLint";
}
```
Effectively, a semicolon is inserted after the `return` statement, causing the code below it (a labeled literal inside a block) to be unreachable. This rule and the [no-unreachable](no-unreachable) rule will protect your code from such cases.
On the other side of the argument are those who say that since semicolons are inserted automatically, they are optional and do not need to be inserted manually. However, the ASI mechanism can also be tricky to people who don't use semicolons. For example, consider this code:
```js
var globalCounter = { }
(function () {
var n = 0
globalCounter.increment = function () {
return ++n
}
})()
```
In this example, a semicolon will not be inserted after the first line, causing a run-time error (because an empty object is called as if it's a function). The [no-unexpected-multiline](no-unexpected-multiline) rule can protect your code from such cases.
Although ASI allows for more freedom over your coding style, it can also make your code behave in an unexpected way, whether you use semicolons or not. Therefore, it is best to know when ASI takes place and when it does not, and have ESLint protect your code from these potentially unexpected cases. In short, as once described by Isaac Schlueter, a `\n` character always ends a statement (just like a semicolon) unless one of the following is true:
1. The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with `.` or `,`.)
1. The line is `--` or `++` (in which case it will decrement/increment the next token.)
1. It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{`
1. The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other binary operator that can only be found between two tokens in a single expression.
## Rule Details
This rule enforces consistent use of semicolons.
## Options
This rule has two options, a string option and an object option.
String option:
* `"always"` (default) requires semicolons at the end of statements
* `"never"` disallows semicolons at the end of statements (except to disambiguate statements beginning with `[`, `(`, `/`, `+`, or `-`)
Object option (when `"always"`):
* `"omitLastInOneLineBlock": true` disallows the last semicolon in a block in which its braces (and therefore the content of the block) are in the same line
* `"omitLastInOneLineClassBody": true` disallows the last semicolon in a class body in which its braces (and therefore the content of the class body) are in the same line
Object option (when `"never"`):
* `"beforeStatementContinuationChars": "any"` (default) ignores semicolons (or lacking semicolon) at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`.
* `"beforeStatementContinuationChars": "always"` requires semicolons at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`.
* `"beforeStatementContinuationChars": "never"` disallows semicolons at the end of statements if it doesn't make ASI hazard even if the next line starts with `[`, `(`, `/`, `+`, or `-`.
**Note:** `beforeStatementContinuationChars` does not apply to class fields because class fields are not statements.
### always
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint semi: ["error", "always"]*/
var name = "ESLint"
object.method = function() {
// ...
}
class Foo {
bar = 1
}
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint semi: "error"*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
```
:::
#### omitLastInOneLineBlock
Examples of additional **correct** code for this rule with the `"always", { "omitLastInOneLineBlock": true }` options:
::: correct
```js
/*eslint semi: ["error", "always", { "omitLastInOneLineBlock": true}] */
if (foo) { bar() }
if (foo) { bar(); baz() }
function f() { bar(); baz() }
class C {
foo() { bar(); baz() }
static { bar(); baz() }
}
```
:::
#### omitLastInOneLineClassBody
Examples of additional **correct** code for this rule with the `"always", { "omitLastInOneLineClassBody": true }` options:
::: correct
```js
/*eslint semi: ["error", "always", { "omitLastInOneLineClassBody": true}] */
export class SomeClass{
logType(){
console.log(this.type);
console.log(this.anotherType);
}
}
export class Variant1 extends SomeClass{type=1}
export class Variant2 extends SomeClass{type=2; anotherType=3}
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint semi: ["error", "never"]*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint semi: ["error", "never"]*/
var name = "ESLint"
object.method = function() {
// ...
}
var name = "ESLint"
;(function() {
// ...
})()
import a from "a"
(function() {
// ...
})()
import b from "b"
;(function() {
// ...
})()
class Foo {
bar = 1
}
```
:::
#### beforeStatementContinuationChars
Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "always" }` options:
::: incorrect
```js
/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"
(function() {
// ...
})()
```
:::
Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "never" }` options:
::: incorrect
```js
/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"
;(function() {
// ...
})()
```
:::
## When Not To Use It
If you do not want to enforce semicolon usage (or omission) in any particular way, then you can turn this rule off.
---
---
title: sort-imports
rule_type: suggestion
related_rules:
- sort-keys
- sort-vars
---
The `import` statement is used to import members (functions, objects or primitives) that have been exported from an external module. Using a specific member syntax:
```js
// single - Import single member.
import myMember from "my-module.js";
import {myOtherMember} from "my-other-module.js";
// multiple - Import multiple members.
import {foo, bar} from "my-module.js";
// all - Import all members, where myModule contains all the exported bindings.
import * as myModule from "my-module.js";
```
The `import` statement can also import a module without exported bindings. Used when the module does not export anything, but runs it own code or changes the global context object.
```js
// none - Import module without exported bindings.
import "my-module.js"
```
When declaring multiple imports, a sorted list of `import` declarations make it easier for developers to read the code and find necessary imports later. This rule is purely a matter of style.
## Rule Details
This rule checks all `import` declarations and verifies that all imports are first sorted by the used member syntax and then alphabetically by the first member or alias name.
The `--fix` option on the command line automatically fixes some problems reported by this rule: multiple members on a single line are automatically sorted (e.g. `import { b, a } from 'foo.js'` is corrected to `import { a, b } from 'foo.js'`), but multiple lines are not reordered.
## Options
This rule accepts an object with its properties as
* `ignoreCase` (default: `false`)
* `ignoreDeclarationSort` (default: `false`)
* `ignoreMemberSort` (default: `false`)
* `memberSyntaxSortOrder` (default: `["none", "all", "multiple", "single"]`); all 4 items must be present in the array, but you can change the order:
* `none` = import module without exported bindings.
* `all` = import all members provided by exported bindings.
* `multiple` = import multiple members.
* `single` = import single member.
* `allowSeparatedGroups` (default: `false`)
Default option settings are:
```json
{
"sort-imports": ["error", {
"ignoreCase": false,
"ignoreDeclarationSort": false,
"ignoreMemberSort": false,
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"],
"allowSeparatedGroups": false
}]
}
```
### Default settings
Examples of **correct** code for this rule when using default options:
::: correct
```js
/*eslint sort-imports: "error"*/
import 'module-without-export.js';
import * as bar from 'bar.js';
import * as foo from 'foo.js';
import {alpha, beta} from 'alpha.js';
import {delta, gamma} from 'delta.js';
import a from 'baz.js';
import {b} from 'qux.js';
```
:::
::: correct
```js
/*eslint sort-imports: "error"*/
import a from 'foo.js';
import b from 'bar.js';
import c from 'baz.js';
```
:::
::: correct
```js
/*eslint sort-imports: "error"*/
import 'foo.js'
import * as bar from 'bar.js';
import {a, b} from 'baz.js';
import c from 'qux.js';
import {d} from 'quux.js';
```
:::
::: correct
```js
/*eslint sort-imports: "error"*/
import {a, b, c} from 'foo.js'
```
:::
Examples of **incorrect** code for this rule when using default options:
::: incorrect
```js
/*eslint sort-imports: "error"*/
import b from 'foo.js';
import a from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import a from 'foo.js';
import A from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import {c, d} from 'foo.js';
import {a, b} from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import a from 'foo.js';
import {b, c} from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import {a} from 'foo.js';
import {b, c} from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import a from 'foo.js';
import * as b from 'bar.js';
```
:::
::: incorrect
```js
/*eslint sort-imports: "error"*/
import {b, a, c} from 'foo.js'
```
:::
### `ignoreCase`
When `false` (default), uppercase letters of the alphabet must always precede lowercase letters.
When `true`, the rule ignores the case-sensitivity of the imports local name.
Examples of **incorrect** code for this rule with the default `{ "ignoreCase": false }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreCase": false }]*/
import a from 'bar.js';
import B from 'foo.js';
import c from 'baz.js';
```
:::
Examples of **correct** code for this rule with the default `{ "ignoreCase": false }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreCase": false }]*/
import B from 'bar.js';
import a from 'foo.js';
import c from 'baz.js';
```
:::
Examples of **correct** code for this rule with `{ "ignoreCase": true }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreCase": true }]*/
import a from 'bar.js';
import B from 'foo.js';
import c from 'baz.js';
```
:::
Examples of **incorrect** code for this rule with the `{ "ignoreCase": true }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreCase": true }]*/
import B from 'foo.js';
import a from 'bar.js';
```
:::
### `ignoreDeclarationSort`
When `true`, the rule ignores the sorting of import declaration statements. Default is `false`.
Examples of **incorrect** code for this rule with the default `{ "ignoreDeclarationSort": false }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreDeclarationSort": false }]*/
import b from 'foo.js'
import a from 'bar.js'
```
:::
Examples of **correct** code for this rule with the default `{ "ignoreDeclarationSort": false }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreDeclarationSort": false }]*/
import a from 'bar.js';
import b from 'foo.js';
```
:::
Examples of **correct** code for this rule with the `{ "ignoreDeclarationSort": true }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/
import b from 'foo.js'
import a from 'bar.js'
```
:::
Examples of **incorrect** code for this rule with the `{ "ignoreDeclarationSort": true }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/
import {b, a, c} from 'foo.js';
```
:::
### `ignoreMemberSort`
When `true`, the rule ignores the member sorting within a `multiple` member import declaration. Default is `false`.
Examples of **incorrect** code for this rule with the default `{ "ignoreMemberSort": false }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreMemberSort": false }]*/
import {b, a, c} from 'foo.js'
```
:::
Examples of **correct** code for this rule with the default `{ "ignoreMemberSort": false }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreMemberSort": false }]*/
import {a, b, c} from 'foo.js';
```
:::
Examples of **correct** code for this rule with the `{ "ignoreMemberSort": true }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "ignoreMemberSort": true }]*/
import {b, a, c} from 'foo.js'
```
:::
Examples of **incorrect** code for this rule with the `{ "ignoreMemberSort": true }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "ignoreMemberSort": true }]*/
import b from 'foo.js';
import a from 'bar.js';
```
:::
### `memberSyntaxSortOrder`
This option takes an array with four predefined elements, the order of elements specifies the order of import styles.
Default order is `["none", "all", "multiple", "single"]`.
There are four different styles and the default member syntax sort order is:
* `none` - import module without exported bindings.
* `all` - import all members provided by exported bindings.
* `multiple` - import multiple members.
* `single` - import single member.
All four options must be specified in the array, but you can customize their order.
Examples of **incorrect** code for this rule with the default `{ "memberSyntaxSortOrder": ["none", "all", "multiple", "single"] }` option:
::: incorrect
```js
/*eslint sort-imports: "error"*/
import a from 'foo.js';
import * as b from 'bar.js';
```
:::
Examples of **correct** code for this rule with the `{ "memberSyntaxSortOrder": ['single', 'all', 'multiple', 'none'] }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "memberSyntaxSortOrder": ['single', 'all', 'multiple', 'none'] }]*/
import a from 'foo.js';
import * as b from 'bar.js';
```
:::
Examples of **correct** code for this rule with the `{ "memberSyntaxSortOrder": ['all', 'single', 'multiple', 'none'] }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "memberSyntaxSortOrder": ['all', 'single', 'multiple', 'none'] }]*/
import * as foo from 'foo.js';
import z from 'zoo.js';
import {a, b} from 'foo.js';
```
:::
### `allowSeparatedGroups`
When `true`, the rule checks the sorting of import declaration statements only for those that appear on consecutive lines. Default is `false`.
In other words, a blank line or a comment line or line with any other statement after an import declaration statement will reset the sorting of import declaration statements.
Examples of **incorrect** code for this rule with the `{ "allowSeparatedGroups": true }` option:
::: incorrect
```js
/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/
import b from 'foo.js';
import c from 'bar.js';
import a from 'baz.js';
```
:::
Examples of **correct** code for this rule with the `{ "allowSeparatedGroups": true }` option:
::: correct
```js
/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/
import b from 'foo.js';
import c from 'bar.js';
import a from 'baz.js';
```
:::
::: correct
```js
/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/
import b from 'foo.js';
import c from 'bar.js';
// comment
import a from 'baz.js';
```
:::
::: correct
```js
/*eslint sort-imports: ["error", { "allowSeparatedGroups": true }]*/
import b from 'foo.js';
import c from 'bar.js';
quux();
import a from 'baz.js';
```
:::
## When Not To Use It
This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing imports isn't a part of your coding standards, then you can leave this rule disabled.
---
---
title: sort-keys
rule_type: suggestion
related_rules:
- sort-imports
- sort-vars
---
When declaring multiple properties, some developers prefer to sort property names alphabetically to more easily find and/or diff necessary properties at a later time. Others feel that it adds complexity and becomes burden to maintain.
## Rule Details
This rule checks all property definitions of object expressions and verifies that all variables are sorted alphabetically.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint sort-keys: "error"*/
const obj1 = {a: 1, c: 3, b: 2};
const obj2 = {a: 1, "c": 3, b: 2};
// Case-sensitive by default.
const obj3 = {a: 1, b: 2, C: 3};
// Non-natural order by default.
const obj4 = {1: a, 2: c, 10: b};
// This rule checks computed properties which have a simple name as well.
// Simple names are names which are expressed by an Identifier node or a Literal node.
const S = Symbol("s")
const obj5 = {a: 1, ["c"]: 3, b: 2};
const obj6 = {a: 1, [S]: 3, b: 2};
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint sort-keys: "error"*/
const obj1 = {a: 1, b: 2, c: 3};
const obj2 = {a: 1, "b": 2, c: 3};
// Case-sensitive by default.
const obj3 = {C: 3, a: 1, b: 2};
// Non-natural order by default.
const obj4 = {1: a, 10: b, 2: c};
// This rule checks computed properties which have a simple name as well.
const obj5 = {a: 1, ["b"]: 2, c: 3};
const obj6 = {a: 1, [b]: 2, c: 3};
// This rule ignores computed properties which have a non-simple name.
const obj7 = {a: 1, [c + d]: 3, b: 2};
const obj8 = {a: 1, ["c" + "d"]: 3, b: 2};
const obj9 = {a: 1, [`${c}`]: 3, b: 2};
const obj10 = {a: 1, [tag`c`]: 3, b: 2};
// This rule does not report unsorted properties that are separated by a spread property.
const obj11 = {b: 1, ...c, a: 2};
```
:::
## Options
```json
{
"sort-keys": ["error", "asc", {"caseSensitive": true, "natural": false, "minKeys": 2}]
}
```
The 1st option is `"asc"` or `"desc"`.
* `"asc"` (default) - enforce properties to be in ascending order.
* `"desc"` - enforce properties to be in descending order.
The 2nd option is an object which has the following properties.
* `caseSensitive` - if `true`, enforce properties to be in case-sensitive order. Default is `true`.
* `minKeys` - Specifies the minimum number of keys that an object should have in order for the object's unsorted keys to produce an error. Default is `2`, which means by default all objects with unsorted keys will result in lint errors.
* `natural` - if `true`, enforce properties to be in natural order. Default is `false`. Natural Order compares strings containing combination of letters and numbers in the way a human being would sort. It basically sorts numerically, instead of sorting alphabetically. So the number 10 comes after the number 3 in Natural Sorting.
* `allowLineSeparatedGroups` - if `true`, the rule allows to group object keys through line breaks. In other words, a blank line after a property will reset the sorting of keys. Default is `false`.
* `ignoreComputedKeys` - if `true`, the rule ignores all computed keys and doesn't report unsorted properties separated by them. A computed key will reset the sorting of the following non-computed keys. Default is `false`.
Example for a list:
With `natural` as `true`, the ordering would be
1
3
6
8
10
With `natural` as `false`, the ordering would be
1
10
3
6
8
### desc
Examples of **incorrect** code for the `"desc"` option:
::: incorrect
```js
/*eslint sort-keys: ["error", "desc"]*/
const obj1 = {b: 2, c: 3, a: 1};
const obj2 = {"b": 2, c: 3, a: 1};
// Case-sensitive by default.
const obj3 = {C: 1, b: 3, a: 2};
// Non-natural order by default.
const obj4 = {10: b, 2: c, 1: a};
```
:::
Examples of **correct** code for the `"desc"` option:
::: correct
```js
/*eslint sort-keys: ["error", "desc"]*/
const obj1 = {c: 3, b: 2, a: 1};
const obj2 = {c: 3, "b": 2, a: 1};
// Case-sensitive by default.
const obj3 = {b: 3, a: 2, C: 1};
// Non-natural order by default.
const obj4 = {2: c, 10: b, 1: a};
```
:::
### caseSensitive
Examples of **incorrect** code for the `{caseSensitive: false}` option:
::: incorrect
```js
/*eslint sort-keys: ["error", "asc", {caseSensitive: false}]*/
const obj1 = {a: 1, c: 3, C: 4, b: 2};
const obj2 = {a: 1, C: 3, c: 4, b: 2};
```
:::
Examples of **correct** code for the `{caseSensitive: false}` option:
::: correct
```js
/*eslint sort-keys: ["error", "asc", {caseSensitive: false}]*/
const obj1 = {a: 1, b: 2, c: 3, C: 4};
const obj2 = {a: 1, b: 2, C: 3, c: 4};
```
:::
### natural
Examples of **incorrect** code for the `{natural: true}` option:
::: incorrect
```js
/*eslint sort-keys: ["error", "asc", {natural: true}]*/
const obj = {1: a, 10: c, 2: b};
```
:::
Examples of **correct** code for the `{natural: true}` option:
::: correct
```js
/*eslint sort-keys: ["error", "asc", {natural: true}]*/
const obj = {1: a, 2: b, 10: c};
```
:::
### minKeys
Examples of **incorrect** code for the `{minKeys: 4}` option:
::: incorrect
```js
/*eslint sort-keys: ["error", "asc", {minKeys: 4}]*/
// 4 keys
const obj1 = {
b: 2,
a: 1, // not sorted correctly (should be 1st key)
c: 3,
d: 4,
};
// 5 keys
const obj2 = {
2: 'a',
1: 'b', // not sorted correctly (should be 1st key)
3: 'c',
4: 'd',
5: 'e',
};
```
:::
Examples of **correct** code for the `{minKeys: 4}` option:
::: correct
```js
/*eslint sort-keys: ["error", "asc", {minKeys: 4}]*/
// 3 keys
const obj1 = {
b: 2,
a: 1,
c: 3,
};
// 2 keys
const obj2 = {
2: 'b',
1: 'a',
};
```
:::
### allowLineSeparatedGroups
Examples of **incorrect** code for the `{allowLineSeparatedGroups: true}` option:
::: incorrect
```js
/*eslint sort-keys: ["error", "asc", {allowLineSeparatedGroups: true}]*/
const obj1 = {
b: 1,
c () {
},
a: 3
}
const obj2 = {
b: 1,
c: 2,
z () {
},
y: 3
}
const obj3 = {
b: 1,
c: 2,
z () {
},
// comment
y: 3,
}
const obj4 = {
b: 1
// comment before comma
, a: 2
};
```
:::
Examples of **correct** code for the `{allowLineSeparatedGroups: true}` option:
::: correct
```js
/*eslint sort-keys: ["error", "asc", {allowLineSeparatedGroups: true}]*/
const obj1 = {
e: 1,
f: 2,
g: 3,
a: 4,
b: 5,
c: 6
}
const obj2 = {
b: 1,
// comment
a: 4,
c: 5,
}
const obj3 = {
c: 1,
d: 2,
b () {
},
e: 3,
}
const obj4 = {
c: 1,
d: 2,
// comment
// comment
b() {
},
e: 4
}
const obj5 = {
b,
[foo + bar]: 1,
a
}
const obj6 = {
b: 1
// comment before comma
,
a: 2
};
const obj7 = {
b: 1,
a: 2,
...z,
c: 3
}
```
:::
### ignoreComputedKeys
Examples of **correct** code for the `{ignoreComputedKeys: true}` option:
::: correct
```js
/*eslint sort-keys: ["error", "asc", {ignoreComputedKeys: true}]*/
const obj1 = {
[b]: 1,
a: 2
}
const obj2 = {
c: 1,
[b]: 2,
a: 3
}
const obj3 = {
c: 1,
["b"]: 2,
a: 3
}
```
:::
## When Not To Use It
If you don't want to notify about properties' order, then it's safe to disable this rule.
## Compatibility
* **JSCS:** [validateOrderInObjectKeys](https://jscs-dev.github.io/rule/validateOrderInObjectKeys)
---
---
title: sort-vars
rule_type: suggestion
related_rules:
- sort-keys
- sort-imports
---
When declaring multiple variables within the same block, some developers prefer to sort variable names alphabetically to be able to find necessary variable easier at the later time. Others feel that it adds complexity and becomes burden to maintain.
## Rule Details
This rule checks all variable declaration blocks and verifies that all variables are sorted alphabetically.
The default configuration of the rule is case-sensitive.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint sort-vars: "error"*/
let b, a;
let c, D, e;
let f, F;
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint sort-vars: "error"*/
let a, b, c, d;
let _a = 10;
let _b = 20;
let E, e;
let G, f, h;
```
:::
Alphabetical list is maintained starting from the first variable and excluding any that are considered problems. So the following code will produce two problems:
```js
/*eslint sort-vars: "error"*/
let c, d, a, b;
```
But this one, will only produce one:
```js
/*eslint sort-vars: "error"*/
let c, d, a, e;
```
## Options
This rule has an object option:
* `"ignoreCase": true` (default `false`) ignores the case-sensitivity of the variables order
### ignoreCase
Examples of **correct** code for this rule with the `{ "ignoreCase": true }` option:
::: correct
```js
/*eslint sort-vars: ["error", { "ignoreCase": true }]*/
let a, A;
let c, D, e;
```
:::
## When Not To Use It
This rule is a formatting preference and not following it won't negatively affect the quality of your code. If you alphabetizing variables isn't a part of your coding standards, then you can leave this rule off.
---
---
title: space-after-function-name
---
Enforces consistent spacing after name in function definitions.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [space-before-function-paren](space-before-function-paren) rule.
:::
Whitespace between a function name and its parameter list is optional.
```js
function withoutSpace(x) {
// ...
}
function withSpace (x) {
// ...
}
```
Some style guides may require a consistent spacing for function names.
## Rule Details
This rule aims to enforce a consistent spacing after function names. It takes one argument. If it is `"always"` then all function names must be followed by at least one space. If `"never"` then there should be no spaces between the name and the parameter list. The default is `"never"`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
function foo (x) {
// ...
}
var x = function named (x) {};
// When ["error", "always"]
function bar(x) {
// ...
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
function foo(x) {
// ...
}
var x = function named(x) {};
// When ["error", "always"]
function bar (x) {
// ...
}
```
:::
---
---
title: space-after-keywords
---
Enforces consistent spacing after keywords.
:::important
This rule was removed in ESLint v2.0.0 and replaced by the [keyword-spacing](keyword-spacing) rule.
:::
Some style guides will require or disallow spaces following the certain keywords.
```js
if (condition) {
doSomething();
} else {
doSomethingElse();
}
if(condition) {
doSomething();
}else{
doSomethingElse();
}
```
## Rule Details
This rule will enforce consistency of spacing after the keywords `if`, `else`, `for`, `while`, `do`, `switch`, `try`, `catch`, `finally`, and `with`.
This rule takes one argument. If it is `"always"` then the keywords must be followed by at least one space. If `"never"`
then there should be no spaces following. The default is `"always"`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint space-after-keywords: "error"*/
if(a) {}
if (a) {} else{}
do{} while (a);
```
:::
::: incorrect
```js
/*eslint space-after-keywords: ["error", "never"]*/
if (a) {}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint space-after-keywords: "error"*/
if (a) {}
if (a) {} else {}
```
:::
::: correct
```js
/*eslint space-after-keywords: ["error", "never"]*/
if(a) {}
```
:::
---
---
title: space-before-blocks
rule_type: layout
related_rules:
- keyword-spacing
- arrow-spacing
- switch-colon-spacing
- block-spacing
- brace-style
---
Consistency is an important part of any style guide.
While it is a personal preference where to put the opening brace of blocks,
it should be consistent across a whole project.
Having an inconsistent style distracts the reader from seeing the important parts of the code.
## Rule Details
This rule will enforce consistency of spacing before blocks. It is only applied on blocks that don’t begin on a new line.
* This rule ignores spacing which is between `=>` and a block. The spacing is handled by the `arrow-spacing` rule.
* This rule ignores spacing which is between a keyword and a block. The spacing is handled by the `keyword-spacing` rule.
* This rule ignores spacing which is between `:` of a switch case and a block. The spacing is handled by the `switch-colon-spacing` rule.
## Options
This rule takes one argument. If it is `"always"` then blocks must always have at least one preceding space. If `"never"`
then all blocks should never have any preceding space. If different spacing is desired for function
blocks, keyword blocks and classes, an optional configuration object can be passed as the rule argument to
configure the cases separately. If any value in the configuration object is `"off"`, then neither style will be enforced for blocks of that kind.
( e.g. `{ "functions": "never", "keywords": "always", "classes": "always" }` )
The default is `"always"`.
### "always"
Examples of **incorrect** code for this rule with the "always" option:
::: incorrect
```js
/*eslint space-before-blocks: "error"*/
if (a){
b();
}
function a(){}
for (;;){
b();
}
try {} catch(a){}
class Foo{
constructor(){}
}
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint space-before-blocks: "error"*/
if (a) {
b();
}
if (a) {
b();
} else{ /*no error. this is checked by `keyword-spacing` rule.*/
c();
}
class C {
static{} /*no error. this is checked by `keyword-spacing` rule.*/
}
function a() {}
for (;;) {
b();
}
try {} catch(a) {}
```
:::
### "never"
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint space-before-blocks: ["error", "never"]*/
if (a) {
b();
}
function a() {}
for (;;) {
b();
}
try {} catch(a) {}
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint space-before-blocks: ["error", "never"]*/
if (a){
b();
}
function a(){}
for (;;){
b();
}
try{} catch(a){}
class Foo{
constructor(){}
}
```
:::
Examples of **incorrect** code for this rule when configured `{ "functions": "never", "keywords": "always", "classes": "never" }`:
::: incorrect
```js
/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "always", "classes": "never" }]*/
function a() {}
try {} catch(a){}
class Foo{
constructor() {}
}
```
:::
Examples of **correct** code for this rule when configured `{ "functions": "never", "keywords": "always", "classes": "never" }`:
::: correct
```js
/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "always", "classes": "never" }]*/
for (;;) {
// ...
}
describe(function(){
// ...
});
class Foo{
constructor(){}
}
```
:::
Examples of **incorrect** code for this rule when configured `{ "functions": "always", "keywords": "never", "classes": "never" }`:
::: incorrect
```js
/*eslint space-before-blocks: ["error", { "functions": "always", "keywords": "never", "classes": "never" }]*/
function a(){}
try {} catch(a) {}
class Foo {
constructor(){}
}
```
:::
Examples of **correct** code for this rule when configured `{ "functions": "always", "keywords": "never", "classes": "never" }`:
::: correct
```js
/*eslint space-before-blocks: ["error", { "functions": "always", "keywords": "never", "classes": "never" }]*/
if (a){
b();
}
var a = function() {}
class Foo{
constructor() {}
}
```
:::
Examples of **incorrect** code for this rule when configured `{ "functions": "never", "keywords": "never", "classes": "always" }`:
::: incorrect
```js
/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "never", "classes": "always" }]*/
class Foo{
constructor(){}
}
```
:::
Examples of **correct** code for this rule when configured `{ "functions": "never", "keywords": "never", "classes": "always" }`:
::: correct
```js
/*eslint space-before-blocks: ["error", { "functions": "never", "keywords": "never", "classes": "always" }]*/
class Foo {
constructor(){}
}
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing before blocks.
---
---
title: space-before-function-paren
rule_type: layout
related_rules:
- keyword-spacing
---
When formatting a function, whitespace is allowed between the function name or `function` keyword and the opening paren. Named functions also require a space between the `function` keyword and the function name, but anonymous functions require no whitespace. For example:
```js
function withoutSpace(x) {
// ...
}
function withSpace (x) {
// ...
}
var anonymousWithoutSpace = function() {};
var anonymousWithSpace = function () {};
```
Style guides may require a space after the `function` keyword for anonymous functions, while others specify no whitespace. Similarly, the space after a function name may or may not be required.
## Rule Details
This rule aims to enforce consistent spacing before function parentheses and as such, will warn whenever whitespace doesn't match the preferences specified.
## Options
This rule has a string option or an object option:
```js
{
"space-before-function-paren": ["error", "always"],
// or
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "always",
"asyncArrow": "always"
}],
}
```
* `always` (default) requires a space followed by the `(` of arguments.
* `never` disallows any space followed by the `(` of arguments.
The string option does not check async arrow function expressions for backward compatibility.
You can also use a separate option for each type of function.
Each of the following options can be set to `"always"`, `"never"`, or `"ignore"`. The default is `"always"`.
* `anonymous` is for anonymous function expressions (e.g. `function () {}`).
* `named` is for named function expressions (e.g. `function foo () {}`).
* `asyncArrow` is for async arrow function expressions (e.g. `async () => {}`).
### "always"
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint space-before-function-paren: "error"*/
function foo() {
// ...
}
var bar = function() {
// ...
};
var bar = function foo() {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
var baz = async() => 1
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
/*eslint space-before-function-paren: "error"*/
function foo () {
// ...
}
var bar = function () {
// ...
};
var bar = function foo () {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
var baz = async () => 1
```
:::
### "never"
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint space-before-function-paren: ["error", "never"]*/
function foo () {
// ...
}
var bar = function () {
// ...
};
var bar = function foo () {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
var baz = async () => 1
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint space-before-function-paren: ["error", "never"]*/
function foo() {
// ...
}
var bar = function() {
// ...
};
var bar = function foo() {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
var baz = async() => 1
```
:::
### `{"anonymous": "always", "named": "never", "asyncArrow": "always"}`
Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option:
::: incorrect
```js
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/
function foo () {
// ...
}
var bar = function() {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
var baz = async(a) => await a
```
:::
Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option:
::: correct
```js
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/
function foo() {
// ...
}
var bar = function () {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
var baz = async (a) => await a
```
:::
### `{"anonymous": "never", "named": "always"}`
Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
::: incorrect
```js
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/
function foo() {
// ...
}
var bar = function () {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
::: correct
```js
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/
function foo () {
// ...
}
var bar = function() {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
### `{"anonymous": "ignore", "named": "always"}`
Examples of **incorrect** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option:
::: incorrect
```js
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/
function foo() {
// ...
}
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option:
::: correct
```js
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/
var bar = function() {
// ...
};
var bar = function () {
// ...
};
function foo () {
// ...
}
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing before function parenthesis.
---
---
title: space-before-function-parentheses
related_rules:
- space-after-keywords
- space-return-throw-case
---
Enforces consistent spacing before opening parenthesis in function definitions.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [space-before-function-paren](space-before-function-paren) rule. The name of the rule changed from "parentheses" to "paren" for consistency with the names of other rules.
:::
When formatting a function, whitespace is allowed between the function name or `function` keyword and the opening paren. Named functions also require a space between the `function` keyword and the function name, but anonymous functions require no whitespace. For example:
```js
function withoutSpace(x) {
// ...
}
function withSpace (x) {
// ...
}
var anonymousWithoutSpace = function() {};
var anonymousWithSpace = function () {};
```
Style guides may require a space after the `function` keyword for anonymous functions, while others specify no whitespace. Similarly, the space after a function name may or may not be required.
## Rule Details
This rule aims to enforce consistent spacing before function parentheses and as such, will warn whenever whitespace doesn't match the preferences specified.
This rule takes one argument. If it is `"always"`, which is the default option, all named functions and anonymous functions must have space before function parentheses. If `"never"` then all named functions and anonymous functions must not have space before function parentheses. If you want different spacing for named and anonymous functions you can pass a configuration object as the rule argument to configure those separately (e. g. `{"anonymous": "always", "named": "never"}`).
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
function foo() {
// ...
}
var bar = function() {
// ...
};
var bar = function foo() {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct
```js
function foo () {
// ...
}
var bar = function () {
// ...
};
var bar = function foo () {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
function foo () {
// ...
}
var bar = function () {
// ...
};
var bar = function foo () {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
function foo() {
// ...
}
var bar = function() {
// ...
};
var bar = function foo() {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never"}` option:
::: incorrect
```js
function foo () {
// ...
}
var bar = function() {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never"}` option:
::: correct
```js
function foo() {
// ...
}
var bar = function () {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
::: incorrect
```js
function foo() {
// ...
}
var bar = function () {
// ...
};
class Foo {
constructor() {
// ...
}
}
var baz = {
bar() {
// ...
}
};
```
:::
Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
::: correct
```js
function foo () {
// ...
}
var bar = function() {
// ...
};
class Foo {
constructor () {
// ...
}
}
var baz = {
bar () {
// ...
}
};
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing before function parenthesis.
---
---
title: space-before-keywords
related_rules:
- space-after-keywords
- block-spacing
- space-return-throw-case
- space-unary-ops
- space-infix-ops
---
Enforces consistent spacing before keywords.
::: important
This rule was removed in ESLint v2.0.0 and replaced by the [keyword-spacing](keyword-spacing) rule.
:::
(fixable) The `--fix` option on the [command line](../use/command-line-interface#--fix) automatically fixed problems reported by this rule.
Keywords are syntax elements of JavaScript, such as `function` and `if`. These identifiers have special meaning to the language and so often appear in a different color in code editors. As an important part of the language, style guides often refer to the spacing that should be used around keywords. For example, you might have a style guide that says keywords should be always be preceded by spaces, which would mean `if-else` statements must look like this:
```js
if (foo) {
// ...
} else {
// ...
}
```
Of course, you could also have a style guide that disallows spaces before keywords.
## Rule Details
This rule will enforce consistency of spacing before the keywords `if`, `else`, `for`,
`while`, `do`, `switch`, `throw`, `try`, `catch`, `finally`, `with`, `break`, `continue`,
`return`, `function`, `yield`, `class` and variable declarations (`let`, `const`, `var`)
and label statements.
This rule takes one argument: `"always"` or `"never"`. If `"always"` then the keywords
must be preceded by at least one space. If `"never"` then no spaces will be allowed before
the keywords `else`, `while` (do...while), `finally` and `catch`. The default value is `"always"`.
This rule will allow keywords to be preceded by an opening curly brace (`{`). If you wish to alter
this behavior, consider using the [block-spacing](block-spacing) rule.
Examples of **incorrect** code for this rule with the default `"always"` option:
::: incorrect
```js
/*eslint space-before-keywords: ["error", "always"]*/
if (foo) {
// ...
}else {}
const foo = 'bar';let baz = 'qux';
var qux =function bar () {}
function bar() {
if (foo) {return; }
}
```
:::
Examples of **correct** code for this rule with the default `"always"` option:
::: correct { "parserOptions": { "ecmaFeatures": { "jsx": true } } }
```jsx
/*eslint space-before-keywords: ["error", "always"]*/
if (foo) {
// ...
} else {}
(function() {})();
for (let foo of ['bar', 'baz', 'qux']) {}
```
:::
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint space-before-keywords: ["error", "never"]*/
if (foo) {
// ...
} else {}
do {
}
while (foo)
try {} finally {}
try {} catch(e) {}
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint space-before-keywords: ["error", "never"]*/
if (foo) {
// ...
}else {}
do {}while (foo)
try {}finally {}
try{}catch(e) {}
```
:::
## When Not To Use It
If you do not wish to enforce consistency on keyword spacing.
---
---
title: space-in-brackets
related_rules:
- array-bracket-spacing
- object-curly-spacing
- space-in-parens
- computed-property-spacing
---
Enforces consistent spacing inside braces of object literals and brackets of array literals.
::: important
This rule was removed in ESLint v1.0.0 and replaced by the [object-curly-spacing](object-curly-spacing) and [array-bracket-spacing](array-bracket-spacing) rules.
:::
While formatting preferences are very personal, a number of style guides require or disallow spaces between brackets:
```js
var obj = { foo: 'bar' };
var arr = [ 'foo', 'bar' ];
foo[ 'bar' ];
var obj = {foo: 'bar'};
var arr = ['foo', 'bar'];
foo['bar'];
```
## Rule Details
This rule aims to maintain consistency around the spacing inside of square brackets, either by disallowing spaces inside of brackets between the brackets and other tokens or enforcing spaces. Brackets that are separated from the adjacent value by a new line are excepted from this rule, as this is a common pattern. Object literals that are used as the first or last element in an array are also ignored.
## Options
There are two options for this rule:
* `"always"` enforces a space inside of object and array literals
* `"never"` enforces zero spaces inside of object and array literals (default)
Depending on your coding conventions, you can choose either option by specifying it in your configuration:
```json
"space-in-brackets": ["error", "always"]
```
### "never"
Examples of **incorrect** code for this rule with the default `"never"` option:
::: incorrect
```js
foo[ 'bar' ];
foo['bar' ];
var arr = [ 'foo', 'bar' ];
var arr = ['foo', 'bar' ];
var arr = [ ['foo'], 'bar'];
var arr = [[ 'foo' ], 'bar'];
var arr = ['foo',
'bar'
];
var obj = { 'foo': 'bar' };
var obj = {'foo': 'bar' };
var obj = { baz: {'foo': 'qux'}, bar};
var obj = {baz: { 'foo': 'qux' }, bar};
```
:::
Examples of **correct** code for this rule with the default `"never"` option:
::: correct
```js
// When options are ["error", "never"]
foo['bar'];
foo[
'bar'
];
foo[
'bar'];
var arr = [];
var arr = ['foo', 'bar', 'baz'];
var arr = [['foo'], 'bar', 'baz'];
var arr = [
'foo',
'bar',
'baz'
];
var arr = [
'foo',
'bar'];
var obj = {'foo': 'bar'};
var obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'};
var obj = {
'foo': 'bar'
};
var obj = {'foo': 'bar'
};
var obj = {
'foo':'bar'};
var obj = {};
```
:::
### "always"
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
foo['bar'];
foo['bar' ];
foo[ 'bar'];
var arr = ['foo', 'bar'];
var arr = ['foo', 'bar' ];
var arr = [ ['foo'], 'bar' ];
var arr = ['foo',
'bar'
];
var arr = [
'foo',
'bar'];
var obj = {'foo': 'bar'};
var obj = {'foo': 'bar' };
var obj = { baz: {'foo': 'qux'}, bar};
var obj = {baz: { 'foo': 'qux' }, bar};
var obj = {'foo': 'bar'
};
var obj = {
'foo':'bar'};
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
foo[ 'bar' ];
foo[
'bar'
];
var arr = [];
var arr = [ 'foo', 'bar', 'baz' ];
var arr = [ [ 'foo' ], 'bar', 'baz' ];
var arr = [
'foo',
'bar',
'baz'
];
var obj = {};
var obj = { 'foo': 'bar' };
var obj = { 'foo': { 'bar': 'baz' }, 'qux': 'quxx' };
var obj = {
'foo': 'bar'
};
```
:::
Note that `"always"` has a special case where `{}` and `[]` are not considered problems.
### Exceptions
An object literal may be used as a third array item to specify spacing exceptions. These exceptions work in the context of the first option. That is, if `"always"` is set to enforce spacing and an exception is set to `false`, it will disallow spacing for cases matching the exception. Likewise, if `"never"` is set to disallow spacing and an exception is set to `true`, it will enforce spacing for cases matching the exception.
You can add exceptions like so:
In case of `"always"` option, set an exception to `false` to enable it:
```json
"space-in-brackets": ["error", "always", {
"singleValue": false,
"objectsInArrays": false,
"arraysInArrays": false,
"arraysInObjects": false,
"objectsInObjects": false,
"propertyName": false
}]
```
In case of `"never"` option, set an exception to `true` to enable it:
```json
"space-in-brackets": ["error", "never", {
"singleValue": true,
"objectsInArrays": true,
"arraysInArrays": true,
"arraysInObjects": true,
"objectsInObjects": true,
"propertyName": true
}]
```
The following exceptions are available:
* `singleValue` sets the spacing of a single value inside of square brackets of an array.
* `objectsInArrays` sets the spacings between the curly braces and square brackets of object literals that are the first or last element in an array.
* `arraysInArrays` sets the spacing between the square brackets of array literals that are the first or last element in an array.
* `arraysInObjects` sets the spacing between the square bracket and the curly brace of an array literal that is the last element in an object.
* `objectsInObjects` sets the spacing between the curly brace of an object literal that is the last element in an object and the curly brace of the containing object.
* `propertyName` sets the spacing in square brackets of computed member expressions.
In each of the following examples, the `"always"` option is assumed.
Examples of **incorrect** code for this rule when `"singleValue"` is set to `false`:
::: incorrect
```js
var foo = [ 'foo' ];
var foo = [ 'foo'];
var foo = ['foo' ];
var foo = [ 1 ];
var foo = [ 1];
var foo = [1 ];
var foo = [ [ 1, 2 ] ];
var foo = [ { 'foo': 'bar' } ];
```
:::
Examples of **correct** code for this rule when `"singleValue"` is set to `false`:
::: correct
```js
var foo = ['foo'];
var foo = [1];
var foo = [[ 1, 1 ]];
var foo = [{ 'foo': 'bar' }];
```
:::
Examples of **incorrect** code when `"objectsInArrays"` is set to `false`:
::: incorrect
```js
var arr = [ { 'foo': 'bar' } ];
var arr = [ {
'foo': 'bar'
} ]
```
:::
Examples of **correct** code when `"objectsInArrays"` is set to `false`:
::: correct
```js
var arr = [{ 'foo': 'bar' }];
var arr = [{
'foo': 'bar'
}];
```
:::
Examples of **incorrect** code when `"arraysInArrays"` is set to `false`:
::: incorrect
```js
var arr = [ [ 1, 2 ], 2, 3, 4 ];
var arr = [ [ 1, 2 ], 2, [ 3, 4 ] ];
```
:::
Examples of **correct** code when `"arraysInArrays"` is set to `false`:
::: correct
```js
var arr = [[ 1, 2 ], 2, 3, 4 ];
var arr = [[ 1, 2 ], 2, [ 3, 4 ]];
```
:::
Examples of **incorrect** code when `"arraysInObjects"` is set to `false`:
::: incorrect
```js
var obj = { "foo": [ 1, 2 ] };
var obj = { "foo": [ "baz", "bar" ] };
```
:::
Examples of **correct** code when `"arraysInObjects"` is set to `false`:
::: correct
```js
var obj = { "foo": [ 1, 2 ]};
var obj = { "foo": [ "baz", "bar" ]};
```
:::
Examples of **incorrect** code when `"objectsInObjects"` is set to `false`:
::: incorrect
```js
var obj = { "foo": { "baz": 1, "bar": 2 } };
var obj = { "foo": [ "baz", "bar" ], "qux": { "baz": 1, "bar": 2 } };
```
:::
Examples of **correct** code when `"objectsInObjects"` is set to `false`:
::: correct
```js
var obj = { "foo": { "baz": 1, "bar": 2 }};
var obj = { "foo": [ "baz", "bar" ], "qux": { "baz": 1, "bar": 2 }};
```
:::
Examples of **incorrect** code when `"propertyName"` is set to `false`:
::: incorrect
```js
var foo = obj[ 1 ];
var foo = obj[ bar ];
```
:::
Examples of **correct** code when `"propertyName"` is set to `false`:
::: correct
```js
var foo = obj[bar];
var foo = obj[0, 1];
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing between brackets.
---
---
title: space-in-parens
rule_type: layout
related_rules:
- array-bracket-spacing
- object-curly-spacing
- computed-property-spacing
---
Some style guides require or disallow spaces inside of parentheses:
```js
foo( 'bar' );
var x = ( 1 + 2 ) * 3;
foo('bar');
var x = (1 + 2) * 3;
```
## Rule Details
This rule will enforce consistent spacing directly inside of parentheses, by disallowing or requiring one or more spaces to the right of `(` and to the left of `)`.
As long as you do not explicitly disallow empty parentheses using the `"empty"` exception , `()` will be allowed.
## Options
There are two options for this rule:
* `"never"` (default) enforces zero spaces inside of parentheses
* `"always"` enforces a space inside of parentheses
Depending on your coding conventions, you can choose either option by specifying it in your configuration:
```json
"space-in-parens": ["error", "always"]
```
### "never"
Examples of **incorrect** code for this rule with the default `"never"` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "never"]*/
foo( );
foo( 'bar');
foo('bar' );
foo( 'bar' );
foo( /* bar */ );
var foo = ( 1 + 2 ) * 3;
( function () { return 'bar'; }() );
```
:::
Examples of **correct** code for this rule with the default `"never"` option:
::: correct
```js
/*eslint space-in-parens: ["error", "never"]*/
foo();
foo('bar');
foo(/* bar */);
var foo = (1 + 2) * 3;
(function () { return 'bar'; }());
```
:::
### "always"
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always"]*/
foo( 'bar');
foo('bar' );
foo('bar');
foo(/* bar */);
var foo = (1 + 2) * 3;
(function () { return 'bar'; }());
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always"]*/
foo();
foo( );
foo( 'bar' );
foo( /* bar */ );
var foo = ( 1 + 2 ) * 3;
( function () { return 'bar'; }() );
```
:::
### Exceptions
An object literal may be used as a third array item to specify exceptions, with the key `"exceptions"` and an array as the value. These exceptions work in the context of the first option. That is, if `"always"` is set to enforce spacing, then any "exception" will *disallow* spacing. Conversely, if `"never"` is set to disallow spacing, then any "exception" will *enforce* spacing.
Note that this rule only enforces spacing within parentheses; it does not check spacing within curly or square brackets, but will enforce or disallow spacing of those brackets if and only if they are adjacent to an opening or closing parenthesis.
The following exceptions are available: `["{}", "[]", "()", "empty"]`.
### Empty Exception
Empty parens exception and behavior:
* `always` allows for both `()` and `( )`
* `never` (default) requires `()`
* `always` excepting `empty` requires `()`
* `never` excepting `empty` requires `( )` (empty parens without a space is here forbidden)
Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["{}"] }` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["{}"] }]*/
foo({bar: 'baz'});
foo(1, {bar: 'baz'});
```
:::
Examples of **correct** code for this rule with the `"never", { "exceptions": ["{}"] }` option:
::: correct
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["{}"] }]*/
foo( {bar: 'baz'} );
foo(1, {bar: 'baz'} );
```
:::
Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["{}"] }` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}"] }]*/
foo( {bar: 'baz'} );
foo( 1, {bar: 'baz'} );
```
:::
Examples of **correct** code for this rule with the `"always", { "exceptions": ["{}"] }` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}"] }]*/
foo({bar: 'baz'});
foo( 1, {bar: 'baz'});
```
:::
Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["[]"] }` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["[]"] }]*/
foo([bar, baz]);
foo([bar, baz], 1);
```
:::
Examples of **correct** code for this rule with the `"never", { "exceptions": ["[]"] }` option:
::: correct
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["[]"] }]*/
foo( [bar, baz] );
foo( [bar, baz], 1);
```
:::
Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["[]"] }` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["[]"] }]*/
foo( [bar, baz] );
foo( [bar, baz], 1 );
```
:::
Examples of **correct** code for this rule with the `"always", { "exceptions": ["[]"] }` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["[]"] }]*/
foo([bar, baz]);
foo([bar, baz], 1 );
```
:::
Examples of **incorrect** code for this rule with the `"never", { "exceptions": ["()"] }]` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["()"] }]*/
foo((1 + 2));
foo((1 + 2), 1);
foo(bar());
```
:::
Examples of **correct** code for this rule with the `"never", { "exceptions": ["()"] }]` option:
::: correct
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["()"] }]*/
foo( (1 + 2) );
foo( (1 + 2), 1);
foo(bar() );
```
:::
Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["()"] }]` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["()"] }]*/
foo( ( 1 + 2 ) );
foo( ( 1 + 2 ), 1 );
```
:::
Examples of **correct** code for this rule with the `"always", { "exceptions": ["()"] }]` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["()"] }]*/
foo(( 1 + 2 ));
foo(( 1 + 2 ), 1 );
```
:::
The `"empty"` exception concerns empty parentheses, and works the same way as the other exceptions, inverting the first option.
Example of **incorrect** code for this rule with the `"never", { "exceptions": ["empty"] }]` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["empty"] }]*/
foo();
```
:::
Example of **correct** code for this rule with the `"never", { "exceptions": ["empty"] }]` option:
::: correct
```js
/*eslint space-in-parens: ["error", "never", { "exceptions": ["empty"] }]*/
foo( );
```
:::
Example of **incorrect** code for this rule with the `"always", { "exceptions": ["empty"] }]` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["empty"] }]*/
foo( );
```
:::
Example of **correct** code for this rule with the `"always", { "exceptions": ["empty"] }]` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["empty"] }]*/
foo();
```
:::
You can include multiple entries in the `"exceptions"` array.
Examples of **incorrect** code for this rule with the `"always", { "exceptions": ["{}", "[]"] }]` option:
::: incorrect
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}", "[]"] }]*/
bar( {bar:'baz'} );
baz( 1, [1,2] );
foo( {bar: 'baz'}, [1, 2] );
```
:::
Examples of **correct** code for this rule with the `"always", { "exceptions": ["{}", "[]"] }]` option:
::: correct
```js
/*eslint space-in-parens: ["error", "always", { "exceptions": ["{}", "[]"] }]*/
bar({bar:'baz'});
baz( 1, [1,2]);
foo({bar: 'baz'}, [1, 2]);
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing between parentheses.
---
---
title: space-infix-ops
rule_type: layout
---
While formatting preferences are very personal, a number of style guides require spaces around operators, such as:
```js
var sum = 1 + 2;
```
Proponents of this rule believe that it makes code easier to read and can more easily highlight potential errors, such as:
```js
var sum = i+++2;
```
While this is valid JavaScript syntax, it is hard to determine what the author intended.
## Rule Details
This rule is aimed at ensuring there are spaces around infix operators.
## Options
This rule accepts a single options argument with the following defaults:
```json
"space-infix-ops": ["error", { "int32Hint": false }]
```
### `int32Hint`
Set the `int32Hint` option to `true` (default is `false`) to allow write `a|0` without space.
```js
var foo = bar|0; // `foo` is forced to be signed 32 bit integer
```
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint space-infix-ops: "error"*/
a+b
a+ b
a +b
a?b:c
const a={b:1};
var {b=0}=bar;
function foo(a=0) { }
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint space-infix-ops: "error"*/
a + b
a + b
a ? b : c
const a = {b:1};
var {b = 0} = bar;
function foo(a = 0) { }
```
:::
## When Not To Use It
You can turn this rule off if you are not concerned with the consistency of spacing around infix operators.
---
---
title: space-return-throw-case
---
Requires spaces after `return`, `throw`, and `case` keywords.
::: important
This rule was removed in ESLint v2.0.0 and replaced by the [keyword-spacing](keyword-spacing) rule.
:::
(fixable) The `--fix` option on the [command line](../use/command-line-interface#--fix) automatically fixed problems reported by this rule.
Require spaces following `return`, `throw`, and `case`.
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint space-return-throw-case: "error"*/
throw{a:0}
function f(){ return-a; }
switch(a){ case'a': break; }
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint space-return-throw-case: "error"*/
throw {a: 0};
function f(){ return -a; }
switch(a){ case 'a': break; }
```
:::
---
---
title: space-unary-ops
rule_type: layout
---
Some style guides require or disallow spaces before or after unary operators. This is mainly a stylistic issue, however, some JavaScript expressions can be written without spacing which makes it harder to read and maintain.
## Rule Details
This rule enforces consistency regarding the spaces after `words` unary operators and after/before `nonwords` unary operators.
For `words` operators, this rule only applies when a space is not syntactically required. For instance, `delete obj.foo` requires the space and will not be considered by this rule. The equivalent `delete(obj.foo)` has an optional space (`delete (obj.foo)`), therefore this rule will apply to it.
Examples of unary `words` operators:
```js
// new
var joe = new Person();
// delete
var obj = {
foo: 'bar'
};
delete obj.foo;
// typeof
typeof {} // object
// void
void 0 // undefined
```
Examples of unary `nonwords` operators:
```js
if ([1,2,3].indexOf(1) !== -1) {};
foo = --foo;
bar = bar++;
baz = !foo;
qux = !!baz;
```
## Options
This rule has three options:
* `words` - applies to unary word operators such as: `new`, `delete`, `typeof`, `void`, `yield`
* `nonwords` - applies to unary operators such as: `-`, `+`, `--`, `++`, `!`, `!!`
* `overrides` - specifies overwriting usage of spacing for each
operator, word or non word. This is empty by default, but can be used
to enforce or disallow spacing around operators. For example:
```js
"space-unary-ops": [
2, {
"words": true,
"nonwords": false,
"overrides": {
"new": false,
"++": true
}
}]
```
In this case, spacing will be disallowed after a `new` operator and required before/after a `++` operator.
Examples of **incorrect** code for this rule with the default `{"words": true, "nonwords": false}` option:
::: incorrect
```js
/*eslint space-unary-ops: "error"*/
typeof!foo;
void{foo:0};
new[foo][0];
delete(foo.bar);
++ foo;
foo --;
- foo;
+ "3";
```
:::
::: incorrect
```js
/*eslint space-unary-ops: "error"*/
function *foo() {
yield(0)
}
```
:::
::: incorrect
```js
/*eslint space-unary-ops: "error"*/
async function foo() {
await(bar);
}
```
:::
Examples of **correct** code for this rule with the `{"words": true, "nonwords": false}` option:
::: correct
```js
/*eslint space-unary-ops: "error"*/
// Word unary operator "typeof" is followed by a whitespace.
typeof !foo;
// Word unary operator "void" is followed by a whitespace.
void {foo:0};
// Word unary operator "new" is followed by a whitespace.
new [foo][0];
// Word unary operator "delete" is followed by a whitespace.
delete (foo.bar);
// Unary operator "++" is not followed by whitespace.
++foo;
// Unary operator "--" is not preceded by whitespace.
foo--;
// Unary operator "-" is not followed by whitespace.
-foo;
// Unary operator "+" is not followed by whitespace.
+"3";
```
:::
::: correct
```js
/*eslint space-unary-ops: "error"*/
function *foo() {
yield (0)
}
```
:::
::: correct
```js
/*eslint space-unary-ops: "error"*/
async function foo() {
await (bar);
}
```
:::
---
---
title: space-unary-word-ops
---
Requires spaces after unary word operators.
:::important
This rule was removed in ESLint v0.10.0 and replaced by the [space-unary-ops](space-unary-ops) rule.
:::
## Rule Details
Examples of **incorrect** code for this rule:
::: incorrect
```js
typeof!a
```
:::
::: incorrect
```js
void{a:0}
```
:::
::: incorrect
```js
new[a][0]
```
:::
::: incorrect
```js
delete(a.b)
```
:::
Examples of **correct** code for this rule:
::: correct
```js
delete a.b
```
:::
::: correct
```js
new C
```
:::
::: correct
```js
void 0
```
:::
---
---
title: spaced-comment
rule_type: suggestion
related_rules:
- spaced-line-comment
---
Some style guides require or disallow a whitespace immediately after the initial `//` or `/*` of a comment.
Whitespace after the `//` or `/*` makes it easier to read text in comments.
On the other hand, commenting out code is easier without having to put a whitespace right after the `//` or `/*`.
## Rule Details
This rule will enforce consistency of spacing after the start of a comment `//` or `/*`. It also provides several
exceptions for various documentation styles.
## Options
The rule takes two options.
* The first is a string which be either `"always"` or `"never"`. The default is `"always"`.
* If `"always"` then the `//` or `/*` must be followed by at least one whitespace.
* If `"never"` then there should be no whitespace following.
* This rule can also take a 2nd option, an object with any of the following keys: `"exceptions"` and `"markers"`.
* The `"exceptions"` value is an array of string patterns which are considered exceptions to the rule. The rule will not warn when the pattern starts from the beginning of the comment and repeats until the end of the line or `*/` if the comment is a single line comment.
Please note that exceptions are ignored if the first argument is `"never"`.
```js
"spaced-comment": ["error", "always", { "exceptions": ["-", "+"] }]
```
* The `"markers"` value is an array of string patterns which are considered markers for docblock-style comments,
such as an additional `/`, used to denote documentation read by doxygen, vsdoc, etc. which must have additional characters.
The `"markers"` array will apply regardless of the value of the first argument, e.g. `"always"` or `"never"`.
```js
"spaced-comment": ["error", "always", { "markers": ["/"] }]
```
The difference between a marker and an exception is that a marker only appears at the beginning of the comment whereas
exceptions can occur anywhere in the comment string.
You can also define separate exceptions and markers for block and line comments. The `"block"` object can have an additional key `"balanced"`, a boolean that specifies if inline block comments should have balanced spacing. The default value is `false`.
* If `"balanced": true` and `"always"` then the `/*` must be followed by at least one whitespace, and the `*/` must be preceded by at least one whitespace.
* If `"balanced": true` and `"never"` then there should be no whitespace following `/*` or preceding `*/`.
* If `"balanced": false` then balanced whitespace is not enforced.
```json
"spaced-comment": ["error", "always", {
"line": {
"markers": ["/"],
"exceptions": ["-", "+"]
},
"block": {
"markers": ["!"],
"exceptions": ["*"],
"balanced": true
}
}]
```
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint spaced-comment: ["error", "always"]*/
//This is a comment with no whitespace at the beginning
/*This is a comment with no whitespace at the beginning */
```
:::
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "block": { "balanced": true } }] */
/* This is a comment with whitespace at the beginning but not the end*/
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/* eslint spaced-comment: ["error", "always"] */
// This is a comment with a whitespace at the beginning
/* This is a comment with a whitespace at the beginning */
/*
* This is a comment with a whitespace at the beginning
*/
/*
This comment has a newline
*/
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always"] */
/**
* I am jsdoc
*/
```
:::
### never
Examples of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
/*eslint spaced-comment: ["error", "never"]*/
// This is a comment with a whitespace at the beginning
/* This is a comment with a whitespace at the beginning */
/* \nThis is a comment with a whitespace at the beginning */
```
:::
::: incorrect
```js
/*eslint spaced-comment: ["error", "never", { "block": { "balanced": true } }]*/
/*This is a comment with whitespace at the end */
```
:::
Examples of **correct** code for this rule with the `"never"` option:
::: correct
```js
/*eslint spaced-comment: ["error", "never"]*/
/*This is a comment with no whitespace at the beginning */
```
:::
::: correct
```js
/*eslint spaced-comment: ["error", "never"]*/
/**
* I am jsdoc
*/
```
:::
### exceptions
Examples of **incorrect** code for this rule with the `"always"` option combined with `"exceptions"`:
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["-"] } }] */
//--------------
// Comment block
//--------------
```
:::
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "exceptions": ["-", "+"] }] */
//------++++++++
// Comment block
//------++++++++
```
:::
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "exceptions": ["-", "+"] }] */
/*------++++++++*/
/* Comment block */
/*------++++++++*/
```
:::
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "line": { "exceptions": ["-+"] } }] */
/*-+-+-+-+-+-+-+*/
// Comment block
/*-+-+-+-+-+-+-+*/
```
:::
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["*"] } }] */
/******** COMMENT *******/
```
:::
Examples of **correct** code for this rule with the `"always"` option combined with `"exceptions"`:
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "exceptions": ["-"] }] */
//--------------
// Comment block
//--------------
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "line": { "exceptions": ["-"] } }] */
//--------------
// Comment block
//--------------
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "exceptions": ["*"] }] */
/****************
* Comment block
****************/
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "exceptions": ["-+"] }] */
//-+-+-+-+-+-+-+
// Comment block
//-+-+-+-+-+-+-+
/*-+-+-+-+-+-+-+*/
// Comment block
/*-+-+-+-+-+-+-+*/
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["-+"] } }] */
/*-+-+-+-+-+-+-+*/
// Comment block
/*-+-+-+-+-+-+-+*/
```
:::
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "block": { "exceptions": ["*"] } }] */
/***************/
/********
COMMENT
*******/
```
:::
### markers
Examples of **incorrect** code for this rule with the `"always"` option combined with `"markers"`:
::: incorrect
```js
/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */
///This is a comment with a marker but without whitespace
```
:::
::: incorrect
```js
/*eslint spaced-comment: ["error", "always", { "block": { "markers": ["!"], "balanced": true } }]*/
/*! This is a comment with a marker but without whitespace at the end*/
```
:::
::: incorrect
```js
/*eslint spaced-comment: ["error", "never", { "block": { "markers": ["!"], "balanced": true } }]*/
/*!This is a comment with a marker but with whitespace at the end */
```
:::
Examples of **correct** code for this rule with the `"always"` option combined with `"markers"`:
::: correct
```js
/* eslint spaced-comment: ["error", "always", { "markers": ["/"] }] */
/// This is a comment with a marker
```
:::
::: correct
```js
/*eslint spaced-comment: ["error", "never", { "markers": ["!<"] }]*/
//! console.log(foo);
// Symbol(some description)
```
It may facilitate identifying symbols when one is observed during debugging.
## Rule Details
This rules requires a description when creating symbols.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint symbol-description: "error"*/
const foo = Symbol();
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint symbol-description: "error"*/
const foo = Symbol("some description");
const someString = "some description";
const bar = Symbol(someString);
```
:::
## Options
This rule has no options.
## When Not To Use It
This rule should not be used in ES3/5 environments.
In addition, this rule can be safely turned off if you don't want to enforce presence of `description` when creating Symbols.
---
---
title: template-curly-spacing
rule_type: layout
---
We can embed expressions in template strings with using a pair of `${` and `}`.
This rule can force usage of spacing _within_ the curly brace pair according to style guides.
```js
let hello = `hello, ${people.name}!`;
```
## Rule Details
This rule aims to maintain consistency around the spacing inside of template literals.
## Options
```json
{
"template-curly-spacing": ["error", "never"]
}
```
This rule has one option which has either `"never"` or `"always"` as value.
* `"never"` (by default) - Disallows spaces inside of the curly brace pair.
* `"always"` - Requires one or more spaces inside of the curly brace pair.
### never
Examples of **incorrect** code for this rule with the default `"never"` option:
::: incorrect
```js
/*eslint template-curly-spacing: "error"*/
`hello, ${ people.name}!`;
`hello, ${people.name }!`;
`hello, ${ people.name }!`;
```
:::
Examples of **correct** code for this rule with the default `"never"` option:
::: correct
```js
/*eslint template-curly-spacing: "error"*/
`hello, ${people.name}!`;
`hello, ${
people.name
}!`;
```
:::
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint template-curly-spacing: ["error", "always"]*/
`hello, ${ people.name}!`;
`hello, ${people.name }!`;
`hello, ${people.name}!`;
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint template-curly-spacing: ["error", "always"]*/
`hello, ${ people.name }!`;
`hello, ${
people.name
}!`;
```
:::
## When Not To Use It
If you don't want to be notified about usage of spacing inside of template strings, then it's safe to disable this rule.
---
---
title: template-tag-spacing
rule_type: layout
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals
- https://exploringjs.com/es6/ch_template-literals.html#_examples-of-using-tagged-template-literals
---
With ES6, it's possible to create functions called [tagged template literals](#further-reading) where the function parameters consist of a template literal's strings and expressions.
When using tagged template literals, it's possible to insert whitespace between the tag function and the template literal. Since this whitespace is optional, the following lines are equivalent:
```js
let hello = func`Hello world`;
let hello = func `Hello world`;
```
## Rule Details
This rule aims to maintain consistency around the spacing between template tag functions and their template literals.
## Options
```json
{
"template-tag-spacing": ["error", "never"]
}
```
This rule has one option whose value can be set to `"never"` or `"always"`
* `"never"` (default) - Disallows spaces between a tag function and its template literal.
* `"always"` - Requires one or more spaces between a tag function and its template literal.
### never
Examples of **incorrect** code for this rule with the default `"never"` option:
::: incorrect
```js
/*eslint template-tag-spacing: "error"*/
func `Hello world`;
```
:::
Examples of **correct** code for this rule with the default `"never"` option:
::: correct
```js
/*eslint template-tag-spacing: "error"*/
func`Hello world`;
```
:::
### always
Examples of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint template-tag-spacing: ["error", "always"]*/
func`Hello world`;
```
:::
Examples of **correct** code for this rule with the `"always"` option:
::: correct
```js
/*eslint template-tag-spacing: ["error", "always"]*/
func `Hello world`;
```
:::
## When Not To Use It
If you don't want to be notified about usage of spacing between tag functions and their template literals, then it's safe to disable this rule.
---
---
title: unicode-bom
rule_type: layout
---
The Unicode Byte Order Mark (BOM) is used to specify whether code units are big
endian or little endian. That is, whether the most significant or least
significant bytes come first. UTF-8 does not require a BOM because byte ordering
does not matter when characters are a single byte. Since UTF-8 is the dominant
encoding of the web, we make `"never"` the default option.
## Rule Details
If the `"always"` option is used, this rule requires that files always begin
with the Unicode BOM character U+FEFF. If `"never"` is used, files must never
begin with U+FEFF.
## Options
This rule has a string option:
* `"always"` files must begin with the Unicode BOM
* `"never"` (default) files must not begin with the Unicode BOM
### always
Example of **correct** code for this rule with the `"always"` option:
::: correct
```js
// U+FEFF at the beginning
/*eslint unicode-bom: ["error", "always"]*/
let abc;
```
:::
Example of **incorrect** code for this rule with the `"always"` option:
::: incorrect
```js
/*eslint unicode-bom: ["error", "always"]*/
let abc;
```
:::
### never
Example of **correct** code for this rule with the default `"never"` option:
::: correct
```js
/*eslint unicode-bom: ["error", "never"]*/
let abc;
```
:::
Example of **incorrect** code for this rule with the `"never"` option:
::: incorrect
```js
// U+FEFF at the beginning
/*eslint unicode-bom: ["error", "never"]*/
let abc;
```
:::
## When Not To Use It
If you use some UTF-16 or UTF-32 files and you want to allow a file to
optionally begin with a Unicode BOM, you should turn this rule off.
---
---
title: use-isnan
rule_type: problem
---
In JavaScript, `NaN` is a special value of the `Number` type. It's used to represent any of the "not-a-number" values represented by the double-precision 64-bit format as specified by the IEEE Standard for Binary Floating-Point Arithmetic.
Because `NaN` is unique in JavaScript by not being equal to anything, including itself, the results of comparisons to `NaN` are confusing:
* `NaN === NaN` or `NaN == NaN` evaluate to `false`
* `NaN !== NaN` or `NaN != NaN` evaluate to `true`
Therefore, use `Number.isNaN()` or global `isNaN()` functions to test whether a value is `NaN`.
## Rule Details
This rule disallows comparisons to `NaN`.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint use-isnan: "error"*/
if (foo == NaN) {
// ...
}
if (foo != NaN) {
// ...
}
if (foo == Number.NaN) {
// ...
}
if (foo != Number.NaN) {
// ...
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint use-isnan: "error"*/
if (isNaN(foo)) {
// ...
}
if (!isNaN(foo)) {
// ...
}
```
:::
## Options
This rule has an object option, with two options:
* `"enforceForSwitchCase": true` (default) additionally disallows `case NaN` and `switch(NaN)` in `switch` statements.
* `"enforceForIndexOf": true` additionally disallows the use of `indexOf` and `lastIndexOf` methods with `NaN`. Default is `false`, meaning that this rule by default does not warn about `indexOf(NaN)` or `lastIndexOf(NaN)` method calls.
### enforceForSwitchCase
The `switch` statement internally uses the `===` comparison to match the expression's value to a case clause.
Therefore, it can never match `case NaN`. Also, `switch(NaN)` can never match a case clause.
Examples of **incorrect** code for this rule with `"enforceForSwitchCase"` option set to `true` (default):
::: incorrect
```js
/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/
switch (foo) {
case NaN:
bar();
break;
case 1:
baz();
break;
// ...
}
switch (NaN) {
case a:
bar();
break;
case b:
baz();
break;
// ...
}
switch (foo) {
case Number.NaN:
bar();
break;
case 1:
baz();
break;
// ...
}
switch (Number.NaN) {
case a:
bar();
break;
case b:
baz();
break;
// ...
}
```
:::
Examples of **correct** code for this rule with `"enforceForSwitchCase"` option set to `true` (default):
::: correct
```js
/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/
if (Number.isNaN(foo)) {
bar();
} else {
switch (foo) {
case 1:
baz();
break;
// ...
}
}
if (Number.isNaN(a)) {
bar();
} else if (Number.isNaN(b)) {
baz();
} // ...
```
:::
Examples of **correct** code for this rule with `"enforceForSwitchCase"` option set to `false`:
::: correct
```js
/*eslint use-isnan: ["error", {"enforceForSwitchCase": false}]*/
switch (foo) {
case NaN:
bar();
break;
case 1:
baz();
break;
// ...
}
switch (NaN) {
case a:
bar();
break;
case b:
baz();
break;
// ...
}
switch (foo) {
case Number.NaN:
bar();
break;
case 1:
baz();
break;
// ...
}
switch (Number.NaN) {
case a:
bar();
break;
case b:
baz();
break;
// ...
}
```
:::
### enforceForIndexOf
The following methods internally use the `===` comparison to match the given value with an array element:
* [`Array.prototype.indexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.indexof)
* [`Array.prototype.lastIndexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.lastindexof)
Therefore, for any array `foo`, `foo.indexOf(NaN)` and `foo.lastIndexOf(NaN)` will always return `-1`.
Set `"enforceForIndexOf"` to `true` if you want this rule to report `indexOf(NaN)` and `lastIndexOf(NaN)` method calls.
Examples of **incorrect** code for this rule with `"enforceForIndexOf"` option set to `true`:
::: incorrect
```js
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/
const hasNaN = myArray.indexOf(NaN) >= 0;
const firstIndex = myArray.indexOf(NaN);
const lastIndex = myArray.lastIndexOf(NaN);
const indexWithSequenceExpression = myArray.indexOf((doStuff(), NaN));
const firstIndexFromSecondElement = myArray.indexOf(NaN, 1);
const lastIndexFromSecondElement = myArray.lastIndexOf(NaN, 1);
```
:::
Examples of **correct** code for this rule with `"enforceForIndexOf"` option set to `true`:
::: correct
```js
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/
function myIsNaN(val) {
return typeof val === "number" && isNaN(val);
}
function indexOfNaN(arr) {
for (let i = 0; i < arr.length; i++) {
if (myIsNaN(arr[i])) {
return i;
}
}
return -1;
}
function lastIndexOfNaN(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
if (myIsNaN(arr[i])) {
return i;
}
}
return -1;
}
const hasNaN = myArray.some(myIsNaN);
const hasNaN1 = indexOfNaN(myArray) >= 0;
const firstIndex = indexOfNaN(myArray);
const lastIndex = lastIndexOfNaN(myArray);
// ES2015
const hasNaN2 = myArray.some(Number.isNaN);
// ES2015
const firstIndex1 = myArray.findIndex(Number.isNaN);
// ES2016
const hasNaN3 = myArray.includes(NaN);
```
:::
#### Known Limitations
This option checks methods with the given names, *even if* the object which has the method is *not* an array.
---
---
title: valid-jsdoc
rule_type: suggestion
related_rules:
- require-jsdoc
further_reading:
- https://jsdoc.app
---
:::important
This rule was removed in ESLint v9.0.0 and replaced by the [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc) equivalent.
:::
[JSDoc](https://jsdoc.app) generates application programming interface (API) documentation from specially-formatted comments in JavaScript code. For example, this is a JSDoc comment for a function:
```js
/**
* Add two numbers.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
* @returns {number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
```
If comments are invalid because of typing mistakes, then documentation will be incomplete.
If comments are inconsistent because they are not updated when function definitions are modified, then readers might become confused.
## Rule Details
This rule enforces valid and consistent JSDoc comments. It reports any of the following problems:
* missing parameter tag: `@arg`, `@argument`, or `@param`
* inconsistent order of parameter names in a comment compared to the function or method
* missing return tag: `@return` or `@returns`
* missing parameter or return type
* missing parameter or return description
* syntax error
This rule does not report missing JSDoc comments for classes, functions, or methods.
**Note:** This rule does not support all of the Google Closure documentation tool's use cases. As such, some code such as `(/**number*/ n => n * 2);` will be flagged as missing appropriate function JSDoc comments even though `/**number*/` is intended to be a type hint and not a documentation block for the function. We don't recommend using this rule if you use type hints in this way.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint valid-jsdoc: "error"*/
// expected @param tag for parameter num1 but found num instead
// missing @param tag for parameter num2
// missing return type
/**
* Add two numbers.
* @param {number} num The first number.
* @returns The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
// missing brace
// missing @returns tag
/**
* @param {string name Whom to greet.
*/
function greet(name) {
console.log("Hello " + name);
}
// missing parameter type for num1
// missing parameter description for num2
/**
* Represents a sum.
* @constructor
* @param num1 The first number.
* @param {number} num2
*/
function sum(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint valid-jsdoc: "error"*/
/**
* Add two numbers.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
* @returns {number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
// default options allow missing function description
// return type `void` means the function has no `return` statement
/**
* @param {string} name Whom to greet.
* @returns {void}
*/
function greet(name) {
console.log("Hello " + name);
}
// @constructor tag allows missing @returns tag
/**
* Represents a sum.
* @constructor
* @param {number} num1 The first number.
* @param {number} num2 The second number.
*/
function sum(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
// class constructor allows missing @returns tag
/**
* Represents a sum.
*/
class Sum {
/**
* @param {number} num1 The first number.
* @param {number} num2 The second number.
*/
constructor(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
}
// @abstract tag allows @returns tag without `return` statement
class Widget {
/**
* When the state changes, does it affect the rendered appearance?
* @abstract
* @param {Object} state The new state of the widget.
* @returns {boolean} Is current appearance inconsistent with new state?
*/
mustRender (state) {
throw new Error("Widget subclass did not implement mustRender");
}
}
// @override tag allows missing @param and @returns tags
class WonderfulWidget extends Widget {
/**
* @override
*/
mustRender (state) {
return state !== this.state; // shallow comparison
}
}
```
:::
## Options
This rule has an object option:
* `"prefer"` enforces consistent documentation tags specified by an object whose properties mean instead of key use value (for example, `"return": "returns"` means instead of `@return` use `@returns`)
* `"preferType"` enforces consistent type strings specified by an object whose properties mean instead of key use value (for example, `"object": "Object"` means instead of `object` use `Object`)
* `"requireReturn"` requires a return tag:
* `true` (default) **even if** the function or method does not have a `return` statement (this option value does not apply to constructors)
* `false` **if and only if** the function or method has a `return` statement or returns a value e.g. `async` function (this option value does apply to constructors)
* `"requireReturnType": false` allows missing type in return tags
* `"matchDescription"` specifies (as a string) a regular expression to match the description in each JSDoc comment (for example, `".+"` requires a description; this option does not apply to descriptions in parameter or return tags)
* `"requireParamDescription": false` allows missing description in parameter tags
* `"requireReturnDescription": false` allows missing description in return tags
* `"requireParamType": false` allows missing type in parameter tags
### prefer
Examples of additional **incorrect** code for this rule with sample `"prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" }` options:
::: incorrect
```js
/*eslint valid-jsdoc: ["error", { "prefer": { "arg": "param", "argument": "param", "class": "constructor", "return": "returns", "virtual": "abstract" } }]*/
/**
* Add two numbers.
* @arg {number} num1 The first number.
* @arg {number} num2 The second number.
* @return {number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
/**
* Represents a sum.
* @class
* @argument {number} num1 The first number.
* @argument {number} num2 The second number.
*/
function sum(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
class Widget {
/**
* When the state changes, does it affect the rendered appearance?
* @virtual
* @argument {Object} state The new state of the widget.
* @return {boolean} Is current appearance inconsistent with new state?
*/
mustRender (state) {
throw new Error("Widget subclass did not implement mustRender");
}
}
```
:::
### preferType
Examples of additional **incorrect** code for this rule with sample `"preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" }` options:
::: incorrect
```js
/*eslint valid-jsdoc: ["error", { "preferType": { "Boolean": "boolean", "Number": "number", "object": "Object", "String": "string" } }]*/
/**
* Add two numbers.
* @param {Number} num1 The first number.
* @param {Number} num2 The second number.
* @returns {Number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
/**
* Output a greeting as a side effect.
* @param {String} name Whom to greet.
* @returns {void}
*/
function greet(name) {
console.log("Hello " + name);
}
class Widget {
/**
* When the state changes, does it affect the rendered appearance?
* @abstract
* @param {object} state The new state of the widget.
* @returns {Boolean} Is current appearance inconsistent with new state?
*/
mustRender (state) {
throw new Error("Widget subclass did not implement mustRender");
}
}
```
:::
### requireReturn
Examples of additional **incorrect** code for this rule with the `"requireReturn": false` option:
::: incorrect
```js
/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/
// unexpected @returns tag because function has no `return` statement
/**
* @param {string} name Whom to greet.
* @returns {string} The greeting.
*/
function greet(name) {
console.log("Hello " + name);
}
// add @abstract tag to allow @returns tag without `return` statement
class Widget {
/**
* When the state changes, does it affect the rendered appearance?
* @param {Object} state The new state of the widget.
* @returns {boolean} Is current appearance inconsistent with new state?
*/
mustRender (state) {
throw new Error("Widget subclass did not implement mustRender");
}
}
```
:::
Example of additional **correct** code for this rule with the `"requireReturn": false` option:
::: correct
```js
/*eslint valid-jsdoc: ["error", { "requireReturn": false }]*/
/**
* @param {string} name Whom to greet.
*/
function greet(name) {
console.log("Hello " + name);
}
```
:::
### requireReturnType
Example of additional **correct** code for this rule with the `"requireReturnType": false` option:
::: correct
```js
/*eslint valid-jsdoc: ["error", { "requireReturnType": false }]*/
/**
* Add two numbers.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
* @returns The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
```
:::
### requireParamType
Example of additional **correct** code for this rule with the `"requireParamType": false` option:
::: correct
```js
/*eslint valid-jsdoc: ["error", { "requireParamType": false }]*/
/**
* Add two numbers.
* @param num1 The first number.
* @param num2 The second number.
* @returns {number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
```
:::
### matchDescription
Example of additional **incorrect** code for this rule with a sample `"matchDescription": ".+"` option:
::: incorrect
```js
/*eslint valid-jsdoc: ["error", { "matchDescription": ".+" }]*/
// missing function description
/**
* @param {string} name Whom to greet.
* @returns {void}
*/
function greet(name) {
console.log("Hello " + name);
}
```
:::
### requireParamDescription
Example of additional **correct** code for this rule with the `"requireParamDescription": false` option:
::: correct
```js
/*eslint valid-jsdoc: ["error", { "requireParamDescription": false }]*/
/**
* Add two numbers.
* @param {number} num1
* @param {number} num2
* @returns {number} The sum of the two numbers.
*/
function add(num1, num2) {
return num1 + num2;
}
```
:::
### requireReturnDescription
Example of additional **correct** code for this rule with the `"requireReturnDescription": false` option:
::: correct
```js
/*eslint valid-jsdoc: ["error", { "requireReturnDescription": false }]*/
/**
* Add two numbers.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
* @returns {number}
*/
function add(num1, num2) {
return num1 + num2;
}
```
:::
## When Not To Use It
If you aren't using JSDoc, then you can safely turn this rule off.
---
---
title: valid-typeof
rule_type: problem
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
---
For a vast majority of use cases, the result of the `typeof` operator is one of the following string literals: `"undefined"`, `"object"`, `"boolean"`, `"number"`, `"string"`, `"function"`, `"symbol"`, and `"bigint"`. It is usually a typing mistake to compare the result of a `typeof` operator to other string literals.
## Rule Details
This rule enforces comparing `typeof` expressions to valid string literals.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint valid-typeof: "error"*/
typeof foo === "strnig"
typeof foo == "undefimed"
typeof bar != "nunber"
typeof bar !== "fucntion"
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint valid-typeof: "error"*/
typeof foo === "string"
typeof bar == "undefined"
typeof foo === baz
typeof bar === typeof qux
```
:::
## Options
This rule has an object option:
* `"requireStringLiterals": true` allows the comparison of `typeof` expressions with only string literals or other `typeof` expressions, and disallows comparisons to any other value. Default is `false`.
### requireStringLiterals
Examples of **incorrect** code with the `{ "requireStringLiterals": true }` option:
::: incorrect
```js
/*eslint valid-typeof: ["error", { "requireStringLiterals": true }]*/
typeof foo === undefined
typeof bar == Object
typeof baz === "strnig"
typeof qux === "some invalid type"
typeof baz === anotherVariable
typeof foo == 5
```
:::
Examples of **correct** code with the `{ "requireStringLiterals": true }` option:
::: correct
```js
/*eslint valid-typeof: ["error", { "requireStringLiterals": true }]*/
typeof foo === "undefined"
typeof bar == "object"
typeof baz === "string"
typeof bar === typeof qux
```
:::
## When Not To Use It
You may want to turn this rule off if you will be using the `typeof` operator on host objects.
---
---
title: vars-on-top
rule_type: suggestion
further_reading:
- https://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting
- https://danhough.com/blog/single-var-pattern-rant/
- https://benalman.com/news/2012/05/multiple-var-statements-javascript/
---
The `vars-on-top` rule generates warnings when variable declarations are not used serially at the top of a function scope or the top of a program.
By default variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter.
This rule forces the programmer to represent that behavior by manually moving the variable declaration to the top of its containing scope.
## Rule Details
This rule aims to keep all variable declarations in the leading series of statements.
Allowing multiple declarations helps promote maintainability and is thus allowed.
Examples of **incorrect** code for this rule:
::: incorrect
```js
/*eslint vars-on-top: "error"*/
// Variable declaration in a nested block, and a variable declaration after other statements:
function doSomething() {
if (true) {
var first = true;
}
var second;
}
// Variable declaration in for initializer:
function doSomethingElse() {
for (var i=0; i<10; i++) {}
}
```
:::
::: incorrect
```js
/*eslint vars-on-top: "error"*/
// Variable declaration after other statements:
f();
var a;
```
:::
::: incorrect
```js
/*eslint vars-on-top: "error"*/
// Variables in class static blocks should be at the top of the static blocks.
class C {
// Variable declaration in a nested block:
static {
if (something) {
var a = true;
}
}
// Variable declaration after other statements:
static {
f();
var a;
}
}
```
:::
Examples of **correct** code for this rule:
::: correct
```js
/*eslint vars-on-top: "error"*/
function doSomething() {
var first;
var second; //multiple declarations are allowed at the top
if (true) {
first = true;
}
}
function doSomethingElse() {
var i;
for (i=0; i<10; i++) {}
}
```
:::
::: correct
```js
/*eslint vars-on-top: "error"*/
var a;
f();
```
:::
::: correct
```js
/*eslint vars-on-top: "error"*/
class C {
static {
var a;
if (something) {
a = true;
}
}
static {
var a;
f();
}
}
```
:::
::: correct
```js
/*eslint vars-on-top: "error"*/
// Directives may precede variable declarations.
"use strict";
var a;
f();
// Comments can describe variables.
function doSomething() {
// this is the first var.
var first;
// this is the second var.
var second
}
```
:::
## Options
This rule has no options.
---
---
title: wrap-iife
rule_type: layout
---
You can immediately invoke function expressions, but not function declarations. A common technique to create an immediately-invoked function expression (IIFE) is to wrap a function declaration in parentheses. The opening parentheses causes the contained function to be parsed as an expression, rather than a declaration.
```js
// function expression could be unwrapped
var x = function () { return { y: 1 };}();
// function declaration must be wrapped
function () { /* side effects */ }(); // SyntaxError
```
## Rule Details
This rule requires all immediately-invoked function expressions to be wrapped in parentheses.
## Options
This rule has two options, a string option and an object option.
String option:
* `"outside"` enforces always wrapping the *call* expression. The default is `"outside"`.
* `"inside"` enforces always wrapping the *function* expression.
* `"any"` enforces always wrapping, but allows either style.
Object option:
* `"functionPrototypeMethods": true` additionally enforces wrapping function expressions invoked using `.call` and `.apply`. The default is `false`.
### outside
Examples of **incorrect** code for the default `"outside"` option:
::: incorrect
```js
/*eslint wrap-iife: ["error", "outside"]*/
var x = function () { return { y: 1 };}(); // unwrapped
var x = (function () { return { y: 1 };})(); // wrapped function expression
```
:::
Examples of **correct** code for the default `"outside"` option:
::: correct
```js
/*eslint wrap-iife: ["error", "outside"]*/
var x = (function () { return { y: 1 };}()); // wrapped call expression
```
:::
### inside
Examples of **incorrect** code for the `"inside"` option:
::: incorrect
```js
/*eslint wrap-iife: ["error", "inside"]*/
var x = function () { return { y: 1 };}(); // unwrapped
var x = (function () { return { y: 1 };}()); // wrapped call expression
```
:::
Examples of **correct** code for the `"inside"` option:
::: correct
```js
/*eslint wrap-iife: ["error", "inside"]*/
var x = (function () { return { y: 1 };})(); // wrapped function expression
```
:::
### any
Examples of **incorrect** code for the `"any"` option:
::: incorrect
```js
/*eslint wrap-iife: ["error", "any"]*/
var x = function () { return { y: 1 };}(); // unwrapped
```
:::
Examples of **correct** code for the `"any"` option:
::: correct
```js
/*eslint wrap-iife: ["error", "any"]*/
var x = (function () { return { y: 1 };}()); // wrapped call expression
var x = (function () { return { y: 1 };})(); // wrapped function expression
```
:::
### functionPrototypeMethods
Examples of **incorrect** code for this rule with the `"inside", { "functionPrototypeMethods": true }` options:
::: incorrect
```js
/* eslint wrap-iife: [2, "inside", { functionPrototypeMethods: true }] */
var x = function(){ foo(); }()
var x = (function(){ foo(); }())
var x = function(){ foo(); }.call(bar)
var x = (function(){ foo(); }.call(bar))
```
:::
Examples of **correct** code for this rule with the `"inside", { "functionPrototypeMethods": true }` options:
::: correct
```js
/* eslint wrap-iife: [2, "inside", { functionPrototypeMethods: true }] */
var x = (function(){ foo(); })()
var x = (function(){ foo(); }).call(bar)
```
:::
---
---
title: wrap-regex
rule_type: layout
---
When a regular expression is used in certain situations, it can end up looking like a division operator. For example:
```js
function a() {
return /foo/.test("bar");
}
```
## Rule Details
This is used to disambiguate the slash operator and facilitates more readable code.
Example of **incorrect** code for this rule:
::: incorrect
```js
/*eslint wrap-regex: "error"*/
function a() {
return /foo/.test("bar");
}
```
:::
Example of **correct** code for this rule:
::: correct
```js
/*eslint wrap-regex: "error"*/
function a() {
return (/foo/).test("bar");
}
```
:::
---
---
title: yield-star-spacing
rule_type: layout
further_reading:
- https://leanpub.com/understandinges6/read/#leanpub-auto-generators
---
## Rule Details
This rule enforces spacing around the `*` in `yield*` expressions.
## Options
The rule takes one option, an object, which has two keys `before` and `after` having boolean values `true` or `false`.
* `before` enforces spacing between the `yield` and the `*`.
If `true`, a space is required, otherwise spaces are disallowed.
* `after` enforces spacing between the `*` and the argument.
If it is `true`, a space is required, otherwise spaces are disallowed.
The default is `{"before": false, "after": true}`.
```json
"yield-star-spacing": ["error", {"before": true, "after": false}]
```
The option also has a string shorthand:
* `{"before": false, "after": true}` → `"after"`
* `{"before": true, "after": false}` → `"before"`
* `{"before": true, "after": true}` → `"both"`
* `{"before": false, "after": false}` → `"neither"`
```json
"yield-star-spacing": ["error", "after"]
```
### after
Examples of **correct** code for this rule with the default `"after"` option:
::: correct
```js
/*eslint yield-star-spacing: ["error", "after"]*/
function* generator() {
yield* other();
}
```
:::
### before
Examples of **correct** code for this rule with the `"before"` option:
::: correct
```js
/*eslint yield-star-spacing: ["error", "before"]*/
function *generator() {
yield *other();
}
```
:::
### both
Examples of **correct** code for this rule with the `"both"` option:
::: correct
```js
/*eslint yield-star-spacing: ["error", "both"]*/
function * generator() {
yield * other();
}
```
:::
### neither
Examples of **correct** code for this rule with the `"neither"` option:
::: correct
```js
/*eslint yield-star-spacing: ["error", "neither"]*/
function*generator() {
yield*other();
}
```
:::
## When Not To Use It
If your project will not be using generators or you are not concerned with spacing consistency, you do not need this rule.
---
---
title: yoda
rule_type: suggestion
further_reading:
- https://en.wikipedia.org/wiki/Yoda_conditions
- http://thomas.tuerke.net/on/design/?with=1249091668#msg1146181680
---
Yoda conditions are so named because the literal value of the condition comes first while the variable comes second. For example, the following is a Yoda condition:
```js
if ("red" === color) {
// ...
}
```
This is called a Yoda condition because it reads as, "if red equals the color", similar to the way the Star Wars character Yoda speaks. Compare to the other way of arranging the operands:
```js
if (color === "red") {
// ...
}
```
This typically reads, "if the color equals red", which is arguably a more natural way to describe the comparison.
Proponents of Yoda conditions highlight that it is impossible to mistakenly use `=` instead of `==` because you cannot assign to a literal value. Doing so will cause a syntax error and you will be informed of the mistake early on. This practice was therefore very common in early programming where tools were not yet available.
Opponents of Yoda conditions point out that tooling has made us better programmers because tools will catch the mistaken use of `=` instead of `==` (ESLint will catch this for you). Therefore, they argue, the utility of the pattern doesn't outweigh the readability hit the code takes while using Yoda conditions.
## Rule Details
This rule aims to enforce consistent style of conditions which compare a variable to a literal value.
## Options
This rule can take a string option:
* If it is the default `"never"`, then comparisons must never be Yoda conditions.
* If it is `"always"`, then the literal value must always come first.
The default `"never"` option can have exception options in an object literal:
* If the `"exceptRange"` property is `true`, the rule *allows* Yoda conditions in range comparisons which are wrapped directly in parentheses, including the parentheses of an `if` or `while` condition. The default value is `false`. A *range* comparison tests whether a variable is inside or outside the range between two literal values.
* If the `"onlyEquality"` property is `true`, the rule reports Yoda conditions *only* for the equality operators `==` and `===`. The default value is `false`.
The `onlyEquality` option allows a superset of the exceptions which `exceptRange` allows, thus both options are not useful together.
### never
Examples of **incorrect** code for the default `"never"` option:
::: incorrect
```js
/*eslint yoda: "error"*/
if ("red" === color) {
// ...
}
if (`red` === color) {
// ...
}
if (`red` === `${color}`) {
// ...
}
if (true == flag) {
// ...
}
if (5 > count) {
// ...
}
if (-1 < str.indexOf(substr)) {
// ...
}
if (0 <= x && x < 1) {
// ...
}
```
:::
Examples of **correct** code for the default `"never"` option:
::: correct
```js
/*eslint yoda: "error"*/
if (5 & value) {
// ...
}
if (value === "red") {
// ...
}
if (value === `red`) {
// ...
}
if (`${value}` === `red`) {
}
```
:::
### exceptRange
Examples of **correct** code for the `"never", { "exceptRange": true }` options:
::: correct
```js
/*eslint yoda: ["error", "never", { "exceptRange": true }]*/
function isReddish(color) {
return (color.hue < 60 || 300 < color.hue);
}
if (x < -1 || 1 < x) {
// ...
}
if (count < 10 && (0 <= rand && rand < 1)) {
// ...
}
if (`blue` < x && x < `green`) {
// ...
}
function howLong(arr) {
return (0 <= arr.length && arr.length < 10) ? "short" : "long";
}
```
:::
### onlyEquality
Examples of **correct** code for the `"never", { "onlyEquality": true }` options:
::: correct
```js
/*eslint yoda: ["error", "never", { "onlyEquality": true }]*/
if (x < -1 || 9 < x) {
}
if (x !== 'foo' && 'bar' != x) {
}
if (x !== `foo` && `bar` != x) {
}
```
:::
### always
Examples of **incorrect** code for the `"always"` option:
::: incorrect
```js
/*eslint yoda: ["error", "always"]*/
if (color == "blue") {
// ...
}
if (color == `blue`) {
// ...
}
```
:::
Examples of **correct** code for the `"always"` option:
::: correct
```js
/*eslint yoda: ["error", "always"]*/
if ("blue" == value) {
// ...
}
if (`blue` == value) {
// ...
}
if (`blue` == `${value}`) {
// ...
}
if (-1 < str.indexOf(substr)) {
// ...
}
```
:::
---
---
title: Command Line Interface Reference
eleventyNavigation:
key: command line interface
parent: use eslint
title: Command Line Interface Reference
order: 4
---
{%- from 'components/npm_tabs.macro.html' import npm_tabs with context %}
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
The ESLint Command Line Interface (CLI) lets you execute linting from the terminal. The CLI has a variety of options that you can pass to configure ESLint.
## Run the CLI
ESLint requires [Node.js](https://nodejs.org/) for installation. Follow the instructions in the [Getting Started Guide](getting-started) to install ESLint.
Most users use [`npx`](https://docs.npmjs.com/cli/v8/commands/npx) to run ESLint on the command line like this:
{{ npx_tabs ({
package: "eslint",
args: ["[options]", "[file|dir|glob]*"]
}) }}
Such as:
{{ npx_tabs ({
package: "eslint",
args: ["file1.js", "file2.js"],
comment: "Run on two files"
}) }}
or
{{ npx_tabs ({
package: "eslint",
args: ["lib/**"],
comment: "Run on multiple files"
}) }}
Please note that when passing a glob as a parameter, it is expanded by your shell. The results of the expansion can vary depending on your shell, and its configuration. If you want to use node `glob` syntax, you have to quote your parameter (using double quotes if you need it to run in Windows), as follows:
{{ npx_tabs ({
package: "eslint",
args: ["\"lib/**\""]
}) }}
You can also omit the file arguments and ESLint will use `.`. For instance, these two lines perform the same operation:
{{ npx_tabs ({
package: "eslint",
args: ["."]
}) }}
{{ npx_tabs ({
package: "eslint",
args: []
}) }}
**Note:** You can also use alternative package managers such as [Yarn](https://yarnpkg.com/) or [pnpm](https://pnpm.io/) to run ESLint. For pnpm use `pnpm dlx eslint` and for Yarn use `yarn dlx eslint`.
## Pass Multiple Values to an Option
Options that accept multiple values can be specified by repeating the option or with a comma-delimited list (other than [`--ignore-pattern`](#--ignore-pattern), which does not allow the second style).
Examples of options that accept multiple values:
{{ npx_tabs ({
package: "eslint",
args: ["--global", "describe", "--global", "it", "tests/"]
}) }}
OR
{{ npx_tabs ({
package: "eslint",
args: ["--global", "describe,it", "tests/"]
}) }}
## Options
You can view all the CLI options by running `npx eslint -h`.
```txt
eslint [options] file.js [file.js] [dir]
Basic configuration:
--no-config-lookup Disable look up for eslint.config.js
-c, --config path::String Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs
--inspect-config Open the config inspector with the current configuration
--ext [String] Specify additional file extensions to lint
--global [String] Define global variables
--parser String Specify the parser to be used
--parser-options Object Specify parser options
Specify Rules and Plugins:
--plugin [String] Specify plugins
--rule Object Specify rules
Fix Problems:
--fix Automatically fix problems
--fix-dry-run Automatically fix problems without saving the changes to the file system
--fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout)
Ignore Files:
--no-ignore Disable use of ignore files and patterns
--ignore-pattern [String] Patterns of files to ignore
Use stdin:
--stdin Lint code provided on - default: false
--stdin-filename String Specify filename to process STDIN as
Handle Warnings:
--quiet Report errors only - default: false
--max-warnings Int Number of warnings to trigger nonzero exit code - default: -1
Output:
-o, --output-file path::String Specify file to write report to
-f, --format String Use a specific output format - default: stylish
--color, --no-color Force enabling/disabling of color
Inline configuration comments:
--no-inline-config Prevent comments from changing config or rules
--report-unused-disable-directives Adds reported errors for unused eslint-disable and eslint-enable directives
--report-unused-disable-directives-severity String Chooses severity level for reporting unused eslint-disable and eslint-enable directives - either: off, warn, error, 0, 1, or 2
--report-unused-inline-configs String Adds reported errors for unused eslint inline config comments - either: off, warn, error, 0, 1, or 2
Caching:
--cache Only check changed files - default: false
--cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache
--cache-location path::String Path to the cache file or directory
--cache-strategy String Strategy to use for detecting changed files in the cache - either: metadata or content - default: metadata
Suppressing Violations:
--suppress-all Suppress all violations - default: false
--suppress-rule [String] Suppress specific rules
--suppressions-location path::String Specify the location of the suppressions file
--prune-suppressions Prune unused suppressions - default: false
--pass-on-unpruned-suppressions Ignore unused suppressions - default: false
Miscellaneous:
--init Run config initialization wizard - default: false
--env-info Output execution environment information - default: false
--no-error-on-unmatched-pattern Prevent errors when pattern is unmatched
--exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false
--no-warn-ignored Suppress warnings when the file list includes ignored files
--pass-on-no-patterns Exit with exit code 0 in case no file patterns are passed
--debug Output debugging information
-h, --help Show help
-v, --version Output the version number
--print-config path::String Print the configuration for the given file
--stats Add statistics to the lint report - default: false
--flag [String] Enable a feature flag
--mcp Start the ESLint MCP server
--concurrency Int|String Number of linting threads, auto to choose automatically, off for no multithreading - default: off
```
### Basic Configuration
#### `--no-config-lookup`
Disables use of configuration from files.
- **Argument Type**: No argument.
##### `--no-config-lookup` example
{{ npx_tabs ({
package: "eslint",
args: ["--no-config-lookup", "file.js"]
}) }}
#### `-c`, `--config`
This option allows you to specify an additional configuration file for ESLint (see [Configure ESLint](configure/) for more).
- **Argument Type**: String. Path to file.
- **Multiple Arguments**: No
##### `-c`, `--config` example
{{ npx_tabs ({
package: "eslint",
args: ["-c", "~/my.eslint.config.js", "file.js"]
}) }}
This example uses the configuration file at `~/my.eslint.config.js`, which is used instead of searching for an `eslint.config.js` file.
#### `--inspect-config`
This option runs `npx @eslint/config-inspector@latest` to start the [config inspector](https://github.com/eslint/config-inspector). You can use the config inspector to better understand what your configuration is doing and which files it applies to. When you use this flag, the CLI does not perform linting.
- **Argument Type**: No argument.
##### `--inspect-config` example
{{ npx_tabs ({
package: "eslint",
args: ["--inspect-config"]
}) }}
#### `--ext`
This option allows you to specify additional file extensions to lint.
- **Argument Type**: String. File extension.
- **Multiple Arguments**: Yes
- **Default Value**: By default, ESLint lints files with extensions `.js`, `.mjs`, `.cjs`, and additional extensions [specified in the configuration file](configure/configuration-files#specifying-files-with-arbitrary-extensions).
This option is primarily intended for use in combination with the [`--no-config-lookup`](#--no-config-lookup) option, since in that case there is no configuration file in which the additional extensions would be specified.
##### `--ext` example
{{ npx_tabs ({
package: "eslint",
args: [".", "--ext", ".ts"],
comment: "Include .ts files"
}) }}
{{ npx_tabs ({
package: "eslint",
args: [".", "--ext", ".ts", "--ext", ".tsx"],
comment: "Include .ts and .tsx files"
}) }}
{{ npx_tabs ({
package: "eslint",
args: [".", "--ext", ".ts,.tsx"],
comment: "Also include .ts and .tsx files"
}) }}
#### `--global`
This option defines global variables so that they are not flagged as undefined by the [`no-undef`](../rules/no-undef) rule.
- **Argument Type**: String. Name of the global variable. Any specified global variables are assumed to be read-only by default, but appending `:true` to a variable's name ensures that `no-undef` also allows writes.
- **Multiple Arguments**: Yes
##### `--global` example
{{ npx_tabs ({
package: "eslint",
args: ["--global", "require,exports:true", "file.js"]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--global", "require", "--global", "exports:true"]
}) }}
#### `--parser`
This option allows you to specify a parser to be used by ESLint.
- **Argument Type**: String. Parser to be used by ESLint.
- **Multiple Arguments**: No
- **Default Value**: `espree`
##### `--parser` example
{{ npx_tabs ({
package: "eslint",
args: ["--parser", "@typescript-eslint/parser", "file.ts"],
comment: "Use TypeScript ESLint parser"
}) }}
#### `--parser-options`
This option allows you to specify parser options to be used by ESLint. The available parser options are determined by the parser being used.
- **Argument Type**: Key/value pair separated by colon (`:`).
- **Multiple Arguments**: Yes
##### `--parser-options` example
{{ npx_tabs ({
package: "eslint",
args: ["--stdin", "--parser-options", "ecmaVersion:6"],
comment: "fails with a parsing error",
previousCommands: ["echo \'3 ** 4\'"]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--stdin", "--parser-options", "ecmaVersion:7"],
comment: "succeeds, yay!",
previousCommands: ["echo \'3 ** 4\'"]
}) }}
### Specify Rules and Plugins
#### `--plugin`
This option specifies a plugin to load.
- **Argument Type**: String. Plugin name. You can optionally omit the prefix `eslint-plugin-` from the plugin name.
- **Multiple Arguments**: Yes
Before using the plugin, you have to install it using npm.
##### `--plugin` example
{{ npx_tabs ({
package: "eslint",
args: ["--plugin", "jquery", "file.js"]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--plugin", "eslint-plugin-mocha", "file.js"]
}) }}
#### `--rule`
This option specifies the rules to be used.
- **Argument Type**: Rules and their configuration specified with [levn](https://github.com/gkz/levn#levn--) format.
- **Multiple Arguments**: Yes
These rules are merged with any rules specified with configuration files. If the rule is defined in a plugin, you have to prefix the rule ID with the plugin name and a `/`.
To ignore rules in configuration files and only run rules specified in the command line, use the `--rule` flag in combination with the [`--no-config-lookup`](#--no-config-lookup) flag.
##### `--rule` example
{{ npx_tabs ({
package: "eslint",
args: ["--rule", "\'quotes: [error, double]\'"],
comment: "Apply single rule"
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--rule", "\'guard-for-in: error\'", "--rule", "\'brace-style: [error, 1tbs]\'"],
comment: "Apply multiple rules"
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--rule", "\'jquery/dollar-sign: error\'"],
comment: "Apply rule from jquery plugin"
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--rule", "\'quotes: [error, double]\'", "--no-config-lookup"],
comment: "Only apply rule from the command line"
}) }}
### Fix Problems
#### `--fix`
This option instructs ESLint to try to [fix](core-concepts#rule-fixes) as many issues as possible. The fixes are made to the actual files themselves and only the remaining unfixed issues are output.
- **Argument Type**: No argument.
Not all problems are fixable using this option, and the option does not work in these situations:
1. This option throws an error when code is piped to ESLint.
1. This option has no effect on code that uses a processor, unless the processor opts into allowing autofixes.
If you want to fix code from `stdin` or otherwise want to get the fixes without actually writing them to the file, use the [`--fix-dry-run`](#--fix-dry-run) option.
##### `--fix` example
{{ npx_tabs ({
package: "eslint",
args: ["--fix", "file.js"]
}) }}
#### `--fix-dry-run`
This option has the same effect as `--fix` with the difference that the fixes are not saved to the file system. Because the default formatter does not output the fixed code, you'll have to use another formatter (e.g. `--format json`) to get the fixes.
- **Argument Type**: No argument.
This makes it possible to fix code from `stdin` when used with the `--stdin` flag.
This flag can be useful for integrations (e.g. editor plugins) which need to autofix text from the command line without saving it to the filesystem.
##### `--fix-dry-run` example
{{ npx_tabs ({
package: "eslint",
args: ["--stdin", "--fix-dry-run", "--format", "json"],
previousCommands: ["getSomeText"]
}) }}
#### `--fix-type`
This option allows you to specify the type of fixes to apply when using either `--fix` or `--fix-dry-run`.
- **Argument Type**: String. One of the following fix types:
1. `problem` - fix potential errors in the code
1. `suggestion` - apply fixes to the code that improve it
1. `layout` - apply fixes that do not change the program structure (AST)
1. `directive` - apply fixes to inline directives such as `// eslint-disable`
- **Multiple Arguments**: Yes
This option is helpful if you are using another program to format your code, but you would still like ESLint to apply other types of fixes.
##### `--fix-type` example
{{ npx_tabs ({
package: "eslint",
args: ["--fix", "--fix-type", "suggestion", "."]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--fix", "--fix-type", "suggestion", "--fix-type", "problem", "."]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--fix", "--fix-type", "suggestion,layout", "."]
}) }}
### Ignore Files
#### `--no-ignore`
Disables excluding of files from [`--ignore-pattern`](#--ignore-pattern) flags and the `ignores` property in configuration.
- **Argument Type**: No argument.
##### `--no-ignore` example
{{ npx_tabs ({
package: "eslint",
args: ["--no-ignore", "file.js"]
}) }}
#### `--ignore-pattern`
This option allows you to specify patterns of files to ignore.
- **Argument Type**: String. The supported syntax is the same as for [`ignores` patterns](configure/configuration-files#excluding-files-with-ignores), which use [minimatch](https://www.npmjs.com/package/minimatch) syntax. You should quote your patterns in order to avoid shell interpretation of glob patterns.
- **Multiple Arguments**: Yes
##### `--ignore-pattern` example
{{ npx_tabs ({
package: "eslint",
args: ["--ignore-pattern", "\"/lib/\"", "--ignore-pattern", "\"/src/vendor/*\"", "."]
}) }}
### Use stdin
#### `--stdin`
This option tells ESLint to read and lint source code from STDIN instead of from files. You can use this to pipe code to ESLint.
- **Argument Type**: No argument.
##### `--stdin` example
{{ npx_tabs ({
package: "eslint",
args: ["--stdin"],
previousCommands: ["cat myFile.js"]
}) }}
#### `--stdin-filename`
This option allows you to specify a filename to process STDIN as.
- **Argument Type**: String. Path to file.
- **Multiple Arguments**: No
This is useful when processing files from STDIN and you have rules which depend on the filename.
##### `--stdin-filename` example
{{ npx_tabs ({
package: "eslint",
args: ["--stdin", "--stdin-filename", "myfile.js"],
previousCommands: ["cat myFile.js"]
}) }}
### Handle Warnings
#### `--quiet`
This option allows you to disable reporting on warnings and running of rules set to warn. If you enable this option, only errors are reported by ESLint and only rules set to error will be run.
- **Argument Type**: No argument.
##### `--quiet` example
{{ npx_tabs ({
package: "eslint",
args: ["--quiet", "file.js"]
}) }}
#### `--max-warnings`
This option allows you to specify a warning threshold, which can be used to force ESLint to exit with an error status if there are too many warning-level rule violations in your project.
- **Argument Type**: Integer. The maximum number of warnings to allow. To prevent this behavior, do not use this option or specify `-1` as the argument.
- **Multiple Arguments**: No
Normally, if ESLint runs and finds no errors (only warnings), it exits with a success exit status. However, if `--max-warnings` is specified and the total warning count is greater than the specified threshold, ESLint exits with an error status.
::: important
When used alongside `--quiet`, this will cause rules marked as warn to still be run, but not reported.
:::
##### `--max-warnings` example
{{ npx_tabs ({
package: "eslint",
args: ["--max-warnings", "10", "file.js"]
}) }}
### Output
#### `-o`, `--output-file`
Write the output of linting results to a specified file.
- **Argument Type**: String. Path to file.
- **Multiple Arguments**: No
##### `-o`, `--output-file` example
{{ npx_tabs ({
package: "eslint",
args: ["-o", "./test/test.html"]
}) }}
#### `-f`, `--format`
This option specifies the output format for the console.
- **Argument Type**: String. One of the [built-in formatters](formatters/) or a custom formatter.
- **Multiple Arguments**: No
- **Default Value**: [`stylish`](formatters/#stylish)
If you are using a custom formatter defined in a local file, you can specify the path to the custom formatter file.
An npm-installed formatter is resolved with or without `eslint-formatter-` prefix.
When specified, the given format is output to the console. If you'd like to save that output into a file, you can do so on the command line like so:
{{ npx_tabs ({
package: "eslint",
args: ["-f", "json", "file.js", ">", "results.json"],
comment: "Saves the output into the `results.json` file."
}) }}
##### `-f`, `--format` example
Use the built-in `json` formatter:
{{ npx_tabs ({
package: "eslint",
args: ["--format", "json", "file.js"]
}) }}
Use a local custom formatter:
{{ npx_tabs ({
package: "eslint",
args: ["-f", "./customformat.js", "file.js"]
}) }}
Use an npm-installed formatter:
{{ npm_tabs({
command: "install",
packages: ["eslint-formatter-pretty"],
args: []
}) }}
Then run one of the following commands
{{ npx_tabs ({
package: "eslint",
args: ["-f", "pretty", "file.js"]
}) }}
or alternatively
{{ npx_tabs ({
package: "eslint",
args: ["-f", "eslint-formatter-pretty", "file.js"]
}) }}
#### `--color` and `--no-color`
These options force the enabling/disabling of colorized output.
- **Argument Type**: No argument.
You can use these options to override the default behavior, which is to enable colorized output unless no TTY is detected, such as when piping `eslint` through `cat` or `less`.
::: warning
When neither `--color` nor `--no-color` is specified, the formatter may decide whether to colorize the output based on the runtime environment. For example, when using the default `stylish` formatter under Node.js, [`FORCE_COLOR`](https://nodejs.org/api/cli.html#force_color1-2-3), [`NO_COLOR`](https://nodejs.org/api/cli.html#no_colorany), or [`NODE_DISABLE_COLORS`](https://nodejs.org/api/cli.html#node_disable_colors1) environment variables may affect whether colors are used.
:::
##### `--color` and `--no-color` example
{{ npx_tabs ({
package: "eslint",
args: ["--color", "file.js", "|", "cat"]
}) }}
{{ npx_tabs ({
package: "eslint",
args: ["--no-color", "file.js"]
}) }}
### Inline Configuration Comments
#### `--no-inline-config`
This option prevents inline comments like `/*eslint-disable*/` or
`/*global foo*/` from having any effect.
- **Argument Type**: No argument.
This allows you to set an ESLint config without files modifying it. All inline config comments are ignored, such as:
- `/*eslint-disable*/`
- `/*eslint-enable*/`
- `/*global*/`
- `/*eslint*/`
- `// eslint-disable-line`
- `// eslint-disable-next-line`
##### `--no-inline-config` example
{{ npx_tabs ({
package: "eslint",
args: ["--no-inline-config", "file.js"]
}) }}
#### `--report-unused-disable-directives`
This option causes ESLint to report directive comments like `// eslint-disable-line` when no errors would have been reported on that line anyway.
- **Argument Type**: No argument.
This can be useful to prevent future errors from unexpectedly being suppressed, by cleaning up old `eslint-disable` and `eslint-enable` comments which are no longer applicable.
::: warning
When using this option, it is possible that new errors start being reported whenever ESLint or custom rules are upgraded.
For example, suppose a rule has a bug that causes it to report a false positive, and an `eslint-disable` comment is added to suppress the incorrect report. If the bug is then fixed in a patch release of ESLint, the `eslint-disable` comment becomes unused since ESLint is no longer generating an incorrect report. This results in a new reported error for the unused directive if the `--report-unused-disable-directives` option is used.
:::
##### `--report-unused-disable-directives` example
{{ npx_tabs ({
package: "eslint",
args: ["--report-unused-disable-directives", "file.js"]
}) }}
#### `--report-unused-disable-directives-severity`
Same as [`--report-unused-disable-directives`](#--report-unused-disable-directives), but allows you to specify the severity level (`error`, `warn`, `off`) of the reported errors. Only one of these two options can be used at a time.
- **Argument Type**: String. One of the following values:
1. `off` (or `0`)
1. `warn` (or `1`)
1. `error` (or `2`)
- **Multiple Arguments**: No
- **Default Value**: By default, `linterOptions.reportUnusedDisableDirectives` configuration setting is used (which defaults to `"warn"`).
##### `--report-unused-disable-directives-severity` example
{{ npx_tabs ({
package: "eslint",
args: ["--report-unused-disable-directives-severity", "warn", "file.js"]
}) }}
#### `--report-unused-inline-configs`
This option causes ESLint to report inline config comments like `/* eslint rule-name: "error" */` whose rule severity and any options match what's already been configured.
- **Argument Type**: String. One of the following values:
1. `off` (or `0`)
1. `warn` (or `1`)
1. `error` (or `2`)
- **Multiple Arguments**: No
- **Default Value**: By default, `linterOptions.reportUnusedInlineConfigs` configuration setting is used (which defaults to `"off"`).
This can be useful to keep files clean and devoid of misleading clutter.
Inline config comments are meant to change ESLint's behavior in some way: if they change nothing, there is no reason to leave them in.
##### `--report-unused-inline-configs` example
```shell
npx eslint --report-unused-inline-configs error file.js
```
### Caching
#### `--cache`
Store the info about processed files in order to only operate on the changed ones. Enabling this option can dramatically improve ESLint's run time performance by ensuring that only changed files are linted.
The cache is stored in `.eslintcache` by default.
- **Argument Type**: No argument.
If you run ESLint with `--cache` and then run ESLint without `--cache`, the `.eslintcache` file will be deleted. This is necessary because the results of the lint might change and make `.eslintcache` invalid. If you want to control when the cache file is deleted, then use `--cache-location` to specify an alternate location for the cache file.
Autofixed files are not placed in the cache. Subsequent linting that does not trigger an autofix will place it in the cache.
##### `--cache` example
{{ npx_tabs ({
package: "eslint",
args: ["--cache", "file.js"]
}) }}
#### `--cache-file`
**Deprecated**: Use `--cache-location` instead.
Path to the cache file. If none specified `.eslintcache` is used. The file is created in the directory where the `eslint` command is executed.
#### `--cache-location`
Specify the path to the cache location. Can be a file or a directory.
- **Argument Type**: String. Path to file or directory. If a directory is specified, a cache file is created inside the specified folder. The name of the file is based on the hash of the current working directory, e.g.: `.cache_hashOfCWD`.
- **Multiple Arguments**: No
- **Default Value**: If no location is specified, `.eslintcache` is used. The file is created in the directory where the `eslint` command is executed.
If the directory for the cache does not exist make sure you add a trailing `/` on \*nix systems or `\` on Windows. Otherwise, the path is assumed to be a file.
##### `--cache-location` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--cache", "--cache-location", "\"/Users/user/.eslintcache/\""]
}) }}
#### `--cache-strategy`
Strategy for the cache to use for detecting changed files.
- **Argument Type**: String. One of the following values:
1. `metadata`
1. `content`
- **Multiple Arguments**: No
- **Default Value**: `metadata`
The `content` strategy can be useful in cases where the modification time of your files changes even if their contents have not. For example, this can happen during git operations like [`git clone`](https://git-scm.com/docs/git-clone) because git does not track file modification time.
##### `--cache-strategy` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--cache", "--cache-strategy", "content"]
}) }}
### Suppressing Violations
#### `--suppress-all`
Suppresses existing violations, so that they are not being reported in subsequent runs. It allows you to enable one or more lint rules and be notified only when new violations show up. The suppressions are stored in `eslint-suppressions.json` by default, unless otherwise specified by `--suppressions-location`. The file gets updated with the new suppressions.
- **Argument Type**: No argument.
##### `--suppress-all` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--suppress-all"]
}) }}
#### `--suppress-rule`
Suppresses violations for specific rules, so that they are not being reported in subsequent runs. Similar to `--suppress-all`, the suppressions are stored in `eslint-suppressions.json` by default, unless otherwise specified by `--suppressions-location`. The file gets updated with the new suppressions.
- **Argument Type**: String. Rule ID.
- **Multiple Arguments**: Yes
##### `--suppress-rule` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--suppress-rule", "no-console", "--suppress-rule", "indent"]
}) }}
#### `--suppressions-location`
Specify the path to the suppressions location. Can be a file or a directory.
- **Argument Type**: String. Path to file. If a directory is specified, a cache file is created inside the specified folder. The name of the file is based on the hash of the current working directory, e.g.: `suppressions_hashOfCWD`
- **Multiple Arguments**: No
- **Default Value**: If no location is specified, `eslint-suppressions.json` is used. The file is created in the directory where the `eslint` command is executed.
##### `--suppressions-location` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--suppressions-location", "\".eslint-suppressions-example.json\""]
}) }}
#### `--prune-suppressions`
Prune unused suppressions from the suppressions file. This option is useful when you addressed one or more of the suppressed violations.
- **Argument Type**: No argument.
##### `--prune-suppressions` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--prune-suppressions"]
}) }}
#### `--pass-on-unpruned-suppressions`
Ignore unused suppressions. By default, ESLint exits with exit code `2` and displays an error message if there are unused suppressions in the suppressions file. When you use this flag, unused suppressions do not affect the exit code and ESLint doesn't output an error about unused suppressions.
- **Argument Type**: No argument.
##### `--pass-on-unpruned-suppressions` example
{{ npx_tabs ({
package: "eslint",
args: ["\"src/**/*.js\"", "--pass-on-unpruned-suppressions"]
}) }}
### Miscellaneous
#### `--init`
This option runs `npm init @eslint/config` to start the config initialization wizard. It's designed to help new users quickly create an `eslint.config.js` file by answering a few questions. When you use this flag, the CLI does not perform linting.
- **Argument Type**: No argument.
The resulting configuration file is created in the current directory.
##### `--init` example
{{ npx_tabs ({
package: "eslint",
args: ["--init"]
}) }}
#### `--env-info`
This option outputs information about the execution environment, including the version of Node.js, npm, and local and global installations of ESLint.
- **Argument Type**: No argument.
The ESLint team may ask for this information to help solve bugs. When you use this flag, the CLI does not perform linting.
##### `--env-info` example
{{ npx_tabs ({
package: "eslint",
args: ["--env-info"]
}) }}
#### `--no-error-on-unmatched-pattern`
This option prevents errors when a quoted glob pattern is unmatched. This does not prevent errors when your shell can't match a glob.
- **Argument Type**: No argument.
##### `--no-error-on-unmatched-pattern` example
{{ npx_tabs ({
package: "eslint",
args: ["--no-error-on-unmatched-pattern", "--ext", ".ts", "\"lib/*\""]
}) }}
#### `--exit-on-fatal-error`
This option causes ESLint to exit with exit code 2 if one or more fatal parsing errors occur. Without this option, ESLint reports fatal parsing errors as rule violations.
- **Argument Type**: No argument.
##### `--exit-on-fatal-error` example
{{ npx_tabs ({
package: "eslint",
args: ["--exit-on-fatal-error", "file.js"]
}) }}
#### `--no-warn-ignored`
This option suppresses both `File ignored by default` and `File ignored because of a matching ignore pattern` warnings when an ignored filename is passed explicitly. It is useful when paired with `--max-warnings 0` as it will prevent exit code 1 due to the aforementioned warning.
- **Argument Type**: No argument.
##### `--no-warn-ignored` example
{{ npx_tabs ({
package: "eslint",
args: ["--no-warn-ignored", "--max-warnings", "0", "ignored-file.js"]
}) }}
#### `--pass-on-no-patterns`
This option allows ESLint to exit with code 0 when no file or directory patterns are passed. Without this option, ESLint assumes you want to use `.` as the pattern.
- **Argument Type**: No argument.
##### `--pass-on-no-patterns` example
{{ npx_tabs ({
package: "eslint",
args: ["--pass-on-no-patterns"]
}) }}
#### `--debug`
This option outputs debugging information to the console. Add this flag to an ESLint command line invocation in order to get extra debugging information while the command runs.
- **Argument Type**: No argument.
This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.
##### `--debug` example
{{ npx_tabs ({
package: "eslint",
args: ["--debug", "test.js"]
}) }}
#### `-h`, `--help`
This option outputs the help menu, displaying all of the available options. All other options are ignored when this is present. When you use this flag, the CLI does not perform linting.
- **Argument Type**: No argument.
##### `-h`, `--help` example
{{ npx_tabs ({
package: "eslint",
args: ["--help"]
}) }}
#### `-v`, `--version`
This option outputs the current ESLint version onto the console. All other options are ignored when this is present. When you use this flag, the CLI does not perform linting.
- **Argument Type**: No argument.
##### `-v`, `--version` example
{{ npx_tabs ({
package: "eslint",
args: ["--version"]
}) }}
#### `--print-config`
This option outputs the configuration to be used for the file passed. When present, no linting is performed and only config-related options are valid. When you use this flag, the CLI does not perform linting.
- **Argument Type**: String. Path to file.
- **Multiple Arguments**: No
##### `--print-config` example
{{ npx_tabs ({
package: "eslint",
args: ["--print-config", "file.js"]
}) }}
#### `--stats`
This option adds a series of detailed performance statistics (see [Stats type](../extend/stats#-stats-type)) such as the _parse_-, _fix_- and _lint_-times (time per rule) to [`result`](../integrate/nodejs-api#-lintresult-type) objects that are passed to the formatter (see [Stats CLI usage](../extend/stats#cli-usage)).
- **Argument Type**: No argument.
This option is intended for use with custom formatters that display statistics. It can also be used with the built-in `json` formatter.
##### `--stats` example
{{ npx_tabs ({
package: "eslint",
args: ["--stats", "--format", "json", "file.js"]
}) }}
#### `--flag`
This option enables one or more feature flags for ESLint.
- **Argument Type**: String. A feature identifier.
- **Multiple Arguments**: Yes
##### `--flag` example
{{ npx_tabs ({
package: "eslint",
args: ["--flag", "x_feature", "file.js"]
}) }}
#### `--mcp`
This option starts the ESLint MCP server for use with AI agents.
- **Argument Type**: No argument.
- **Multiple Arguments**: No
##### `--mcp` example
{{ npx_tabs ({
package: "eslint",
args: ["--mcp"]
}) }}
#### `--concurrency`
This option controls the number of worker threads used to lint files.
- **Argument Type**: Int|String. A positive integer, `auto` or `off`.
- **Multiple Arguments**: No
- **Default Value**: `off`
The value `off` causes all files to be linted in the main thread. The value `auto` attempts to determine the best setting automatically.
##### `--concurrency` example
{{ npx_tabs ({
package: "eslint",
args: ["--concurrency", "auto"]
}) }}
## Exit Codes
When linting files, ESLint exits with one of the following exit codes:
- `0`: Linting was successful and there are no linting errors. If the [`--max-warnings`](#--max-warnings) flag is set to `n`, the number of linting warnings is at most `n`.
- `1`: Linting was successful and there is at least one linting error, or there are more linting warnings than allowed by the [`--max-warnings`](#--max-warnings) option.
- `2`: Linting was unsuccessful due to a configuration problem or an internal error.
---
---
title: Combine Configs
eleventyNavigation:
key: combine configs
parent: configure
title: Combine Configs
order: 6
---
In many cases, you won't write an ESLint config file from scratch, but rather, you'll use a combination of predefined and shareable configs along with your own overrides to create the config for your project. This page explains some of the patterns you can use to combine configs in your configuration file.
## Apply a Config Object
If you are importing a [config object](../core-concepts/glossary#config-object) from another module, you can apply it to just a subset of files by creating a new object with a `files` key and using the `extends` key to merge in the rest of the properties from the imported object. For example:
```js
// eslint.config.js
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",
},
},
]);
```
Here, the `"js/recommended"` predefined configuration is applied to files that match the pattern `"**/*.js"` first and then adds the desired configuration for `no-unused-vars`.
## Apply a Config Array
If you are importing a [config array](../core-concepts/glossary#config-array) from another module, you can apply a config array (an array of configuration objects) to just a subset of files by using the `extends` key. For example:
```js
// eslint.config.js
import exampleConfigs from "eslint-config-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
extends: [exampleConfigs],
rules: {
"no-unused-vars": "warn",
},
},
]);
```
Here, the `exampleConfigs` shareable configuration is applied to files that match the pattern "`**/*.js"` first and then another configuration object adds the desired configuration for `no-unused-vars`.
---
---
title: Configuration Files (Deprecated)
---
::: warning
This config system is deprecated and not enabled by default. To opt-in, set the `ESLINT_USE_FLAT_CONFIG` environment variable to `false`. [View the updated documentation](configuration-files).
:::
You can put your ESLint project configuration in a configuration file. You can include built-in rules, how you want them enforced, plugins with custom rules, shareable configurations, which files you want rules to apply to, and more.
## Configuration File Formats
ESLint supports configuration files in several formats:
- **JavaScript** - use `.eslintrc.js` and export an object containing your configuration.
- **JavaScript (ESM)** - use `.eslintrc.cjs` when running ESLint in JavaScript packages that specify `"type":"module"` in their `package.json`. Note that ESLint does not support ESM configuration at this time.
- **YAML** - use `.eslintrc.yaml` or `.eslintrc.yml` to define the configuration structure.
- **JSON** - use `.eslintrc.json` to define the configuration structure. ESLint's JSON files also allow JavaScript-style comments.
- **package.json** - create an `eslintConfig` property in your `package.json` file and define your configuration there.
If there are multiple configuration files in the same directory, ESLint only uses one. The priority order is as follows:
1. `.eslintrc.js`
1. `.eslintrc.cjs`
1. `.eslintrc.yaml`
1. `.eslintrc.yml`
1. `.eslintrc.json`
1. `package.json`
## Using Configuration Files
There are two ways to use configuration files.
The first way to use configuration files is via `.eslintrc.*` and `package.json` files. ESLint automatically looks for them in the directory of the file to be linted, and in successive parent directories all the way up to the root directory of the filesystem (`/`), the home directory of the current user (`~/`), or when `root: true` is specified. See [Cascading and Hierarchy](#cascading-and-hierarchy) below for more details on this. Configuration files can be useful when you want different configurations for different parts of a project or when you want others to be able to use ESLint directly without needing to remember to pass in the configuration file.
The second way to use configuration files is to save the file wherever you would like and pass its location to the CLI using the `--config` option, such as:
```shell
eslint -c myconfig.json myfiletotest.js
```
If you are using one configuration file and want ESLint to ignore any `.eslintrc.*` files, make sure to use `--no-eslintrc` along with the [`--config`](../../use/command-line-interface#-c---config) flag.
Here's an example JSON configuration file that uses the `typescript-eslint` parser to support TypeScript syntax:
```json
{
"root": true,
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/strict-boolean-expressions": [
2,
{
"allowString": false,
"allowNumber": false
}
]
},
"ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
}
```
### Comments in configuration files
Both the JSON and YAML configuration file formats support comments (`package.json` files should not include them). You can use JavaScript-style comments for JSON files and YAML-style comments for YAML files. ESLint safely ignores comments in configuration files. This allows your configuration files to be more human-friendly.
For JavaScript-style comments:
```js
{
"env": {
"browser": true
},
"rules": {
// Override our default settings just for this directory
"eqeqeq": "warn",
"strict": "off"
}
}
```
For YAML-style comments:
```yaml
env:
browser: true
rules:
# Override default settings
eqeqeq: warn
strict: off
```
## Adding Shared Settings
ESLint supports adding shared settings into configuration files. Plugins use `settings` to specify the information that should be shared across all of its rules. You can add a `settings` object to the ESLint configuration file and it is supplied to every executed rule. This may be useful if you are adding custom rules and want them to have access to the same information and be easily configurable.
In JSON:
```json
{
"settings": {
"sharedData": "Hello"
}
}
```
And in YAML:
```yaml
---
settings:
sharedData: "Hello"
```
## Cascading and Hierarchy
When using `.eslintrc.*` and `package.json` files for configuration, you can take advantage of configuration cascading. Suppose your project has the following structure:
```text
your-project
├── .eslintrc.json
├── lib
│ └── source.js
└─┬ tests
├── .eslintrc.json
└── test.js
```
The configuration cascade works based on the location of the file being linted. If there is an `.eslintrc` file in the same directory as the file being linted, then that configuration takes precedence. ESLint then searches up the directory structure, merging any `.eslintrc` files it finds along the way until reaching either an `.eslintrc` file with `root: true` or the root directory.
In the same way, if there is a `package.json` file in the root directory with an `eslintConfig` field, the configuration it describes is applied to all subdirectories beneath it. However, the configuration described by the `.eslintrc` file in the `tests/` directory overrides conflicting specifications.
```text
your-project
├── package.json
├── lib
│ └── source.js
└─┬ tests
├── .eslintrc.json
└── test.js
```
If there is an `.eslintrc` and a `package.json` file found in the same directory, `.eslintrc` takes priority and the `package.json` file is not used.
By default, ESLint looks for configuration files in all parent folders up to the root directory. This can be useful if you want all of your projects to follow a certain convention, but can sometimes lead to unexpected results. To limit ESLint to a specific project, place `"root": true` inside the `.eslintrc.*` file or `eslintConfig` field of the `package.json` file or in the `.eslintrc.*` file at your project's root level. ESLint stops looking in parent folders once it finds a configuration with `"root": true`.
```js
{
"root": true
}
```
And in YAML:
```yaml
---
root: true
```
For example, consider `projectA` which has `"root": true` set in the `.eslintrc` file in the `lib/` directory. In this case, while linting `main.js`, the configurations within `lib/` are used, but the `.eslintrc` file in `projectA/` is not.
```text
home
└── user
└── projectA
├── .eslintrc.json <- Not used
└── lib
├── .eslintrc.json <- { "root": true }
└── main.js
```
The complete configuration hierarchy, from highest to lowest precedence, is as follows:
1. Inline configuration
1. `/*eslint-disable*/` and `/*eslint-enable*/`
1. `/*global*/`
1. `/*eslint*/`
1. `/*eslint-env*/`
1. Command line options (or CLIEngine equivalents):
1. `--global`
1. `--rule`
1. `--env`
1. `-c`, `--config`
1. Project-level configuration:
1. `.eslintrc.*` or `package.json` file in the same directory as the linted file
1. Continue searching for `.eslintrc.*` and `package.json` files in ancestor directories up to and including the root directory or until a config with `"root": true` is found.
Please note that the [home directory of the current user on your preferred operating system](https://nodejs.org/api/os.html#os_os_homedir) (`~/`) is also considered a root directory in this context and searching for configuration files stops there as well. And with the [removal of support for Personal Configuration Files](configuration-files-deprecated#personal-configuration-files-deprecated) from the 8.0.0 release forward, configuration files present in that directory are ignored.
## Extending Configuration Files
A configuration file, once extended, can inherit all the traits of another configuration file (including rules, plugins, and language options) and modify all the options. As a result, there are three configurations, as defined below:
- Base config: the configuration that is extended.
- Derived config: the configuration that extends the base configuration.
- Resulting actual config: the result of merging the derived configuration into the base configuration.
The `extends` property value is either:
- a string that specifies a configuration (either a path to a config file, the name of a shareable config, `eslint:recommended`, or `eslint:all`).
- an array of strings where each additional configuration extends the preceding configurations.
ESLint extends configurations recursively, so a base configuration can also have an `extends` property. Relative paths and shareable config names in an `extends` property are resolved from the location of the config file where they appear.
The `eslint-config-` prefix can be omitted from the configuration name. For example, `airbnb` resolves as `eslint-config-airbnb`.
The `rules` property can do any of the following to extend (or override) the set of rules:
- enable additional rules
- change an inherited rule's severity without changing its options:
- Base config: `"eqeqeq": ["error", "allow-null"]`
- Derived config: `"eqeqeq": "warn"`
- Resulting actual config: `"eqeqeq": ["warn", "allow-null"]`
- override options for rules from base configurations:
- Base config: `"quotes": ["error", "single", "avoid-escape"]`
- Derived config: `"quotes": ["error", "single"]`
- Resulting actual config: `"quotes": ["error", "single"]`
- override options for rules given as object from base configurations:
- Base config: `"max-lines": ["error", { "max": 200, "skipBlankLines": true, "skipComments": true }]`
- Derived config: `"max-lines": ["error", { "max": 100 }]`
- Resulting actual config: `"max-lines": ["error", { "max": 100 }]` where `skipBlankLines` and `skipComments` default to `false`
### Using a shareable configuration package
A [sharable configuration](../../extend/shareable-configs) is an npm package that exports a configuration object. Make sure that you have installed the package in your project root directory, so that ESLint can require it.
The `extends` property value can omit the `eslint-config-` prefix of the package name.
The `npm init @eslint/config` command can create a configuration so you can extend a popular style guide (for example, `eslint-config-standard`).
Example of a configuration file in YAML format:
```yaml
extends: standard
rules:
comma-dangle:
- error
- always
no-empty: warn
```
### Using `eslint:recommended`
Using `"eslint:recommended"` in the `extends` property enables a subset of core rules that report common problems (these rules are identified with a checkmark (recommended) on the [rules page](../../rules/)).
Here's an example of extending `eslint:recommended` and overriding some of the set configuration options:
Example of a configuration file in JavaScript format:
```js
module.exports = {
extends: "eslint:recommended",
rules: {
// enable additional rules
indent: ["error", 4],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double"],
semi: ["error", "always"],
// override configuration set by extending "eslint:recommended"
"no-empty": "warn",
"no-cond-assign": ["error", "always"],
// disable rules from base configurations
"for-direction": "off",
},
};
```
### Using a configuration from a plugin
A [plugin](../../extend/plugins) is an npm package that can add various extensions to ESLint. A plugin can perform numerous functions, including but not limited to adding new rules and exporting [shareable configurations](../../extend/plugins#configs-in-plugins). Make sure the package has been installed in a directory where ESLint can require it.
The `plugins` [property value](./plugins#configure-plugins) can omit the `eslint-plugin-` prefix of the package name.
The `extends` property value can consist of:
- `plugin:`
- the package name (from which you can omit the prefix, for example, `react` is short for `eslint-plugin-react`)
- `/`
- the configuration name (for example, `recommended`)
Example of a configuration file in JSON format:
```json
{
"plugins": ["react"],
"extends": ["eslint:recommended", "plugin:react/recommended"],
"rules": {
"react/no-set-state": "off"
}
}
```
### Using a configuration file
The `extends` property value can be an absolute or relative path to a base [configuration file](#using-configuration-files). ESLint resolves a relative path to a base configuration file relative to the configuration file that uses it.
Example of a configuration file in JSON format:
```json
{
"extends": [
"./node_modules/coding-standard/eslintDefaults.js",
"./node_modules/coding-standard/.eslintrc-es6",
"./node_modules/coding-standard/.eslintrc-jsx"
],
"rules": {
"eqeqeq": "warn"
}
}
```
### Using `"eslint:all"`
The `extends` property value can be `"eslint:all"` to enable all core rules in the currently installed version of ESLint. The set of core rules can change at any minor or major version of ESLint.
**Important:** This configuration is **not recommended for production use** because it changes with every minor and major version of ESLint. Use it at your own risk.
You might enable all core rules as a shortcut to explore rules and options while you decide on the configuration for a project, especially if you rarely override options or disable rules. The default options for rules are not endorsements by ESLint (for example, the default option for the [`quotes`](../../rules/quotes) rule does not mean double quotes are better than single quotes).
If your configuration extends `eslint:all`, after you upgrade to a newer major or minor version of ESLint, review the reported problems before you use the `--fix` option on the [command line](../command-line-interface#--fix), so you know if a new fixable rule will make changes to the code.
Example of a configuration file in JavaScript format:
```js
module.exports = {
extends: "eslint:all",
rules: {
// override default options
"comma-dangle": ["error", "always"],
indent: ["error", 2],
"no-cond-assign": ["error", "always"],
// disable now, but enable in the future
"one-var": "off", // ["error", "never"]
// disable
"init-declarations": "off",
"no-console": "off",
"no-inline-comments": "off",
},
};
```
## Configuration Based on Glob Patterns
**v4.1.0+.** Sometimes a more fine-controlled configuration is necessary, like if the configuration for files within the same directory has to be different. In this case, you can provide configurations under the `overrides` key that only apply to files that match specific glob patterns, using the same format you would pass on the command line (e.g., `app/**/*.test.js`).
Glob patterns in overrides use [minimatch syntax](https://github.com/isaacs/minimatch).
### How do overrides work?
It is possible to override settings based on file glob patterns in your configuration by using the `overrides` key. An example of using the `overrides` key is as follows:
In your `.eslintrc.json`:
```json
{
"rules": {
"quotes": ["error", "double"]
},
"overrides": [
{
"files": ["bin/*.js", "lib/*.js"],
"excludedFiles": "*.test.js",
"rules": {
"quotes": ["error", "single"]
}
}
]
}
```
Here is how overrides work in a configuration file:
- The patterns are applied against the file path relative to the directory of the config file. For example, if your config file has the path `/Users/john/workspace/any-project/.eslintrc.js` and the file you want to lint has the path `/Users/john/workspace/any-project/lib/util.js`, then the pattern provided in `.eslintrc.js` is executed against the relative path `lib/util.js`.
- Glob pattern overrides have higher precedence than the regular configuration in the same config file. Multiple overrides within the same config are applied in order. That is, the last override block in a config file always has the highest precedence.
- A glob specific configuration works almost the same as any other ESLint config. Override blocks can contain any configuration options that are valid in a regular config, with the exception of `root` and `ignorePatterns`.
- A glob specific configuration can have an `extends` setting, but the `root` property in the extended configs is ignored. The `ignorePatterns` property in the extended configs is used only for the files the glob specific configuration matched.
- Nested `overrides` settings are applied only if the glob patterns of both the parent config and the child config are matched. This is the same when the extended configs have an `overrides` setting.
- Multiple glob patterns can be provided within a single override block. A file must match at least one of the supplied patterns for the configuration to apply.
- Override blocks can also specify patterns to exclude from matches. If a file matches any of the excluded patterns, the configuration won't apply.
### Relative glob patterns
```txt
project-root
├── app
│ ├── lib
│ │ ├── foo.js
│ │ ├── fooSpec.js
│ ├── components
│ │ ├── bar.js
│ │ ├── barSpec.js
│ ├── .eslintrc.json
├── server
│ ├── server.js
│ ├── serverSpec.js
├── .eslintrc.json
```
The config in `app/.eslintrc.json` defines the glob pattern `**/*Spec.js`. This pattern is relative to the base directory of `app/.eslintrc.json`. So, this pattern would match `app/lib/fooSpec.js` and `app/components/barSpec.js` but **NOT** `server/serverSpec.js`. If you defined the same pattern in the `.eslintrc.json` file within in the `project-root` folder, it would match all three of the `*Spec` files.
If a config is provided via the `--config` CLI option, the glob patterns in the config are relative to the current working directory rather than the base directory of the given config. For example, if `--config configs/.eslintrc.json` is present, the glob patterns in the config are relative to `.` rather than `./configs`.
### Specifying target files to lint
If you specified directories with CLI (e.g., `eslint lib`), ESLint searches target files in the directory to lint. The target files are `*.js` or the files that match any of `overrides` entries (but exclude entries that are any of `files` end with `*`).
If you specified the [`--ext`](../command-line-interface#--ext) command line option along with directories, the target files are only the files that have specified file extensions regardless of `overrides` entries.
## Personal Configuration Files (deprecated)
⚠️ **This feature has been deprecated**. This feature was removed in the 8.0.0 release. If you want to continue to use personal configuration files, please use the [`--config` CLI option](../command-line-interface#-c---config). For more information regarding this decision, please see [RFC 28](https://github.com/eslint/rfcs/pull/28) and [RFC 32](https://github.com/eslint/rfcs/pull/32).
`~/` refers to [the home directory of the current user on your preferred operating system](https://nodejs.org/api/os.html#os_os_homedir). The personal configuration file being referred to here is `~/.eslintrc.*` file, which is currently handled differently than other configuration files.
### How does ESLint find personal configuration files?
If `eslint` could not find any configuration file in the project, `eslint` loads `~/.eslintrc.*` file.
If `eslint` could find configuration files in the project, `eslint` ignores `~/.eslintrc.*` file even if it's in an ancestor directory of the project directory.
### How do personal configuration files behave?
`~/.eslintrc.*` files behave similarly to regular configuration files, with some exceptions:
`~/.eslintrc.*` files load shareable configs and custom parsers from `~/node_modules/` – similarly to `require()` – in the user's home directory. Please note that it doesn't load global-installed packages.
`~/.eslintrc.*` files load plugins from `$CWD/node_modules` by default in order to identify plugins uniquely. If you want to use plugins with `~/.eslintrc.*` files, plugins must be installed locally per project. Alternatively, you can use the `--resolve-plugins-relative-to` CLI option to change the location from which ESLint loads plugins.
---
---
title: Configuration Files
eleventyNavigation:
key: configuration files
parent: configure
title: Configuration Files
order: 1
---
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
{%- from 'components/npm_tabs.macro.html' import npm_tabs with context %}
::: tip
This page explains how to use flat config files. For the deprecated eslintrc format, [see the deprecated documentation](configuration-files-deprecated).
:::
You can put your ESLint project configuration in a configuration file. You can include built-in rules, how you want them enforced, plugins with custom rules, shareable configurations, which files you want rules to apply to, and more.
## Configuration File
The ESLint configuration file may be named any of the following:
- `eslint.config.js`
- `eslint.config.mjs`
- `eslint.config.cjs`
- `eslint.config.ts` (requires [additional setup](#typescript-configuration-files))
- `eslint.config.mts` (requires [additional setup](#typescript-configuration-files))
- `eslint.config.cts` (requires [additional setup](#typescript-configuration-files))
It should be placed in the root directory of your project and export an array of [configuration objects](#configuration-objects). Here's an example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
semi: "error",
"prefer-const": "error",
},
},
]);
```
In this example, the `defineConfig()` helper is used to define a configuration array with just one configuration object. The configuration object enables two rules: `semi` and `prefer-const`. These rules are applied to all of the files ESLint processes using this config file.
If your project does not specify `"type":"module"` in its `package.json` file, then `eslint.config.js` must be in CommonJS format, such as:
```js
// eslint.config.js
const { defineConfig } = require("eslint/config");
module.exports = defineConfig([
{
rules: {
semi: "error",
"prefer-const": "error",
},
},
]);
```
## Configuration Objects
Each configuration object contains all of the information ESLint needs to execute on a set of files. Each configuration object is made up of these properties:
- `name` - A name for the configuration object. This is used in error messages and [config inspector](https://github.com/eslint/config-inspector) to help identify which configuration object is being used. ([Naming Convention](#configuration-naming-conventions))
- `basePath` - A string specifying the path to a subdirectory to which the configuration object should apply to. It can be a relative or an absolute path.
- `files` - An array of glob patterns indicating the files that the configuration object should apply to. If not specified, the configuration object applies to all files matched by any other configuration object.
- `ignores` - An array of glob patterns indicating the files that the configuration object should not apply to. If not specified, the configuration object applies to all files matched by `files`. If `ignores` is used without any other keys in the configuration object, then the patterns act as [global ignores](#globally-ignoring-files-with-ignores) and it gets applied to every configuration object.
- `extends` - An array of strings, configuration objects, or configuration arrays that contain additional configuration to apply.
- `languageOptions` - An object containing settings related to how JavaScript is configured for linting.
- `ecmaVersion` - The version of ECMAScript to support. May be any year (i.e., `2022`) or version (i.e., `5`). Set to `"latest"` for the most recent supported version. (default: `"latest"`)
- `sourceType` - The type of JavaScript source code. Possible values are `"script"` for traditional script files, `"module"` for ECMAScript modules (ESM), and `"commonjs"` for CommonJS files. (default: `"module"` for `.js` and `.mjs` files; `"commonjs"` for `.cjs` files)
- `globals` - An object specifying additional objects that should be added to the global scope during linting.
- `parser` - An object containing a `parse()` method or a `parseForESLint()` method. (default: [`espree`](https://github.com/eslint/js/tree/main/packages/espree))
- `parserOptions` - An object specifying additional options that are passed directly to the `parse()` or `parseForESLint()` method on the parser. The available options are parser-dependent.
- `linterOptions` - An object containing settings related to the linting process.
- `noInlineConfig` - A Boolean value indicating if inline configuration is allowed.
- `reportUnusedDisableDirectives` - A severity string indicating if and how unused disable and enable directives should be tracked and reported. For legacy compatibility, `true` is equivalent to `"warn"` and `false` is equivalent to `"off"`. (default: `"warn"`).
- `reportUnusedInlineConfigs` - A severity string indicating if and how unused inline configs should be tracked and reported. (default: `"off"`)
- `processor` - Either an object containing `preprocess()` and `postprocess()` methods or a string indicating the name of a processor inside of a plugin (i.e., `"pluginName/processorName"`).
- `plugins` - An object containing a name-value mapping of plugin names to plugin objects. When `files` is specified, these plugins are only available to the matching files.
- `rules` - An object containing the configured rules. When `files` or `ignores` are specified, these rule configurations are only available to the matching files.
- `settings` - An object containing name-value pairs of information that should be available to all rules.
### Specifying `files` and `ignores`
::: tip
Patterns specified in `files` and `ignores` use [`minimatch`](https://www.npmjs.com/package/minimatch) syntax and are evaluated relative to the location of the `eslint.config.js` file. If using an alternate config file via the `--config` command line option, then all patterns are evaluated relative to the current working directory. In case the configuration object has the `basePath` property with a relative path, the subdirectory it specifies is evaluated relative to the location of the `eslint.config.js` file (or relative to the current working directory if using an alternate config file via the `--config` command line option). In configuration objects with the `basePath` property, patterns specified in `files` and `ignores` are evaluated relative to the subdirectory represented by the `basePath`.
:::
You can use a combination of `files` and `ignores` to determine which files the configuration object should apply to and which not. Here's an example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
// matches all files ending with .js
{
files: ["**/*.js"],
rules: {
semi: "error",
},
},
// matches all files ending with .js except those in __tests
{
files: ["**/*.js"],
ignores: ["__tests/**"],
rules: {
"no-console": "error",
},
},
]);
```
Configuration objects without `files` or `ignores` are automatically applied to any file that is matched by any other configuration object. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
// matches all files because it doesn't specify the `files` or `ignores` key
{
rules: {
semi: "error",
},
},
]);
```
With this configuration, the `semi` rule is enabled for all files that match the default files in ESLint. So if you pass `example.js` to ESLint, the `semi` rule is applied. If you pass a non-JavaScript file, like `example.txt`, the `semi` rule is not applied because there are no other configuration objects that match that filename. (ESLint outputs an error message letting you know that the file was ignored due to missing configuration.)
::: important
By default, ESLint lints files that match the patterns `**/*.js`, `**/*.cjs`, and `**/*.mjs`. Those files are always matched unless you explicitly exclude them using [global ignores](#globally-ignoring-files-with-ignores).
If your configuration object includes other patterns, the rules in configuration objects without a `files` key will also apply to these patterns.
Therefore, when using ESLint for non-JS files as well, it is more appropriate to create a configuration object that includes `files: ["**/*.js", "**/*.cjs", "**/*.mjs"]` and place the relevant rules there.
:::
#### Specifying files with arbitrary extensions
To lint files with extensions other than the default `.js`, `.cjs` and `.mjs`, include them in `files` with a pattern in the format of `"**/*.extension"`. Any pattern will work except if it is `*` or if it ends with `/*` or `/**`.
For example, to lint TypeScript files with `.ts`, `.cts` and `.mts` extensions, you would specify a configuration object like this:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.ts", "**/*.cts", "**/*.mts"],
},
// ...other config
]);
```
#### Specifying files without extension
Files without an extension can be matched with the pattern `!(*.*)`. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/!(*.*)"],
},
// ...other config
]);
```
The above config lints files without extension besides the default `.js`, `.cjs` and `.mjs` extensions in all directories.
::: tip
Filenames starting with a dot, such as `.gitignore`, are considered to have only an extension without a base name. In the case of `.gitignore`, the extension is `gitignore`, so the file matches the pattern `"**/.gitignore"` but not `"**/*.gitignore"`.
:::
#### Specifying files with an AND operation
Multiple patterns can be matched against the same file by using an array of strings inside of the `files` array. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: [["src/*", "**/.js"]],
},
// ...other config
]);
```
The pattern `["src/*", "**/.js"]` matches when a file is both inside of the `src` directory and also ends with `.js`. This approach can be helpful when you're dynamically calculating the value of the `files` array and want to avoid potential errors by trying to combine multiple glob patterns into a single string.
#### Excluding files with `ignores`
You can limit which files a configuration object applies to by specifying a combination of `files` and `ignores` patterns. For example, you may want certain rules to apply only to files in your `src` directory:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["src/**/*.js"],
rules: {
semi: "error",
},
},
]);
```
Here, only the JavaScript files in the `src` directory have the `semi` rule applied. If you run ESLint on files in another directory, this configuration object is skipped. By adding `ignores`, you can also remove some of the files in `src` from this configuration object:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["src/**/*.js"],
ignores: ["**/*.config.js"],
rules: {
semi: "error",
},
},
]);
```
This configuration object matches all JavaScript files in the `src` directory except those that end with `.config.js`. You can also use negation patterns in `ignores` to exclude files from the ignore patterns, such as:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["src/**/*.js"],
ignores: ["**/*.config.js", "!**/eslint.config.js"],
rules: {
semi: "error",
},
},
]);
```
Here, the configuration object excludes files ending with `.config.js` except for `eslint.config.js`. That file still has `semi` applied.
Non-global `ignores` patterns can only match file names. A pattern like `"dir-to-exclude/"` will not ignore anything. To ignore everything in a particular directory, a pattern like `"dir-to-exclude/**"` should be used instead.
If `ignores` is used without `files` and there are other keys (such as `rules`), then the configuration object applies to all linted files except the ones excluded by `ignores`, for example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
ignores: ["**/*.config.js"],
rules: {
semi: "error",
},
},
]);
```
This configuration object applies to all JavaScript files except those ending with `.config.js`. Effectively, this is like having `files` set to `**/*`. In general, it's a good idea to always include `files` if you are specifying `ignores`.
Note that when `files` is not specified, negated `ignores` patterns do not cause any matching files to be linted automatically.
ESLint only lints files that are matched either by default or by a `files` pattern that is not `*` and does not end with `/*` or `/**`.
::: tip
Use the [config inspector](https://github.com/eslint/config-inspector) (`--inspect-config` in the CLI) to test which config objects apply to a specific file.
:::
#### Globally ignoring files with `ignores`
Depending on how the `ignores` property is used, it can behave as non-global `ignores` or as global `ignores`.
- When `ignores` is used without any other keys (besides `name`) in the configuration object, then the patterns act as global ignores. This means they apply to every configuration object (not only to the configuration object in which it is defined). Global `ignores` allows you not to have to copy and keep the `ignores` property synchronized in more than one configuration object.
- If `ignores` is used with other properties in the same configuration object, then the patterns act as non-global ignores. This way `ignores` applies only to the configuration object in which it is defined.
Global and non-global `ignores` have some usage differences:
- patterns in non-global `ignores` only match the files (`dir/filename.js`) or files within directories (`dir/**`)
- patterns in global `ignores` can match directories (`dir/`) in addition to the patterns that non-global ignores supports.
For all uses of `ignores`:
- The patterns you define are added after the default ESLint patterns, which are `["**/node_modules/", ".git/"]`.
- The patterns always match files and directories that begin with a dot, such as `.foo.js` or `.fixtures`, unless those files are explicitly ignored. The only dot directory ignored by default is `.git`.
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
// Example of global ignores
export default defineConfig([
{
ignores: [".config/", "dist/", "tsconfig.json"] // acts as global ignores, due to the absence of other properties
},
{ ... }, // ... other configuration object, inherit global ignores
{ ... }, // ... other configuration object, inherit global ignores
]);
// Example of non-global ignores
export default defineConfig([
{
ignores: [".config/**", "dir1/script1.js"],
rules: { ... } // the presence of this property dictates non-global ignores
},
{
ignores: ["other-dir/**", "dist/script2.js"],
rules: { ... } // the presence of this property dictates non-global ignores
},
]);
```
To avoid confusion, use the `globalIgnores()` helper function to clearly indicate which ignores are meant to be global. Here's the previous example rewritten to use `globalIgnores()`:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
// Example of global ignores
export default defineConfig([
globalIgnores([".config/", "dist/", "tsconfig.json"]),
{ ... }, // ... other configuration object, inherit global ignores
{ ... }, // ... other configuration object, inherit global ignores
]);
// Example of non-global ignores
export default defineConfig([
{
ignores: [".config/**", "dir1/script1.js"],
rules: { ... } // the presence of this property dictates non-global ignores
},
{
ignores: ["other-dir/**", "dist/script2.js"],
rules: { ... } // the presence of this property dictates non-global ignores
},
]);
```
For more information and examples on configuring rules regarding `ignores`, see [Ignore Files](ignore).
#### Specifying base path
You can optionally specify `basePath` to apply the configuration object to a specific subdirectory (including its subdirectories).
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
// matches all files in tests and its subdirectories
{
basePath: "tests",
rules: {
"no-undef": "error",
},
},
// matches all files ending with spec.js in tests and its subdirectories
{
basePath: "tests",
files: ["**/*.spec.js"],
languageOptions: {
globals: {
it: "readonly",
describe: "readonly",
},
},
},
// globally ignores tests/fixtures directory
{
basePath: "tests",
ignores: ["fixtures/"],
},
]);
```
In combination with [`extends`](#extending-configurations), multiple configuration objects can be applied to the same subdirectory by specifying `basePath` only once, like this:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
basePath: "tests",
extends: [
// matches all files in tests and its subdirectories
{
rules: {
"no-undef": "error",
},
},
// matches all files ending with spec.js in tests and its subdirectories
{
files: ["**/*.spec.js"],
languageOptions: {
globals: {
it: "readonly",
describe: "readonly",
},
},
},
// globally ignores tests/fixtures directory
{
ignores: ["fixtures/"],
},
],
},
]);
```
#### Cascading Configuration Objects
When more than one configuration object matches a given filename, the configuration objects are merged with later objects overriding previous objects when there is a conflict. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
languageOptions: {
globals: {
MY_CUSTOM_GLOBAL: "readonly",
},
},
},
{
files: ["tests/**/*.js"],
languageOptions: {
globals: {
it: "readonly",
describe: "readonly",
},
},
},
]);
```
Using this configuration, all JavaScript files define a custom global object defined called `MY_CUSTOM_GLOBAL` while those JavaScript files in the `tests` directory have `it` and `describe` defined as global objects in addition to `MY_CUSTOM_GLOBAL`. For any JavaScript file in the `tests` directory, both configuration objects are applied, so `languageOptions.globals` are merged to create a final result.
### Configuring Linter Options
Options specific to the linting process can be configured using the `linterOptions` object. These effect how linting proceeds and does not affect how the source code of the file is interpreted.
#### Disabling Inline Configuration
Inline configuration is implemented using an `/*eslint*/` comment, such as `/*eslint semi: error*/`. You can disallow inline configuration by setting `noInlineConfig` to `true`. When enabled, all inline configuration is ignored. Here's an example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
linterOptions: {
noInlineConfig: true,
},
},
]);
```
#### Reporting Unused Disable Directives
Disable and enable directives such as `/*eslint-disable*/`, `/*eslint-enable*/` and `/*eslint-disable-next-line*/` are used to disable ESLint rules around certain portions of code. As code changes, it's possible for these directives to no longer be needed because the code has changed in such a way that the rule is no longer triggered. You can enable reporting of these unused disable directives by setting the `reportUnusedDisableDirectives` option to a severity string, as in this example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
linterOptions: {
reportUnusedDisableDirectives: "error",
},
},
]);
```
This setting defaults to `"warn"`.
You can override this setting using the [`--report-unused-disable-directives`](../command-line-interface#--report-unused-disable-directives) or the [`--report-unused-disable-directives-severity`](../command-line-interface#--report-unused-disable-directives-severity) command line options.
For legacy compatibility, `true` is equivalent to `"warn"` and `false` is equivalent to `"off"`.
#### Reporting Unused Inline Configs
Inline config comments such as `/* eslint rule-name: "error" */` are used to change ESLint rule severity and/or options around certain portions of code.
As a project's ESLint configuration file changes, it's possible for these directives to no longer be different from what was already set.
You can enable reporting of these unused inline config comments by setting the `reportUnusedInlineConfigs` option to a severity string, as in this example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
linterOptions: {
reportUnusedInlineConfigs: "error",
},
},
]);
```
You can override this setting using the [`--report-unused-inline-configs`](../command-line-interface#--report-unused-inline-configs) command line option.
### Configuring Rules
You can configure any number of rules in a configuration object by adding a `rules` property containing an object with your rule configurations. The names in this object are the names of the rules and the values are the configurations for each of those rules. Here's an example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
semi: "error",
},
},
]);
```
This configuration object specifies that the [`semi`](../../rules/semi) rule should be enabled with a severity of `"error"`. You can also provide options to a rule by specifying an array where the first item is the severity and each item after that is an option for the rule. For example, you can switch the `semi` rule to disallow semicolons by passing `"never"` as an option:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
semi: ["error", "never"],
},
},
]);
```
Each rule specifies its own options and can be any valid JSON data type. Please check the documentation for the rule you want to configure for more information about its available options.
For more information on configuring rules, see [Configure Rules](rules).
### Configuring Shared Settings
ESLint supports adding shared settings into configuration files. When you add a `settings` object to a configuration object, it is supplied to every rule. By convention, plugins namespace the settings they are interested in to avoid collisions with others. Plugins can use `settings` to specify the information that should be shared across all of their rules. This may be useful if you are adding custom rules and want them to have access to the same information. Here's an example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
settings: {
sharedData: "Hello",
},
plugins: {
customPlugin: {
rules: {
"my-rule": {
meta: {
// custom rule's meta information
},
create(context) {
const sharedData = context.settings.sharedData;
return {
// code
};
},
},
},
},
},
rules: {
"customPlugin/my-rule": "error",
},
},
]);
```
### Extending Configurations
A configuration object uses `extends` to inherit all the traits of another configuration object or array (including rules, plugins, and language options) and can then modify all the options. The `extends` key is an array of values indicating which configurations to extend from. The elements of the `extends` array can be one of three values:
- a string that specifies the name of a configuration in a plugin
- a configuration object
- a configuration array
#### Using Configurations from Plugins
ESLint plugins can export predefined configurations. These configurations are referenced using a string and follow the pattern `pluginName/configName`. The plugin must be specified in the `plugins` key first. Here's an example:
```js
// eslint.config.js
import examplePlugin from "eslint-plugin-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
example: examplePlugin,
},
extends: ["example/recommended"],
},
]);
```
In this example, the configuration named `recommended` from `eslint-plugin-example` is loaded. The plugin configurations can also be referenced by name inside of the configuration array.
You can also insert plugin configurations directly into the `extends` array. For example:
```js
// eslint.config.js
import pluginExample from "eslint-plugin-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
example: pluginExample,
},
extends: [pluginExample.configs.recommended],
},
]);
```
In this case, the configuration named `recommended` from `eslint-plugin-example` is accessed directly through the plugin object's `configs` property.
::: important
It's recommended to always use a `files` key when you use the `extends` key to ensure that your configuration applies to the correct files. By omitting the `files` key, the extended configuration may end up applied to all files.
:::
#### Using Predefined Configurations
ESLint has two predefined configurations for JavaScript:
- `js/recommended` - enables the rules that ESLint recommends everyone use to avoid potential errors.
- `js/all` - enables all of the rules shipped with ESLint. This configuration is **not recommended** for production use because it changes with every minor and major version of ESLint. Use at your own risk.
To include these predefined configurations, install the `@eslint/js` package and then make any modifications to other properties in subsequent configuration objects:
```js
// eslint.config.js
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",
},
},
]);
```
Here, the `js/recommended` predefined configuration is applied first and then another configuration object adds the desired configuration for [`no-unused-vars`](../../rules/no-unused-vars).
For more information on how to combine predefined configs with your preferences, please see [Combine Configs](combine-configs).
#### Using a Shareable Configuration Package
A sharable configuration is an npm package that exports a configuration object or array. This package should be installed as a dependency in your project and then referenced from inside of your `eslint.config.js` file. For example, to use a shareable configuration named `eslint-config-example`, your configuration file would look like this:
```js
// eslint.config.js
import exampleConfig from "eslint-config-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
extends: [exampleConfig],
rules: {
"no-unused-vars": "warn",
},
},
]);
```
In this example, `exampleConfig` can be either an object or an array, and either way it can be inserted directly into the `extends` array.
For more information on how to combine shareable configs with your preferences, please see [Combine Configs](combine-configs).
### When to Use Extends vs Cascading
When to use `Extends`:
- **For reusing configurations** - When you want to inherit and build upon existing configurations from plugins, shareable packages, or predefined configs.
- **For plugin configuration** - When applying recommended or specific configurations from ESLint plugins (e.g., `example/recommended`).
- **For shareable configurations** - When using npm packages that export configuration objects (e.g., `eslint-config-example`).
- **For predefined configurations** - When using ESLint's built-in configurations like `js/recommended` or `js/all`.
- **For modular configuration** - When you want to compose multiple configuration sources into a single configuration object.
- **For maintaining consistency** - When you want to ensure consistent base rules across multiple configuration objects.
- **For plugin integration** - When you need to apply configurations that come bundled with plugins.
When to use `Cascading`:
- **For file-specific rule** - When you need different rules for different file patterns or directories.
- **For progressive configuration** - When you want to apply base rules to all files and then add/override rules for specific subsets.
- **For environment-specific settings** - When test files, source files, and config files need different rule sets.
- **For directory-based configuration** - When different project directories require different linting approaches.
- **For rule severity adjustment** - When you want to change rule severity (`error`/`warn`/`off`) for specific file patterns.
- **For language option variations** - When different files need different ECMAScript versions or parser options.
### Configuration Naming Conventions
The `name` property is optional, but it is recommended to provide a name for each configuration object, especially when you are creating shared configurations. The name is used in error messages and the config inspector to help identify which configuration object is being used.
The name should be descriptive of the configuration object's purpose and scoped with the configuration name or plugin name using `/` as a separator. ESLint does not enforce the names to be unique at runtime, but it is recommended that unique names be set to avoid confusion.
For example, if you are creating a configuration object for a plugin named `eslint-plugin-example`, you might add `name` to the configuration objects with the `example/` prefix:
```js
export default {
configs: {
recommended: {
name: "example/recommended",
rules: {
"no-unused-vars": "warn",
},
},
strict: {
name: "example/strict",
rules: {
"no-unused-vars": "error",
},
},
},
};
```
When exposing arrays of configuration objects, the `name` may have extra scoping levels to help identify the configuration object. For example:
```js
export default {
configs: {
strict: [
{
name: "example/strict/language-setup",
languageOptions: {
ecmaVersion: 2024,
},
},
{
name: "example/strict/sub-config",
files: ["src/**/*.js"],
rules: {
"no-unused-vars": "error",
},
},
],
},
};
```
## Configuration File Resolution
When ESLint is run on the command line, it determines configuration for each target file by first looking in the directory that contains the file and then searching up ancestor directories until it finds an `eslint.config.*` file. This behavior improves support for monorepos, where subdirectories can have their own configuration files.
You can prevent this search by using the `-c` or `--config` option on the command line to specify an alternate configuration file, such as:
{{ npx_tabs({
package: "eslint",
args: ["--config", "some-other-file.js", "**/*.js"]
}) }}
In this case, ESLint does not search for configuration files and instead uses `some-other-file.js`.
## TypeScript Configuration Files
For Deno and Bun, TypeScript configuration files are natively supported; for Node.js, you must install the optional dev dependency [`jiti`](https://github.com/unjs/jiti) in version 2.2.0 or later in your project (this dependency is not automatically installed by ESLint):
{{ npm_tabs({
command: "install",
packages: ["jiti"],
args: ["--save-dev"]
}) }}
You can then create a configuration file with a `.ts`, `.mts`, or `.cts` extension, and export an array of [configuration objects](#configuration-objects).
::: important
ESLint does not perform type checking on your configuration file and does not apply any settings from `tsconfig.json`.
:::
### Native TypeScript Support
If you're using **Node.js >= 22.13.0**, you can load TypeScript configuration files natively without requiring [`jiti`](https://github.com/unjs/jiti). This is possible thanks to the [**`--experimental-strip-types`**](https://nodejs.org/docs/latest-v22.x/api/cli.html#--experimental-strip-types) flag.
Since this feature is still experimental, you must also enable the `unstable_native_nodejs_ts_config` flag.
```bash
npx --node-options='--experimental-strip-types' eslint --flag unstable_native_nodejs_ts_config
```
### Configuration File Precedence
If you have multiple ESLint configuration files, ESLint prioritizes JavaScript files over TypeScript files. The order of precedence is as follows:
1. `eslint.config.js`
2. `eslint.config.mjs`
3. `eslint.config.cjs`
4. `eslint.config.ts`
5. `eslint.config.mts`
6. `eslint.config.cts`
To override this behavior, use the `--config` or `-c` command line option to specify a different configuration file:
{{ npx_tabs({
package: "eslint",
args: ["--config", "eslint.config.ts"]
}) }}
---
---
title: Debug Your Configuration
eleventyNavigation:
key: debug config
parent: configure
title: Debug Your Configuration
order: 8
---
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
ESLint creates a configuration for each file that is linted based on your configuration file and command line options. The larger the configuration file, the more difficult it can be to determine why a file isn't linted as expected. To aid in debugging your configuration, ESLint provides several tools.
## Run the CLI in Debug Mode
**Use When:** You aren't sure if the correct configuration file is being read. This may happen if you have multiple configuration files in the same project.
**What To Do:** Run ESLint with the [`--debug`](../command-line-interface#--debug) command line flag and pass the file to check, like this:
{{ npx_tabs({
package: "eslint",
args: ["--debug", "file.js"]
}) }}
This outputs all of ESLint's debugging information onto the console. You should copy this output to a file and then search for `eslint.config.js` to see which file is loaded. Here's some example output:
```text
eslint:eslint Using file patterns: bin/eslint.js +0ms
eslint:eslint Searching for eslint.config.js +0ms
eslint:eslint Loading config from C:\Users\nzakas\projects\eslint\eslint\eslint.config.js +5ms
eslint:eslint Config file URL is file:///C:/Users/nzakas/projects/eslint/eslint/eslint.config.js +0ms
```
## Print a File's Calculated Configuration
**Use When:** You aren't sure why linting isn't producing the expected results, either because it seems like your rule configuration isn't being honored or the wrong language options are being used.
**What To Do:** Run ESLint with the [`--print-config`](../command-line-interface#--print-config) command line flag and pass the file to check, like this:
{{ npx_tabs({
package: "eslint",
args: ["--print-config", "file.js"]
}) }}
This outputs a JSON representation of the file's calculated config, such as:
```json
{
"linterOptions": {
"reportUnusedDisableDirectives": 1
},
"language": "@/js",
"languageOptions": {
"sourceType": "module",
"ecmaVersion": "latest"
},
"plugins": ["@"],
"rules": {
"prefer-const": 2
}
}
```
::: tip
You won't see any entries for `files`, `ignores`, or `name`, because those are only used in calculating the final configuration and so do not appear in the result. You will see any default configuration applied by ESLint itself.
:::
## Use the Config Inspector
**Use When:** You aren't sure if certain configuration objects in your configuration file match a given filename.
**What To Do:** Run ESLint with the [`--inspect-config`](../command-line-interface#--inspect-config) command line flag and pass the file to check, like this:
{{ npx_tabs({
package: "eslint",
args: ["--inspect-config"]
}) }}
This initiates the config inspector by installing and starting [`@eslint/config-inspector`](https://github.com/eslint/config-inspector). You can then type in the filename in question to see which configuration objects will apply.

The config inspector also shows you when rules are deprecated, how many available rules you're using, and more.
---
---
title: Ignore Files (Deprecated)
---
::: warning
This documentation is for ignoring files using the deprecated eslintrc configuration format. [View the updated documentation](ignore).
:::
You can configure ESLint to ignore certain files and directories while linting by specifying one or more glob patterns.
You can ignore files in the following ways:
- Add `ignorePatterns` to a configuration file.
- Create a dedicated file that contains the ignore patterns (`.eslintignore` by default).
## `ignorePatterns` in Config Files
You can tell ESLint to ignore specific files and directories using `ignorePatterns` in your config files. `ignorePatterns` patterns follow the same rules as `.eslintignore`. Please see the [`.eslintignore` file documentation](#the-eslintignore-file) to learn more.
```json
{
"ignorePatterns": ["temp.js", "**/vendor/*.js"],
"rules": {
//...
}
}
```
- Glob patterns in `ignorePatterns` are relative to the directory that the config file is placed in.
- You cannot write `ignorePatterns` property under `overrides` property.
- Patterns defined in `.eslintignore` take precedence over the `ignorePatterns` property of config files.
If a glob pattern starts with `/`, the pattern is relative to the base directory of the config file. For example, `/foo.js` in `lib/.eslintrc.json` matches to `lib/foo.js` but not `lib/subdir/foo.js`.
If a config is provided via the `--config` CLI option, the ignore patterns that start with `/` in the config are relative to the current working directory rather than the base directory of the given config. For example, if `--config configs/.eslintrc.json` is present, the ignore patterns in the config are relative to `.` rather than `./configs`.
## The `.eslintignore` File
You can tell ESLint to ignore specific files and directories by creating an `.eslintignore` file in your project's root directory. The `.eslintignore` file is a plain text file where each line is a glob pattern indicating which paths should be omitted from linting. For example, the following omits all JavaScript files:
```text
**/*.js
```
When ESLint is run, it looks in the current working directory to find an `.eslintignore` file before determining which files to lint. If this file is found, then those preferences are applied when traversing directories. Only one `.eslintignore` file can be used at a time, so `.eslintignore` files other than the one in the current working directory are not used.
Globs are matched using [node-ignore](https://github.com/kaelzhang/node-ignore), so a number of features are available:
- Lines beginning with `#` are treated as comments and do not affect the ignore patterns.
- Paths are relative to the current working directory. This is also true of paths passed in via the `--ignore-pattern` [command](../command-line-interface#--ignore-pattern).
- Lines preceded by `!` are negated patterns that re-include a pattern that was ignored by an earlier pattern.
- Ignore patterns behave according to the `.gitignore` [specification](https://git-scm.com/docs/gitignore).
Of particular note is that like `.gitignore` files, all paths used as patterns for both `.eslintignore` and `--ignore-pattern` must use forward slashes as their path separators.
```text
# Valid
/root/src/*.js
# Invalid
\root\src\*.js
```
Please see [`.gitignore`](https://git-scm.com/docs/gitignore)'s specification for further examples of valid syntax.
In addition to any patterns in the `.eslintignore` file, ESLint always follows a couple of implicit ignore rules even if the `--no-ignore` flag is passed. The implicit rules are as follows:
- `node_modules/` is ignored.
- dot-files (except for `.eslintrc.*`) as well as dot-folders and their contents are ignored.
There are also some exceptions to these rules:
- If the path to lint is a glob pattern or directory path and contains a dot-folder, all dot-files and dot-folders are linted. This includes dot-files and dot-folders that are buried deeper in the directory structure.
For example, `eslint .config/` would lint all dot-folders and dot-files in the `.config` directory, including immediate children as well as children that are deeper in the directory structure.
- If the path to lint is a specific file path and the `--no-ignore` flag has been passed, ESLint would lint the file regardless of the implicit ignore rules.
For example, `eslint .config/my-config-file.js --no-ignore` would cause `my-config-file.js` to be linted. It should be noted that the same command without the `--no-ignore` line would not lint the `my-config-file.js` file.
- Allowlist and denylist rules specified via `--ignore-pattern` or `.eslintignore` are prioritized above implicit ignore rules.
For example, in this scenario, `.build/test.js` is the desired file to allowlist. Because all dot-folders and their children are ignored by default, `.build` must first be allowlisted so that eslint becomes aware of its children. Then, `.build/test.js` must be explicitly allowlisted, while the rest of the content is denylisted. This is done with the following `.eslintignore` file:
```text
# Allowlist 'test.js' in the '.build' folder
# But do not allow anything else in the '.build' folder to be linted
!.build
.build/*
!.build/test.js
```
The following `--ignore-pattern` is also equivalent:
```shell
eslint --ignore-pattern '!.build' --ignore-pattern '.build/*' --ignore-pattern '!.build/test.js' parent-folder/
```
## Using an Alternate File
If you'd prefer to use a different file than the `.eslintignore` in the current working directory, you can specify it on the command line using the `--ignore-path` option. For example, you can use `.jshintignore` file because it has the same format:
```shell
eslint --ignore-path .jshintignore file.js
```
You can also use your `.gitignore` file:
```shell
eslint --ignore-path .gitignore file.js
```
Any file that follows the standard ignore file format can be used. Keep in mind that specifying `--ignore-path` means that the existing `.eslintignore` file is not used. Note that globbing rules in `.eslintignore` follow those of `.gitignore`.
## Using eslintIgnore in package.json
If an `.eslintignore` file is not found and an alternate file is not specified, ESLint looks in `package.json` for the `eslintIgnore` key to check for files to ignore.
```json
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": ["hello.js", "world.js"]
}
```
## Ignored File Warnings
When you pass directories to ESLint, files and directories are silently ignored. If you pass a specific file to ESLint, then ESLint creates a warning that the file was skipped. For example, suppose you have an `.eslintignore` file that looks like this:
```text
foo.js
```
And then you run:
```shell
eslint foo.js
```
You'll see this warning:
```text
foo.js
0:0 warning File ignored because of a matching ignore pattern. Use "--no-ignore" to disable file ignore settings or use "--no-warn-ignored" to suppress this warning.
✖ 1 problem (0 errors, 1 warning)
```
This message occurs because ESLint is unsure if you wanted to actually lint the file or not. As the message indicates, you can use `--no-ignore` to omit using the ignore rules.
Consider another scenario where you want to run ESLint on a specific dot-file or dot-folder, but have forgotten to specifically allow those files in your `.eslintignore` file. You would run something like this:
```shell
eslint .config/foo.js
```
You would see this warning:
```text
.config/foo.js
0:0 warning File ignored by default. Use a negated ignore pattern (like "--ignore-pattern '!'") to override
✖ 1 problem (0 errors, 1 warning)
```
This message occurs because, normally, this file would be ignored by ESLint's implicit ignore rules (as mentioned above). A negated ignore rule in your `.eslintignore` file would override the implicit rule and reinclude this file for linting. Additionally, in this case, `--no-ignore` could be used to lint the file as well.
---
---
title: Ignore Files
eleventyNavigation:
key: ignore files
parent: configure
title: Ignore Files
order: 7
---
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
::: tip
This page explains how to ignore files using the flat config format. For the deprecated eslintrc format, [see the deprecated documentation](ignore-deprecated).
:::
::: tip
This page explains how to use the `globalIgnores()` function to completely ignore files and directories. For more information on non-global ignores, see [Specifying files and ignores](configuration-files#specifying-files-and-ignores). For more information on the differences between global and non-global ignores, see [Globally ignoring files with `ignores`](configuration-files#globally-ignoring-files-with-ignores).
:::
You can configure ESLint to ignore certain files and directories while linting by specifying one or more glob patterns in the following ways:
- Inside of your `eslint.config.js` file.
- On the command line using `--ignore-pattern`.
## Ignoring Files
In your `eslint.config.js` file, you can use the `globalIgnores()` helper function to indicate patterns of files to be ignored. Here's an example:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([globalIgnores([".config/*"])]);
```
This configuration specifies that all of the files in the `.config` directory should be ignored. This pattern is added after the default patterns, which are `["**/node_modules/", ".git/"]`.
By default, ESLint lints files that match the patterns `**/*.js`, `**/*.cjs`, and `**/*.mjs`. You can ignore them with `globalIgnores()` if you don't want ESLint to lint these files:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores(["**/*.js", "**/*.cjs", "**/*.mjs"]),
]);
```
When non-JS files are specified in the `files` property, ESLint still lints files that match the default patterns. To lint only the files specified in the `files` property, you must ignore the default file patterns:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores(["**/*.js", "**/*.cjs", "**/*.mjs"]),
{
files: ["**/*.ts"],
ignores: [".config/**"],
rules: {
/* ... */
},
},
]);
```
You can also ignore files on the command line using [`--ignore-pattern`](../command-line-interface#--ignore-pattern), such as:
{{ npx_tabs({
package: "eslint",
args: [".", "--ignore-pattern", "\'.config/*\'"]
}) }}
## Ignoring Directories
Ignoring directories works the same way as ignoring files, by passing a pattern to the `globalIgnores()` helper function. For example, the following ignores the `.config` directory as a whole (meaning file search will not traverse into it at all):
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([globalIgnores([".config/"])]);
```
Unlike `.gitignore`, an ignore pattern like `.config` will only ignore the `.config` directory in the same directory as the configuration file. If you want to recursively ignore all directories named `.config`, you need to use `**/.config/`, as in this example:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([globalIgnores(["**/.config/"])]);
```
## Unignoring Files and Directories
You can also unignore files and directories that are ignored by previous patterns, including the default patterns. For example, this config unignores `node_modules/mylibrary`:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores([
"!node_modules/", // unignore `node_modules/` directory
"node_modules/*", // ignore its content
"!node_modules/mylibrary/", // unignore `node_modules/mylibrary` directory
]),
]);
```
If you'd like to ignore a directory except for specific files or subdirectories, then the ignore pattern `directory/**/*` must be used instead of `directory/**`. The pattern `directory/**` ignores the entire directory and its contents, so traversal will skip over the directory completely and you cannot unignore anything inside.
For example, `build/**` ignores directory `build` and its contents, whereas `build/**/*` ignores only its contents. If you'd like to ignore everything in the `build` directory except for `build/test.js`, you'd need to create a config like this:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores([
"build/**/*", // ignore all contents in and under `build/` directory but not the `build/` directory itself
"!build/test.js", // unignore `!build/test.js`
]),
]);
```
If you'd like to ignore a directory except for specific files at any level under the directory, you should also ensure that subdirectories are not ignored. Note that while patterns that end with `/` only match directories, patterns that don't end with `/` match both files and directories so it isn't possible to write a single pattern that only ignores files, but you can achieve this with two patterns: one to ignore all contents and another to unignore subdirectories.
For example, this config ignores all files in and under `build` directory except for files named `test.js` at any level:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores([
"build/**/*", // ignore all contents in and under `build/` directory but not the `build/` directory itself
"!build/**/*/", // unignore all subdirectories
"!build/**/test.js", // unignore `test.js` files
]),
]);
```
If you want to ignore ESLint's default file patterns (`**/*.js`, `**/*.cjs`, and `**/*.mjs`) while still linting specific files or directories, you can use negative patterns to unignore them:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores(["**/*.js", "**/*.cjs", "**/*.mjs", "!**/src/**/*.js"]),
]);
```
This configuration ignores all files matching the default patterns except for JavaScript files located within `src` directories.
::: important
Note that only global `ignores` patterns can match directories.
`ignores` patterns that are specific to a configuration will only match file names.
:::
You can also unignore files on the command line using [`--ignore-pattern`](../command-line-interface#--ignore-pattern), such as:
{{ npx_tabs({
package: "eslint",
args: [".", "--ignore-pattern", "\'!node_modules/\'"]
}) }}
## Glob Pattern Resolution
How glob patterns are evaluated depends on where they are located and how they are used:
1. When using `globalIgnores()` in an `eslint.config.js` file, glob patterns are evaluated relative to the `eslint.config.js` file.
1. When using `globalIgnores()` in an alternate configuration file specified using the [`--config`](../command-line-interface#-c---config) command line option, glob patterns are evaluated relative to the current working directory.
1. When using [`--ignore-pattern`](../command-line-interface#--ignore-pattern), glob patterns are evaluated relative to the current working directory.
## Name the Global Ignores Config
By default, `globalIgnores()` will assign a name to the config that represents your ignores. You can override this name by providing a second argument to `globalIgnores()`, which is the name you'd like to use instead of the default:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
globalIgnores(["build/**/*"], "Ignore Build Directory"),
]);
```
The `"Ignore Build Directory"` string in this example is the name of the config created for the global ignores. This is useful for debugging purposes.
## Ignored File Warnings
When you pass directories to the ESLint CLI, files and directories are silently ignored. If you pass a specific file to ESLint, then ESLint creates a warning that the file was skipped. For example, suppose you have an `eslint.config.js` file that looks like this:
```js
// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([globalIgnores(["foo.js"])]);
```
And then you run:
{{ npx_tabs({
package: "eslint",
args: ["foo.js"]
}) }}
You'll see this warning:
```text
foo.js
0:0 warning File ignored because of a matching ignore pattern. Use "--no-ignore" to disable file ignore settings or use "--no-warn-ignored" to suppress this warning.
✖ 1 problem (0 errors, 1 warning)
```
This message occurs because ESLint is unsure if you wanted to actually lint the file or not. As the message indicates, you can use `--no-ignore` to omit using the ignore rules.
## Including `.gitignore` Files
If you want to include patterns from a [`.gitignore`](https://git-scm.com/docs/gitignore) file or any other file with gitignore-style patterns, you can use [`includeIgnoreFile`](https://github.com/eslint/rewrite/tree/main/packages/compat#including-ignore-files) utility from the [`@eslint/compat`](https://www.npmjs.com/package/@eslint/compat) package.
By default, `includeIgnoreFile()` will assign a name to the config that represents your ignores. You can override this name by providing a second argument to `includeIgnoreFile()`, which is the name you'd like to use instead of the default:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
import { includeIgnoreFile } from "@eslint/compat";
import { fileURLToPath } from "node:url";
const gitignorePath = fileURLToPath(new URL(".gitignore", import.meta.url));
export default defineConfig([
includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"),
{
// your overrides
},
]);
```
This automatically loads the specified file and translates gitignore-style patterns into `ignores` glob patterns.
---
---
title: Configure ESLint
eleventyNavigation:
key: configure
parent: use eslint
title: Configure ESLint
order: 3
---
ESLint is designed to be flexible and configurable for your use case. You can turn off every rule and run only with basic syntax validation or mix and match the bundled rules and your custom rules to fit the needs of your project. There are two primary ways to configure ESLint:
1. **Configuration Comments** - use JavaScript comments to embed configuration information directly into a file.
2. **Configuration Files** - use a JavaScript file to specify configuration information for an entire directory and all of its subdirectories. This can be in the form of an [`eslint.config.js`](./configuration-files) file which ESLint will look for and read automatically, or you can specify a configuration file on the [command line](../command-line-interface).
Here are some of the options that you can configure in ESLint:
- [**Globals**](./language-options#specifying-globals) - the additional global variables your script accesses during execution.
- [**Rules**](rules) - which rules are enabled and at what error level.
- [**Plugins**](plugins) - which third-party plugins define additional rules, languages, configs, etc. for ESLint to use.
All of these options give you fine-grained control over how ESLint treats your code.
## Table of Contents
[**Configuration Files**](configuration-files)
- [Configuration File Format](./configuration-files#configuration-file)
- [Configuration Objects](./configuration-files#configuration-objects)
- [Configuring Shared Settings](./configuration-files#configuring-shared-settings)
- [Configuration File Resolution](./configuration-files#configuration-file-resolution)
[**Configure Language Options**](language-options)
- [Specifying JavaScript Options](./language-options#specifying-javascript-options)
- [Specifying Globals](./language-options#specifying-globals)
[**Configure Rules**](rules)
- [Configuring Rules](./rules)
- [Disabling Rules](./rules#disabling-rules)
[**Configure Plugins**](plugins)
- [Configure Plugins](./plugins#configure-plugins)
- [Specify a Processor](./plugins#specify-a-processor)
[**Configure a Parser**](./parser)
- [Configure a Custom Parser](./parser#configure-a-custom-parser)
[**Ignore Files**](ignore)
- [Ignoring Files](./ignore#ignoring-files)
- [Ignoring Directories](./ignore#ignoring-directories)
- [Unignoring Files and Directories](./ignore#unignoring-files-and-directories)
- [Ignored File Warnings](./ignore#ignored-file-warnings)
---
---
title: Configure Language Options (Deprecated)
---
::: warning
This documentation is for configuring language options using the deprecated eslintrc configuration format. [View the updated documentation](language-options).
:::
The JavaScript ecosystem has a variety of runtimes, versions, extensions, and frameworks. Each of these can have different supported syntax and global variables. ESLint lets you configure language options specific to the JavaScript used in your project, like custom global variables. You can also use plugins to extend ESLint to support your project's language options.
## Specifying Environments
An environment provides predefined global variables. The available environments are:
- `browser` - browser global variables.
- `node` - Node.js global variables and Node.js scoping.
- `commonjs` - CommonJS global variables and CommonJS scoping (use this for browser-only code that uses Browserify/WebPack).
- `shared-node-browser` - Globals common to both Node.js and Browser.
- `es6` - enable all ECMAScript 6 features except for modules (this automatically sets the `ecmaVersion` parser option to 6).
- `es2016` - adds all ECMAScript 2016 globals and automatically sets the `ecmaVersion` parser option to 7.
- `es2017` - adds all ECMAScript 2017 globals and automatically sets the `ecmaVersion` parser option to 8.
- `es2018` - adds all ECMAScript 2018 globals and automatically sets the `ecmaVersion` parser option to 9.
- `es2019` - adds all ECMAScript 2019 globals and automatically sets the `ecmaVersion` parser option to 10.
- `es2020` - adds all ECMAScript 2020 globals and automatically sets the `ecmaVersion` parser option to 11.
- `es2021` - adds all ECMAScript 2021 globals and automatically sets the `ecmaVersion` parser option to 12.
- `es2022` - adds all ECMAScript 2022 globals and automatically sets the `ecmaVersion` parser option to 13.
- `es2023` - adds all ECMAScript 2023 globals and automatically sets the `ecmaVersion` parser option to 14.
- `es2024` - adds all ECMAScript 2024 globals and automatically sets the `ecmaVersion` parser option to 15.
- `worker` - web workers global variables.
- `amd` - defines `require()` and `define()` as global variables as per the [amd](https://github.com/amdjs/amdjs-api/blob/master/AMD.md) spec.
- `mocha` - adds all of the Mocha testing global variables.
- `jasmine` - adds all of the Jasmine testing global variables for version 1.3 and 2.0.
- `jest` - Jest global variables.
- `phantomjs` - PhantomJS global variables.
- `protractor` - Protractor global variables.
- `qunit` - QUnit global variables.
- `jquery` - jQuery global variables.
- `prototypejs` - Prototype.js global variables.
- `shelljs` - ShellJS global variables.
- `meteor` - Meteor global variables.
- `mongo` - MongoDB global variables.
- `applescript` - AppleScript global variables.
- `nashorn` - Java 8 Nashorn global variables.
- `serviceworker` - Service Worker global variables.
- `atomtest` - Atom test helper globals.
- `embertest` - Ember test helper globals.
- `webextensions` - WebExtensions globals.
- `greasemonkey` - GreaseMonkey globals.
These environments are not mutually exclusive, so you can define more than one at a time.
Environments can be specified inside of a file, in configuration files or using the `--env` [command line](../command-line-interface) flag.
### Using configuration comments
To specify environments with a comment inside of a JavaScript file, use the following format:
```js
/* eslint-env node, mocha */
```
This enables Node.js and Mocha environments.
### Using configuration files
To specify environments in a configuration file, use the `env` key. Specify which environments you want to enable by setting each to `true`. For example, the following enables the browser and Node.js environments:
```json
{
"env": {
"browser": true,
"node": true
}
}
```
Or in a `package.json` file
```json
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
}
}
```
And in YAML:
```yaml
---
env:
browser: true
node: true
```
### Using a plugin
If you want to use an environment from a plugin, be sure to specify the plugin name in the `plugins` array and then use the unprefixed plugin name, followed by a slash, followed by the environment name. For example:
```json
{
"plugins": ["example"],
"env": {
"example/custom": true
}
}
```
Or in a `package.json` file
```json
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"plugins": ["example"],
"env": {
"example/custom": true
}
}
}
```
## Specifying Globals
Some of ESLint's core rules rely on knowledge of the global variables available to your code at runtime. Since these can vary greatly between different environments as well as be modified at runtime, ESLint makes no assumptions about what global variables exist in your execution environment. If you would like to use rules that require knowledge of what global variables are available, you can define global variables in your configuration file or by using configuration comments in your source code.
### Using configuration comments
To specify globals using a comment inside of your JavaScript file, use the following format:
```js
/* global var1, var2 */
```
This defines two global variables, `var1` and `var2`. If you want to optionally specify that these global variables can be written to (rather than only being read), then you can set each with a `"writable"` flag:
```js
/* global var1:writable, var2:writable */
```
### Using configuration files
To configure global variables inside of a configuration file, set the `globals` configuration property to an object containing keys named for each of the global variables you want to use. For each global variable key, set the corresponding value equal to `"writable"` to allow the variable to be overwritten or `"readonly"` to disallow overwriting. For example:
```json
{
"globals": {
"var1": "writable",
"var2": "readonly"
}
}
```
And in YAML:
```yaml
---
globals:
var1: writable
var2: readonly
```
These examples allow `var1` to be overwritten in your code, but disallow it for `var2`.
Globals can be disabled by setting their value to `"off"`. For example, in an environment where most ES2015 globals are available but `Promise` is unavailable, you might use this config:
```json
{
"env": {
"es6": true
},
"globals": {
"Promise": "off"
}
}
```
For historical reasons, the boolean value `false` and the string value `"readable"` are equivalent to `"readonly"`. Similarly, the boolean value `true` and the string value `"writeable"` are equivalent to `"writable"`. However, the use of these older values is deprecated.
## Specifying Parser Options
ESLint allows you to specify the JavaScript language options you want to support. By default, ESLint expects ECMAScript 5 syntax. You can override that setting to enable support for other ECMAScript versions and JSX using parser options.
Please note that supporting JSX syntax is not the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) if you are using React.
By the same token, supporting ES6 syntax is not the same as supporting new ES6 globals (e.g., new types such as `Set`). For ES6 syntax, use `{ "parserOptions": { "ecmaVersion": 6 } }`; for new ES6 global variables, use `{ "env": { "es6": true } }`. Setting `{ "env": { "es6": true } }` enables ES6 syntax automatically, but `{ "parserOptions": { "ecmaVersion": 6 } }` does not enable ES6 globals automatically. In summary, to support only ES6 syntax, use `{ "parserOptions": { "ecmaVersion": 6 } }`, and to support both ES6 syntax and new ES6 global variables, such as `Set` and others, use `{ "env": { "es6": true } }`.
Parser options are set in your `.eslintrc.*` file with the `parserOptions` property. The available options are:
- `ecmaVersion` - set to 3, 5 (default), 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, or 17 to specify the version of ECMAScript syntax you want to use. You can also set it to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), 2022 (same as 13), 2023 (same as 14), 2024 (same as 15), 2025 (same as 16), or 2026 (same as 17) to use the year-based naming. You can also set `"latest"` to use the most recently supported version.
- `sourceType` - set to `"script"` (default) or `"module"` if your code is in ECMAScript modules.
- `allowReserved` - allow the use of reserved words as identifiers (if `ecmaVersion` is 3).
- `ecmaFeatures` - an object indicating which additional language features you'd like to use:
- `globalReturn` - allow `return` statements in the global scope
- `impliedStrict` - enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is 5 or greater)
- `jsx` - enable [JSX](https://facebook.github.io/jsx/)
Here's an example `.eslintrc.json` file:
```json
{
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "error"
}
}
```
Setting parser options helps ESLint determine what is a parsing error. All language options are `false` by default.
---
---
title: Configure Language Options
eleventyNavigation:
key: configure language options
parent: configure
title: Configure Language Options
order: 2
---
::: tip
This page explains how to configure language options using the flat config format. For the deprecated eslintrc format, [see the deprecated documentation](language-options-deprecated).
:::
The JavaScript ecosystem has a variety of runtimes, versions, extensions, and frameworks. Each of these can have different supported syntax and global variables. ESLint lets you configure language options specific to the JavaScript used in your project, like custom global variables. You can also use plugins to extend ESLint to support your project's language options.
## Specifying JavaScript Options
ESLint allows you to specify the JavaScript language options you want to support. By default, ESLint expects the most recent stage 4 ECMAScript syntax and ECMAScript modules (ESM) mode. You can override these settings by using the `languageOptions` key and specifying one or more of these properties:
- `ecmaVersion` (default: `"latest"`) - Indicates the ECMAScript version of the code being linted, determining both the syntax and the available global variables. Set to `3` or `5` for ECMAScript 3 and 5, respectively. Otherwise, you can use any year between `2015` to present. In most cases, we recommend using the default of `"latest"` to ensure you're always using the most recent ECMAScript version.
- `sourceType` (default: `"module"`) - Indicates the mode of the JavaScript file being used. Possible values are:
- `module` - ESM module (invalid when `ecmaVersion` is `3` or `5`). Your code has a module scope and is run in strict mode.
- `commonjs` - CommonJS module (useful if your code uses `require()`). Your code has a top-level function scope and runs in non-strict mode.
- `script` - non-module. Your code has a shared global scope and runs in non-strict mode.
Here's an example [configuration file](./configuration-files#configuration-file) you might use when linting ECMAScript 5 code:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
ecmaVersion: 5,
sourceType: "script",
},
},
]);
```
## Specifying Parser Options
If you are using the built-in ESLint parser, you can additionally change how ESLint interprets your code by specifying the `languageOptions.parserOptions` key. All options are `false` by default:
- `allowReserved` - allow the use of reserved words as identifiers (if `ecmaVersion` is `3`).
- `ecmaFeatures` - an object indicating which additional language features you'd like to use:
- `globalReturn` - allow `return` statements in the global scope.
- `impliedStrict` - enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is `5` or greater).
- `jsx` - enable [JSX](https://facebook.github.io/jsx/).
Here's an example [configuration file](./configuration-files#configuration-file) that enables JSX parsing in the default parser:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
},
]);
```
::: important
Please note that supporting JSX syntax is not the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) if you are using React.
:::
## Specifying Globals
Some of ESLint's core rules rely on knowledge of the global variables available to your code at runtime. Since these can vary greatly between different environments as well as be modified at runtime, ESLint makes no assumptions about what global variables exist in your execution environment. If you would like to use rules that require knowledge of what global variables are available, you can define global variables in your configuration file or by using configuration comments in your source code.
### Using configuration comments
To specify globals using a comment inside of your JavaScript file, use the following format:
```js
/* global var1, var2 */
```
This defines two global variables, `var1` and `var2`. If you want to optionally specify that these global variables can be written to (rather than only being read), then you can set each with a `"writable"` flag:
```js
/* global var1:writable, var2:writable */
```
### Using configuration files
To configure global variables inside of a [configuration file](./configuration-files#configuration-file), set the `languageOptions.globals` configuration property to an object containing keys named for each of the global variables you want to use. For each global variable key, set the corresponding value equal to `"writable"` to allow the variable to be overwritten or `"readonly"` to disallow overwriting. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
globals: {
var1: "writable",
var2: "readonly",
},
},
},
]);
```
This configuration allows `var1` to be overwritten in your code, but disallow it for `var2`.
Globals can be disabled by setting their value to `"off"`. For example, in an environment where most globals are available but `Promise` is unavailable, you might use this config:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
globals: {
Promise: "off",
},
},
},
]);
```
::: tip
For historical reasons, the boolean value `false` and the string value `"readable"` are equivalent to `"readonly"`. Similarly, the boolean value `true` and the string value `"writeable"` are equivalent to `"writable"`. However, the use of these older values is deprecated.
:::
### Predefined global variables
Apart from the ECMAScript standard built-in globals, which are automatically enabled based on the configured `languageOptions.ecmaVersion`, ESLint doesn't provide predefined sets of global variables. You can use the [`globals`](https://www.npmjs.com/package/globals) package to additionally enable all globals for a specific environment. For example, here is how you can add `console`, amongst other browser globals, into your configuration.
```js
// eslint.config.js
import globals from "globals";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
globals: {
...globals.browser,
},
},
},
]);
```
You can include multiple different collections of globals in the same way. The following example includes globals both for web browsers and for [Jest](https://jestjs.io/):
```js
// eslint.config.js
import globals from "globals";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
globals: {
...globals.browser,
...globals.jest,
},
},
},
]);
```
---
---
title: Configuration Migration Guide
eleventyNavigation:
key: migration guide
parent: configure
title: Configuration Migration Guide
order: 9
---
{%- from 'components/npm_tabs.macro.html' import npm_tabs with context %}
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
This guide provides an overview of how you can migrate your ESLint configuration file from the eslintrc format (typically configured in `.eslintrc.js` or `.eslintrc.json` files) to the new flat config format (typically configured in an `eslint.config.js` file).
To learn more about the flat config format, refer to [this blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/).
For reference information on these configuration formats, refer to the following documentation:
- [eslintrc configuration files](configuration-files-deprecated)
- [flat configuration files](configuration-files)
## Migrate Your Config File
To get started, use the [configuration migrator](https://npmjs.com/package/@eslint/migrate-config) on your existing configuration file (`.eslintrc`, `.eslintrc.json`, `.eslintrc.yml`), like this:
{{ npx_tabs({
package: "@eslint/migrate-config",
args: [".eslintrc.json"]
}) }}
This will create a starting point for your `eslint.config.js` file but is not guaranteed to work immediately without further modification. It will, however, do most of the conversion work mentioned in this guide automatically.
::: important
The configuration migrator doesn't yet work well for `.eslintrc.js` files. If you are using `.eslintrc.js`, the migration results in a config file that matches the evaluated output of your configuration and won't include any functions, conditionals, or anything other than the raw data represented in your configuration.
:::
## Start Using Flat Config Files
The flat config file format has been the default configuration file format since ESLint v9.0.0. You can start using the flat config file format without any additional configuration.
To use flat config with ESLint v8, place a `eslint.config.js` file in the root of your project **or** set the `ESLINT_USE_FLAT_CONFIG` environment variable to `true`.
## Things That Haven’t Changed between Configuration File Formats
While the configuration file format has changed from eslintrc to flat config, the following has stayed the same:
- Syntax for configuring rules.
- Syntax for configuring processors.
- The CLI, except for the flag changes noted in [CLI Flag Changes](#cli-flag-changes).
- Global variables are configured the same way, but on a different property (see [Configuring Language Options](#configuring-language-options)).
## Key Differences between Configuration Formats
A few of the most notable differences between the eslintrc and flat config formats are the following:
### Importing Plugins and Custom Parsers
Eslintrc files use string-based import system inside the `plugins` property to load plugins and inside the `extends` property to load external configurations.
Flat config files represent plugins and parsers as JavaScript objects. This means you can use CommonJS `require()` or ES module `import` statements to load plugins and custom parsers from external files.
For example, this eslintrc config file loads `eslint-plugin-jsdoc` and configures rules from that plugin:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
plugins: ["jsdoc"],
rules: {
"jsdoc/require-description": "error",
"jsdoc/check-values": "error",
},
// ...other config
};
```
In flat config, you would do the same thing like this:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import jsdoc from "eslint-plugin-jsdoc";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
jsdoc: jsdoc,
},
rules: {
"jsdoc/require-description": "error",
"jsdoc/check-values": "error",
},
},
]);
```
::: tip
If you import a plugin and get an error such as "TypeError: context.getScope is not a function", then that means the plugin has not yet been updated to the ESLint v9.x rule API. While you should file an issue with the particular plugin, you can manually patch the plugin to work in ESLint v9.x using the [compatibility utilities](https://eslint.org/blog/2024/05/eslint-compatibility-utilities/).
:::
### Custom Parsers
In eslintrc files, importing a custom parser is similar to importing a plugin: you use a string to specify the name of the parser.
In flat config files, import a custom parser as a module, then assign it to the `languageOptions.parser` property of a configuration object.
For example, this eslintrc config file uses the `@babel/eslint-parser` parser:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
parser: "@babel/eslint-parser",
// ...other config
};
```
In flat config, you would do the same thing like this:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import babelParser from "@babel/eslint-parser";
export default defineConfig([
{
// ...other config
languageOptions: {
parser: babelParser,
},
// ...other config
},
]);
```
### Processors
In eslintrc files, processors had to be defined in a plugin, and then referenced by name in the configuration. Processors beginning with a dot indicated a [file extension-named processor](../../extend/custom-processors-deprecated#file-extension-named-processor) which ESLint would automatically configure for that file extension.
In flat config files, processors can still be referenced from plugins by their name, but they can now also be inserted directly into the configuration. Processors will _never_ be automatically configured, and must be explicitly set in the configuration.
As an example with a custom plugin with processors:
```javascript
// node_modules/eslint-plugin-someplugin/index.js
module.exports = {
processors: {
".md": {
preprocess() {},
postprocess() {},
},
someProcessor: {
preprocess() {},
postprocess() {},
},
},
};
```
In eslintrc, you would configure as follows:
```javascript
// .eslintrc.js
module.exports = {
plugins: ["someplugin"],
processor: "someplugin/someProcessor",
};
```
ESLint would also automatically add the equivalent of the following:
```javascript
{
overrides: [
{
files: ["**/*.md"],
processor: "someplugin/.md",
},
];
}
```
In flat config, the following are all valid ways to express the same:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import somePlugin from "eslint-plugin-someplugin";
export default defineConfig([
{
plugins: { somePlugin },
processor: "somePlugin/someProcessor",
},
{
plugins: { somePlugin },
// We can embed the processor object in the config directly
processor: somePlugin.processors.someProcessor,
},
{
// We don't need the plugin to be present in the config to use the processor directly
processor: somePlugin.processors.someProcessor,
},
]);
```
Note that because the `.md` processor is _not_ automatically added by flat config, you also need to specify an extra configuration element:
```javascript
{
files: ["**/*.md"],
processor: somePlugin.processors[".md"]
}
```
### Glob-Based Configs
By default, eslintrc files lint all files (except those covered by `.eslintignore`) in the directory in which they’re placed and its child directories. If you want to have different configurations for different file glob patterns, you can specify them in the `overrides` property.
By default, flat config files support different glob pattern-based configs in exported array. You can include the glob pattern in a config object's `files` property. If you don't specify a `files` property, the config defaults to the glob pattern `"**/*.{js,mjs,cjs}"`. Basically, all configuration in the flat config file is like the eslintrc `overrides` property.
#### eslintrc Examples
For example, this eslintrc file applies to all files in the directory where it is placed and its child directories:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
rules: {
semi: ["warn", "always"],
},
};
```
This eslintrc file supports multiple configs with overrides:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
overrides: [
{
files: ["src/**/*"],
rules: {
semi: ["warn", "always"],
},
},
{
files: ["test/**/*"],
rules: {
"no-console": "off",
},
},
],
};
```
For flat config, here is a configuration with the default glob pattern:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
export default defineConfig([
js.configs.recommended, // Recommended config applied to all files
// Override the recommended config
{
rules: {
indent: ["error", 2],
"no-unused-vars": "warn",
},
// ...other configuration
},
]);
```
A flat config example configuration supporting multiple configs for different glob patterns:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
export default defineConfig([
js.configs.recommended, // Recommended config applied to all files
// File-pattern specific overrides
{
files: ["src/**/*", "test/**/*"],
rules: {
semi: ["warn", "always"],
},
},
{
files: ["test/**/*"],
rules: {
"no-console": "off",
},
},
// ...other configurations
]);
```
### Configuring Language Options
In eslintrc files, you configure various language options across the `env`, `globals` and `parserOptions` properties. Groups of global variables for specific runtimes (e.g. `document` and `window` for browser JavaScript; `process` and `require` for Node.js) are configured with the `env` property.
In flat config files, the `globals`, and `parserOptions` are consolidated under the `languageOptions` key; the `env` property doesn't exist. Groups of global variables for specific runtimes are imported from the [globals](https://www.npmjs.com/package/globals) npm package and included in the `globals` property. You can use the spread operator (`...`) to import multiple globals at once.
For example, here's an eslintrc file with language options:
```javascript
// .eslintrc.js
module.exports = {
env: {
browser: true,
node: true,
},
globals: {
myCustomGlobal: "readonly",
},
parserOptions: {
ecmaVersion: 2022,
sourceType: "module",
},
// ...other config
};
```
Here's the same configuration in flat config:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import globals from "globals";
export default defineConfig([
{
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
globals: {
...globals.browser,
...globals.node,
myCustomGlobal: "readonly",
},
},
// ...other config
},
]);
```
::: tip
You'll need to install the `globals` package from npm for this example to work. It is not automatically installed by ESLint.
:::
### `eslint-env` Configuration Comments
In the eslintrc config system it was possible to use `eslint-env` configuration comments to define globals for a file.
These comments are no longer recognized when linting with flat config and will be reported as errors.
For this reason, when migrating from eslintrc to flat config, `eslint-env` configuration comments should be removed from all files.
They can be either replaced with equivalent but more verbose `global` configuration comments, or dropped in favor of `globals` definitions in the config file.
For example, when using eslintrc, a file to be linted could look like this:
```javascript
// tests/my-file.js
/* eslint-env mocha */
describe("unit tests", () => {
it("should pass", () => {
// ...
});
});
```
In the above example, `describe` and `it` would be recognized as global identifiers because of the `/* eslint-env mocha */` comment.
The same effect can be achieved with flat config with a `global` configuration comment, e.g.:
```javascript
// tests/my-file.js
/* global describe, it -- Globals defined by Mocha */
describe("unit tests", () => {
it("should pass", () => {
// ...
});
});
```
Another option is to remove the comment from the file being linted and define the globals in the configuration, for example:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import globals from "globals";
export default defineConfig([
// ...other config
{
files: ["tests/**"],
languageOptions: {
globals: {
...globals.mocha,
},
},
},
]);
```
### Predefined and Shareable Configs
In eslintrc files, use the `extends` property to use predefined and shareable configs. ESLint comes with two predefined configs that you can access as strings:
- `"eslint:recommended"`: the rules recommended by ESLint.
- `"eslint:all"`: all rules shipped with ESLint.
You can also use the `extends` property to extend a shareable config. Shareable configs can either be paths to local config files or npm package names.
In flat config files, predefined configs are imported from separate modules into flat config files. The `recommended` and `all` rules configs are located in the [`@eslint/js`](https://www.npmjs.com/package/@eslint/js) package. You must import this package to use these configs:
{{ npm_tabs({
command: "install",
packages: ["@eslint/js"],
args: ["--save-dev"]
}) }}
You can add each of these configs to the exported array or expose specific rules from them. You must import the modules for local config files and npm package configs with flat config.
For example, here's an eslintrc file using the built-in `eslint:recommended` config:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
extends: "eslint:recommended",
rules: {
semi: ["warn", "always"],
},
// ...other config
};
```
This eslintrc file uses built-in config, local custom config, and shareable config from an npm package:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
extends: [
"eslint:recommended",
"./custom-config.js",
"eslint-config-my-config",
],
rules: {
semi: ["warn", "always"],
},
// ...other config
};
```
To use the same configs in flat config, you would do the following:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import customConfig from "./custom-config.js";
import myConfig from "eslint-config-my-config";
export default defineConfig([
js.configs.recommended,
customConfig,
myConfig,
{
rules: {
semi: ["warn", "always"],
},
// ...other config
},
]);
```
Note that because you are just importing JavaScript modules, you can mutate the config objects before ESLint uses them. For example, you might want to have a certain config object only apply to your test files:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import customTestConfig from "./custom-test-config.js";
export default defineConfig([
js.configs.recommended,
{
...customTestConfig,
files: ["**/*.test.js"],
},
]);
```
#### Using eslintrc Configs in Flat Config
You may find that there's a shareable config you rely on that hasn't yet been updated to flat config format. In that case, you can use the `FlatCompat` utility to translate the eslintrc format into flat config format. First, install the `@eslint/eslintrc` package:
{{ npm_tabs({
command: "install",
packages: ["@eslint/eslintrc"],
args: ["--save-dev"]
}) }}
Then, import `FlatCompat` and create a new instance to convert an existing eslintrc config. For example, if the npm package `eslint-config-my-config` is in eslintrc format, you can write this:
```js
import { defineConfig } from "eslint/config";
import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";
// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
export default defineConfig([
// mimic ESLintRC-style extends
...compat.extends("eslint-config-my-config"),
]);
```
This example uses the `FlatCompat#extends()` method to insert the `eslint-config-my-config` into the flat config array.
For more information about the `FlatCompat` class, please see the [package README](https://github.com/eslint/eslintrc#usage).
### Ignoring Files
With eslintrc, you can make ESLint ignore files by creating a separate `.eslintignore` file in the root of your project. The `.eslintignore` file uses the same glob pattern syntax as `.gitignore` files. Alternatively, you can use an `ignorePatterns` property in your eslintrc file.
To ignore files with flat config, you can use the `ignores` property in a config object with no other properties. The `ignores` property accepts an array of glob patterns. Flat config does not support loading ignore patterns from `.eslintignore` files, so you'll need to migrate those patterns directly into flat config.
For example, here's a `.eslintignore` example you can use with an eslintrc config:
```shell
# .eslintignore
temp.js
config/*
# ...other ignored files
```
Here are the same patterns represented as `ignorePatterns` in a `.eslintrc.js` file:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
ignorePatterns: ["temp.js", "config/*"],
};
```
The equivalent ignore patterns in flat config look like this:
```javascript
import { defineConfig } from "eslint/config";
export default defineConfig([
// ...other config
{
// Note: there should be no other properties in this object
ignores: ["**/temp.js", "config/*"],
},
]);
```
In `.eslintignore`, `temp.js` ignores all files named `temp.js`, whereas in flat config, you need to specify this as `**/temp.js`. The pattern `temp.js` in flat config only ignores a file named `temp.js` in the same directory as the configuration file.
::: important
In flat config, dotfiles (e.g. `.dotfile.js`) are no longer ignored by default. If you want to ignore dotfiles, add an ignore pattern of `"**/.*"`.
:::
### Linter Options
Eslintrc files let you configure the linter itself with the `noInlineConfig` and `reportUnusedDisableDirectives` properties.
The flat config system introduces a new top-level property `linterOptions` that you can use to configure the linter. In the `linterOptions` object, you can include `noInlineConfig` and `reportUnusedDisableDirectives`.
For example, here's an eslintrc file with linter options enabled:
```javascript
// .eslintrc.js
module.exports = {
// ...other config
noInlineConfig: true,
reportUnusedDisableDirectives: true,
};
```
Here's the same options in flat config:
```javascript
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
// ...other config
linterOptions: {
noInlineConfig: true,
reportUnusedDisableDirectives: "warn",
},
},
]);
```
### CLI Flag Changes
The following CLI flags are no longer supported with the flat config file format:
- `--env`
- `--ignore-path`
- `--no-eslintrc`
- `--resolve-plugins-relative-to`
- `--rulesdir`
#### `--env`
The `--env` flag was used to enable environment-specific globals (for example, `browser`, or `node`). Flat config doesn't support this flag. Instead, define the relevant globals directly in your configuration. See [Specifying Globals](language-options#specifying-globals) for more details.
For example, if you previously used `--env browser,node`, you’ll need to update your config file like this:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
import globals from "globals";
export default defineConfig([
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
},
]);
```
#### `--ignore-path`
The `--ignore-path` flag was used to specify which file to use as your `.eslintignore`. Flat config doesn't load ignore patterns from `.eslintignore` files and does not support this flag. If you want to include patterns from a `.gitignore` file, use `includeIgnoreFile()` from `@eslint/compat`. See [Including `.gitignore` Files](ignore#including-gitignore-files) for more details.
For example, if you previously used `--ignore-path .gitignore`:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
import { includeIgnoreFile } from "@eslint/compat";
import { fileURLToPath } from "node:url";
const gitignorePath = fileURLToPath(new URL(".gitignore", import.meta.url));
export default defineConfig([
includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"),
// other configs
]);
```
#### `--no-eslintrc`
The `--no-eslintrc` flag has been replaced with `--no-config-lookup`.
#### `--resolve-plugins-relative-to`
The `--resolve-plugins-relative-to` flag was used to indicate which directory plugin references in your configuration file should be resolved relative to. This was necessary because shareable configs could only resolve plugins that were peer dependencies or dependencies of parent packages.
With flat config, shareable configs can specify their dependencies directly, so this flag is no longer needed.
#### `--rulesdir`
The `--rulesdir` flag was used to load additional rules from a specified directory. This is no longer supported when using flat config. You can instead create a plugin containing the local rules you have directly in your config, like this:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
import myRule from "./rules/my-rule.js";
export default defineConfig([
{
// define the plugin
plugins: {
local: {
rules: {
"my-rule": myRule,
},
},
},
// configure the rule
rules: {
"local/my-rule": ["error"],
},
},
]);
```
### `package.json` Configuration No Longer Supported
With eslintrc, it was possible to use a `package.json` file to configure ESLint using the `eslintConfig` key.
With flat config, it's no longer possible to use a `package.json` file to configure ESLint. You'll need to move your configuration into a separate file.
### Additional Changes
The following changes have been made from the eslintrc to the flat config file format:
- The `root` option no longer exists. (Flat config files act as if `root: true` is set.)
- The `files` option cannot be a single string anymore, it must be an array.
- The `sourceType` option now supports the new value `"commonjs"` (`.eslintrc` supports it too, but it was never documented).
## TypeScript Types for Flat Config Files
You can see the TypeScript types for the flat config file format in the [`lib/types` source folder on GitHub](https://github.com/eslint/eslint/tree/main/lib/types). The interface for the objects in the config’s array is called `Linter.Config`.
You can view the type definitions in [`lib/types/index.d.ts`](https://github.com/eslint/eslint/blob/main/lib/types/index.d.ts).
## Visual Studio Code Support
ESLint v9.x support was added in the [`vscode-eslint`](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) v3.0.10.
In versions of `vscode-eslint` prior to v3.0.10, the new configuration system is not enabled by default. To enable support for the new configuration files, edit your `.vscode/settings.json` file and add the following:
```json
{
// required in vscode-eslint < v3.0.10 only
"eslint.experimental.useFlatConfig": true
}
```
In a future version of the ESLint plugin, you will no longer need to enable this manually.
## Further Reading
- [Overview of the flat config file format blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/)
- [API usage of new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-3/)
- [Background to new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-1/)
---
---
title: Configure a Parser (Deprecated)
---
::: warning
This documentation is for configuring parsers using the deprecated eslintrc configuration format. [View the updated documentation](parser).
:::
You can use custom parsers to convert JavaScript code into an abstract syntax tree for ESLint to evaluate. You might want to add a custom parser if your code isn't compatible with ESLint's default parser, Espree.
## Configure a Custom Parser
By default, ESLint uses [Espree](https://github.com/eslint/js/tree/main/packages/espree) as its parser. You can optionally specify that a different parser should be used in your configuration file if the parser meets the following requirements:
1. It must be a Node module loadable from the config file where the parser is used. Usually, this means you should install the parser package separately using npm.
1. It must conform to the [parser interface](../../extend/custom-parsers).
Note that even with these compatibilities, there are no guarantees that an external parser works correctly with ESLint. ESLint does not fix bugs related to incompatibilities with other parsers.
To indicate the npm module to use as your parser, specify it using the `parser` option in your `.eslintrc` file. For example, the following specifies to use Esprima instead of Espree:
```json
{
"parser": "esprima",
"rules": {
"semi": "error"
}
}
```
The following parsers are compatible with ESLint:
- [Esprima](https://www.npmjs.com/package/esprima)
- [@babel/eslint-parser](https://www.npmjs.com/package/@babel/eslint-parser) - A wrapper around the [Babel](https://babeljs.io) parser that makes it compatible with ESLint.
- [@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser) - A parser that converts TypeScript into an ESTree-compatible form so it can be used in ESLint.
Note that when using a custom parser, the `parserOptions` configuration property is still required for ESLint to work properly with features not in ECMAScript 5 by default. Parsers are all passed `parserOptions` and may or may not use them to determine which features to enable.
---
---
title: Configure a Parser
eleventyNavigation:
key: configure parser
parent: configure
title: Configure a Parser
order: 5
---
::: tip
This page explains how to configure parsers using the flat config format. For the deprecated eslintrc format, [see the deprecated documentation](parser-deprecated).
:::
You can use custom parsers to convert JavaScript code into an abstract syntax tree for ESLint to evaluate. You might want to add a custom parser if your code isn't compatible with ESLint's default parser, Espree.
## Configure a Custom Parser
In many cases, you can use the [default parser](https://github.com/eslint/js/tree/main/packages/espree) that ESLint ships with for parsing your JavaScript code. You can optionally override the default parser by using the `parser` property. The `parser` property must be an object that conforms to the [parser interface](../../extend/custom-parsers). For example, you can use the [`@babel/eslint-parser`](https://www.npmjs.com/package/@babel/eslint-parser) package to allow ESLint to parse experimental syntax:
```js
// eslint.config.js
import babelParser from "@babel/eslint-parser";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js", "**/*.mjs"],
languageOptions: {
parser: babelParser,
},
},
]);
```
This configuration ensures that the Babel parser, rather than the default Espree parser, is used to parse all files ending with `.js` and `.mjs`.
The following third-party parsers are known to be compatible with ESLint:
- [Esprima](https://www.npmjs.com/package/esprima)
- [@babel/eslint-parser](https://www.npmjs.com/package/@babel/eslint-parser) - A wrapper around the [Babel](https://babeljs.io) parser that makes it compatible with ESLint.
- [@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser) - A parser that converts TypeScript into an ESTree-compatible form so it can be used in ESLint.
::: warning
There are no guarantees that an external parser works correctly with ESLint. ESLint does not fix bugs related to incompatibilities that affect only third-party parsers.
:::
## Configure Parser Options
Parsers may accept options to alter the way they behave. The `languageOptions.parserOptions` is used to pass options directly to parsers. These options are always parser-specific, so you'll need to check the documentation of the parser you're using for available options. Here's an example of setting parser options for the Babel ESLint parser:
```js
// eslint.config.js
import babelParser from "@babel/eslint-parser";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
languageOptions: {
parser: babelParser,
parserOptions: {
requireConfigFile: false,
babelOptions: {
babelrc: false,
configFile: false,
presets: ["@babel/preset-env"],
},
},
},
},
]);
```
::: tip
In addition to the options specified in `languageOptions.parserOptions`, ESLint also passes `ecmaVersion` and `sourceType` to all parsers. This allows custom parsers to understand the context in which ESLint is evaluating JavaScript code.
:::
---
---
title: Configure Plugins (Deprecated)
---
::: warning
This documentation is for configuring plugins using the deprecated eslintrc configuration format. [View the updated documentation](plugins).
:::
You can extend ESLint with plugins in a variety of different ways. Plugins can include:
- Custom rules to validate if your code meets a certain expectation, and what to do if it does not meet that expectation.
- Custom configurations.
- Custom environments.
- Custom processors to extract JavaScript code from other kinds of files or preprocess code before linting.
## Configure Plugins
ESLint supports the use of third-party plugins. Before using a plugin, you have to install it using npm.
To configure plugins inside of a configuration file, use the `plugins` key, which contains a list of plugin names. The `eslint-plugin-` prefix can be omitted from the plugin name.
```json
{
"plugins": ["plugin1", "eslint-plugin-plugin2"]
}
```
And in YAML:
```yaml
---
plugins:
- plugin1
- eslint-plugin-plugin2
```
**Notes:**
1. Plugins are resolved relative to the config file. In other words, ESLint loads the plugin as a user would obtain by running `require('eslint-plugin-pluginname')` in the config file.
2. Plugins in the base configuration (loaded by `extends` setting) are relative to the derived config file. For example, if `./.eslintrc` has `extends: ["foo"]` and the `eslint-config-foo` has `plugins: ["bar"]`, ESLint finds the `eslint-plugin-bar` from `./node_modules/` (rather than `./node_modules/eslint-config-foo/node_modules/`) or ancestor directories. Thus every plugin in the config file and base configurations is resolved uniquely.
### Naming convention
#### Include a plugin
The `eslint-plugin-` prefix can be omitted for both non-scoped and scoped packages.
A non-scoped package:
```js
{
// ...
"plugins": [
"jquery", // means eslint-plugin-jquery
]
// ...
}
```
A scoped package:
```js
{
// ...
"plugins": [
"@jquery/jquery", // means @jquery/eslint-plugin-jquery
"@foobar" // means @foobar/eslint-plugin
]
// ...
}
```
#### Use a plugin
Rules, environments, and configurations defined in plugins must be referenced with the following convention:
- `eslint-plugin-foo` → `foo/a-rule`
- `@foo/eslint-plugin` → `@foo/a-config`
- `@foo/eslint-plugin-bar` → `@foo/bar/a-environment`
For example:
```js
{
// ...
"plugins": [
"jquery", // eslint-plugin-jquery
"@foo/foo", // @foo/eslint-plugin-foo
"@bar" // @bar/eslint-plugin
],
"extends": [
"plugin:@foo/foo/recommended",
"plugin:@bar/recommended"
],
"rules": {
"jquery/a-rule": "error",
"@foo/foo/some-rule": "error",
"@bar/another-rule": "error"
},
"env": {
"jquery/jquery": true,
"@foo/foo/env-foo": true,
"@bar/env-bar": true,
}
// ...
}
```
### Specify a Processor
Plugins may provide processors. Processors can extract JavaScript code from other kinds of files, then let ESLint lint the JavaScript code. Alternatively, processors can convert JavaScript code during preprocessing.
To specify processors in a configuration file, use the `processor` key with the concatenated string of a plugin name and a processor name by a slash. For example, the following enables the processor `a-processor` that the plugin `a-plugin` provided:
```json
{
"plugins": ["a-plugin"],
"processor": "a-plugin/a-processor"
}
```
To specify processors for specific kinds of files, use the combination of the `overrides` key and the `processor` key. For example, the following uses the processor `a-plugin/markdown` for `*.md` files.
```json
{
"plugins": ["a-plugin"],
"overrides": [
{
"files": ["*.md"],
"processor": "a-plugin/markdown"
}
]
}
```
Processors may make named code blocks such as `0.js` and `1.js`. ESLint handles such a named code block as a child file of the original file. You can specify additional configurations for named code blocks in the `overrides` section of the config. For example, the following disables the `strict` rule for the named code blocks which end with `.js` in markdown files.
```json
{
"plugins": ["a-plugin"],
"overrides": [
{
"files": ["*.md"],
"processor": "a-plugin/markdown"
},
{
"files": ["**/*.md/*.js"],
"rules": {
"strict": "off"
}
}
]
}
```
ESLint checks the file path of named code blocks then ignores those if any `overrides` entry didn't match the file path. Be sure to add an `overrides` entry if you want to lint named code blocks other than `*.js`.
---
---
title: Configure Plugins
eleventyNavigation:
key: configure plugins
parent: configure
title: Configure Plugins
order: 4
---
::: tip
This page explains how to configure plugins using the flat config format. For the deprecated eslintrc format, [see the deprecated documentation](plugins-deprecated).
:::
You can extend ESLint with plugins in a variety of different ways. Plugins can include:
- Custom rules to validate if your code meets a certain expectation, and what to do if it does not meet that expectation.
- Custom configurations. Please refer to the plugin's documentation for details on how to use these configurations.
- Custom processors to extract JavaScript code from other kinds of files or preprocess code before linting.
## Configure Plugins
ESLint supports the use of third-party plugins. Plugins are simply objects that conform to a specific interface that ESLint recognizes.
To configure plugins inside of a [configuration file](./configuration-files#configuration-file), use the `plugins` key, which contains an object with properties representing plugin namespaces and values equal to the plugin object.
```js
// eslint.config.js
import example from "eslint-plugin-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
plugins: {
example,
},
rules: {
"example/rule1": "warn",
},
},
]);
```
::: tip
When creating a namespace for a plugin, the convention is to use the npm package name without the `eslint-plugin-` prefix. In the preceding example, `eslint-plugin-example` is assigned a namespace of `example`.
:::
### Configure a Local Plugin
Plugins don't need to be published to npm for use with ESLint. You can also load plugins directly from a file, as in this example:
```js
// eslint.config.js
import local from "./my-local-plugin.js";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
plugins: {
local,
},
rules: {
"local/rule1": "warn",
},
},
]);
```
Here, the namespace `local` is used, but you can also use any name you'd like instead.
### Configure a Virtual Plugin
Plugin definitions can be created virtually directly in your config. For example, suppose you have a rule contained in a file called `my-rule.js` that you'd like to enable in your config. You can define a virtual plugin to do so, as in this example:
```js
// eslint.config.js
import myRule from "./rules/my-rule.js";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
plugins: {
local: {
rules: {
"my-rule": myRule,
},
},
},
rules: {
"local/my-rule": "warn",
},
},
]);
```
Here, the namespace `local` is used to define a virtual plugin. The rule `myRule` is then assigned a name of `my-rule` inside of the virtual plugin's `rules` object. (See [Create Plugins](../../extend/plugins) for the complete format of a plugin.) You can then reference the rule as `local/my-rule` to configure it.
## Use Plugin Rules
You can use specific rules included in a plugin. To do this, specify the plugin
in a configuration object using the `plugins` key. The value for the `plugin` key
is an object where the name of the plugin is the property name and the value is the plugin object itself. Here's an example:
```js
// eslint.config.js
import jsdoc from "eslint-plugin-jsdoc";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
jsdoc: jsdoc,
},
rules: {
"jsdoc/require-description": "error",
"jsdoc/check-values": "error",
},
},
]);
```
In this configuration, the JSDoc plugin is defined to have the name `jsdoc`. The prefix `jsdoc/` in each rule name indicates that the rule is coming from the plugin with that name rather than from ESLint itself.
Because the name of the plugin and the plugin object are both `jsdoc`, you can also shorten the configuration to this:
```js
import jsdoc from "eslint-plugin-jsdoc";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
jsdoc,
},
rules: {
"jsdoc/require-description": "error",
"jsdoc/check-values": "error",
},
},
]);
```
While this is the most common convention, you don't need to use the same name that the plugin prescribes. You can specify any prefix that you'd like, such as:
```js
import jsdoc from "eslint-plugin-jsdoc";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
jsd: jsdoc,
},
rules: {
"jsd/require-description": "error",
"jsd/check-values": "error",
},
},
]);
```
This configuration object uses `jsd` as the prefix plugin instead of `jsdoc`.
## Specify a Processor
Plugins may provide processors. Processors can extract JavaScript code from other kinds of files, then let ESLint lint the JavaScript code. Alternatively, processors can convert JavaScript code during preprocessing.
To specify processors in a [configuration file](./configuration-files#configuration-file), use the `processor` key and assign the name of processor in the format `namespace/processor-name`. For example, the following uses the processor from `@eslint/markdown` for `*.md` files.
```js
// eslint.config.js
import markdown from "@eslint/markdown";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.md"],
plugins: {
markdown,
},
processor: "markdown/markdown",
},
]);
```
Processors may make named code blocks such as `0.js` and `1.js`. ESLint handles such a named code block as a child file of the original file. You can specify additional configurations for named code blocks with additional config objects. For example, the following disables the `strict` rule for the named code blocks which end with `.js` in markdown files.
```js
// eslint.config.js
import markdown from "@eslint/markdown";
import { defineConfig } from "eslint/config";
export default defineConfig([
// applies to all JavaScript files
{
rules: {
strict: "error",
},
},
// applies to Markdown files
{
files: ["**/*.md"],
plugins: {
markdown,
},
processor: "markdown/markdown",
},
// applies only to JavaScript blocks inside of Markdown files
{
files: ["**/*.md/*.js"],
rules: {
strict: "off",
},
},
]);
```
ESLint only lints named code blocks when they are JavaScript files or if they match a `files` entry in a config object. Be sure to add a config object with a matching `files` entry if you want to lint non-JavaScript named code blocks. Also note that [global ignores](./ignore) apply to named code blocks as well.
```js
// eslint.config.js
import markdown from "@eslint/markdown";
import { defineConfig } from "eslint/config";
export default defineConfig([
// applies to Markdown files
{
files: ["**/*.md"],
plugins: {
markdown,
},
processor: "markdown/markdown",
},
// applies to all .jsx files, including jsx blocks inside of Markdown files
{
files: ["**/*.jsx"],
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
},
// ignore jsx blocks inside of test.md files
{
ignores: ["**/test.md/*.jsx"],
},
]);
```
## Specify a Language
Plugins may provide languages. Languages allow ESLint to lint programming languages besides JavaScript. To specify a language in a [configuration file](./configuration-files#configuration-file), use the `language` key and assign the name of language in the format `namespace/language-name`. For example, the following uses the `json/jsonc` language from `@eslint/json` for `*.json` files.
```js
// eslint.config.js
import json from "@eslint/json";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.json"],
plugins: {
json,
},
language: "json/jsonc",
},
]);
```
::: tip
When you specify a `language` in a config object, `languageOptions` becomes specific to that language. Each language defines its own `languageOptions`, so check the documentation of the plugin to determine which options are available.
:::
## Common Problems
- [Plugin rules using the ESLint < v9.0.0 API](../troubleshooting/v9-rule-api-changes)
- [Plugin configurations have not been upgraded to flat config](migration-guide#using-eslintrc-configs-in-flat-config)
---
---
title: Configure Rules (Deprecated)
---
::: warning
This documentation is for configuring rules using the deprecated eslintrc configuration format. [View the updated documentation](rules).
:::
Rules are the core building block of ESLint. A rule validates if your code meets a certain expectation, and what to do if it does not meet that expectation. Rules can also contain additional configuration options specific to that rule.
ESLint comes with a large number of [built-in rules](../../rules/) and you can add more rules through plugins. You can modify which rules your project uses with either configuration comments or configuration files.
## Rule Severities
To change a rule's severity, set the rule ID equal to one of these values:
- `"off"` or `0` - turn the rule off
- `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
- `"error"` or `2` - turn the rule on as an error (exit code is 1 when triggered)
Rules are typically set to `"error"` to enforce compliance with the rule during continuous integration testing, pre-commit checks, and pull request merging because doing so causes ESLint to exit with a non-zero exit code.
If you don't want to enforce compliance with a rule but would still like ESLint to report the rule's violations, set the severity to `"warn"`. This is typically used when introducing a new rule that will eventually be set to `"error"`, when a rule is flagging something other than a potential buildtime or runtime error (such as an unused variable), or when a rule cannot determine with certainty that a problem has been found (when a rule might have false positives and need manual review).
### Using configuration comments
To configure rules inside of a file using configuration comments, use a comment in the following format:
```js
/* eslint eqeqeq: "off", curly: "error" */
```
In this example, [`eqeqeq`](../../rules/eqeqeq) is turned off and [`curly`](../../rules/curly) is turned on as an error. You can also use the numeric equivalent for the rule severity:
```js
/* eslint eqeqeq: 0, curly: 2 */
```
This example is the same as the last example, only it uses the numeric codes instead of the string values. The `eqeqeq` rule is off and the `curly` rule is set to be an error.
If a rule has additional options, you can specify them using array literal syntax, such as:
```js
/* eslint quotes: ["error", "double"], curly: 2 */
```
This comment specifies the "double" option for the [`quotes`](../../rules/quotes) rule. The first item in the array is always the rule severity (number or string).
#### Configuration Comment Descriptions
Configuration comments can include descriptions to explain why the comment is necessary. The description must occur after the configuration and is separated from the configuration by two or more consecutive `-` characters. For example:
```js
/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */
```
```js
/* eslint eqeqeq: "off", curly: "error"
--------
Here's a description about why this configuration is necessary. */
```
```js
/* eslint eqeqeq: "off", curly: "error"
* --------
* This will not work due to the line above starting with a '*' character.
*/
```
### Using configuration files
To configure rules inside of a configuration file, use the `rules` key along with an error level and any options you want to use. For example:
```json
{
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"]
}
}
```
And in YAML:
```yaml
---
rules:
eqeqeq: off
curly: error
quotes:
- error
- double
```
## Rules from Plugins
To configure a rule that is defined within a plugin, prefix the rule ID with the plugin name and `/`.
In a configuration file, for example:
```json
{
"plugins": ["plugin1"],
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"],
"plugin1/rule1": "error"
}
}
```
And in YAML:
```yaml
---
plugins:
- plugin1
rules:
eqeqeq: 0
curly: error
quotes:
- error
- "double"
plugin1/rule1: error
```
In these configuration files, the rule `plugin1/rule1` comes from the plugin named `plugin1`, which is contained in an npm package named `eslint-plugin-plugin1`.
You can also use this format with configuration comments, such as:
```js
/* eslint "plugin1/rule1": "error" */
```
**Note:** When specifying rules from plugins, make sure to omit `eslint-plugin-`. ESLint uses only the unprefixed name internally to locate rules.
## Disabling Rules
### Using configuration comments
- **Use with Caution.** Disabling ESLint rules inline should be restricted and used only in situations with a clear and
valid reason for doing so. Disabling rules inline should not be the default solution to resolve linting errors.
- **Document the Reason.** Provide a comment explaining the reason for disabling a particular rule after the `--` section of the comment. This
documentation should clarify why the rule is being disabled and why it is necessary in that specific situation.
- **Temporary Solutions.** If a disable comment is added as a temporary measure to address a pressing issue, create a follow-up task to address the underlying problem adequately. This ensures that the
disable comment is revisited and resolved at a later stage.
- **Code Reviews and Pair Programming.** Encourage team members to review each other's code regularly. Code reviews can help
identify the reasons behind disable comments and ensure that they are used appropriately.
- **Configurations.** Whenever possible, prefer using ESLint configuration files over disable comments. Configuration
files allow for consistent and project-wide rule handling.
To disable rule warnings in a part of a file, use block comments in the following format:
```js
/* eslint-disable */
alert("foo");
/* eslint-enable */
```
You can also disable or enable warnings for specific rules:
```js
/* eslint-disable no-alert, no-console */
alert("foo");
console.log("bar");
/* eslint-enable no-alert, no-console */
```
**Note:** `/* eslint-enable */` without any specific rules listed causes all disabled rules to be re-enabled.
To disable rule warnings in an entire file, put a `/* eslint-disable */` block comment at the top of the file:
```js
/* eslint-disable */
alert("foo");
```
You can also disable or enable specific rules for an entire file:
```js
/* eslint-disable no-alert */
alert("foo");
```
To ensure that a rule is never applied (regardless of any future enable/disable lines):
```js
/* eslint no-alert: "off" */
alert("foo");
```
To disable all rules on a specific line, use a line or block comment in one of the following formats:
```js
alert("foo"); // eslint-disable-line
// eslint-disable-next-line
alert("foo");
/* eslint-disable-next-line */
alert("foo");
alert("foo"); /* eslint-disable-line */
```
To disable a specific rule on a specific line:
```js
alert("foo"); // eslint-disable-line no-alert
// eslint-disable-next-line no-alert
alert("foo");
alert("foo"); /* eslint-disable-line no-alert */
/* eslint-disable-next-line no-alert */
alert("foo");
```
To disable multiple rules on a specific line:
```js
alert("foo"); // eslint-disable-line no-alert, quotes, semi
// eslint-disable-next-line no-alert, quotes, semi
alert("foo");
alert("foo"); /* eslint-disable-line no-alert, quotes, semi */
/* eslint-disable-next-line no-alert, quotes, semi */
alert("foo");
/* eslint-disable-next-line
no-alert,
quotes,
semi
*/
alert("foo");
```
All of the above methods also work for plugin rules. For example, to disable `eslint-plugin-example`'s `rule-name` rule, combine the plugin's name (`example`) and the rule's name (`rule-name`) into `example/rule-name`:
```js
foo(); // eslint-disable-line example/rule-name
foo(); /* eslint-disable-line example/rule-name */
```
**Note:** Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript.
#### Comment descriptions
Configuration comments can include descriptions to explain why disabling or re-enabling the rule is necessary. The description must come after the configuration and needs to be separated from the configuration by two or more consecutive `-` characters. For example:
```js
// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
console.log("hello");
/* eslint-disable-next-line no-console --
* Here's a very long description about why this configuration is necessary
* along with some additional information
**/
console.log("hello");
```
### Using configuration files
To disable rules inside of a configuration file for a group of files, use the `overrides` key along with a `files` key. For example:
```json
{
"rules": {...},
"overrides": [
{
"files": ["*-test.js","*.spec.js"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}
```
### Disabling Inline Comments
To disable all inline config comments, use the `noInlineConfig` setting in your configuration file. For example:
```json
{
"rules": {...},
"noInlineConfig": true
}
```
You can also use the [`--no-inline-config`](../command-line-interface#--no-inline-config) CLI option to disable rule comments, in addition to other in-line configuration.
#### Report unused `eslint-disable` comments
To report unused `eslint-disable` comments, use the `reportUnusedDisableDirectives` setting. For example:
```json
{
"rules": {...},
"reportUnusedDisableDirectives": true
}
```
This setting is similar to [`--report-unused-disable-directives`](../command-line-interface#--report-unused-disable-directives) CLI option, but doesn't fail linting (reports as `"warn"` severity).
---
---
title: Configure Rules
eleventyNavigation:
key: configure rules
parent: configure
title: Configure Rules
order: 3
---
::: tip
This page explains how to configure rules using the flat config format. For the deprecated eslintrc format, [see the deprecated documentation](rules-deprecated).
:::
Rules are the core building block of ESLint. A rule validates if your code meets a certain expectation, and what to do if it does not meet that expectation. Rules can also contain additional configuration options specific to that rule.
ESLint comes with a large number of [built-in rules](../../rules/) and you can add more rules through plugins. You can modify which rules your project uses with either configuration comments or configuration files.
## Rule Severities
To change a rule's severity, set the rule ID equal to one of these values:
- `"off"` or `0` - turn the rule off.
- `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code).
- `"error"` or `2` - turn the rule on as an error (exit code is 1 when triggered).
Rules are typically set to `"error"` to enforce compliance with the rule during continuous integration testing, pre-commit checks, and pull request merging because doing so causes ESLint to exit with a non-zero exit code.
If you don't want to enforce compliance with a rule but would still like ESLint to report the rule's violations, set the severity to `"warn"`. This is typically used when introducing a new rule that will eventually be set to `"error"`, when a rule is flagging something other than a potential buildtime or runtime error (such as an unused variable), or when a rule cannot determine with certainty that a problem has been found (when a rule might have false positives and need manual review).
### Using configuration comments
To configure rules inside of a file using configuration comments, use a comment in the following format:
```js
/* eslint eqeqeq: "off", curly: "error" */
```
In this example, [`eqeqeq`](../../rules/eqeqeq) is turned off and [`curly`](../../rules/curly) is turned on as an error. You can also use the numeric equivalent for the rule severity:
```js
/* eslint eqeqeq: 0, curly: 2 */
```
This example is the same as the last example, only it uses the numeric codes instead of the string values. The [`eqeqeq`](../../rules/eqeqeq) rule is off and the [`curly`](../../rules/curly) rule is set to be an error.
If a rule has additional options, you can specify them using array literal syntax, such as:
```js
/* eslint quotes: ["error", "double"], curly: 2 */
```
This comment specifies the `"double"` option for the [`quotes`](../../rules/quotes) rule. The first item in the array is always the rule severity (number or string).
#### Configuration Comment Descriptions
Configuration comments can include descriptions to explain why the comment is necessary. The description must occur after the configuration and is separated from the configuration by two or more consecutive `-` characters. For example:
```js
/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */
```
```js
/* eslint eqeqeq: "off", curly: "error"
--------
Here's a description about why this configuration is necessary. */
```
```js
/* eslint eqeqeq: "off", curly: "error"
* --------
* This will not work due to the line above starting with a '*' character.
*/
```
#### Report unused `eslint` inline config comments
To report unused `eslint` inline config comments (those that don't change anything from what was already configured), use the `reportUnusedInlineConfigs` setting. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
linterOptions: {
reportUnusedInlineConfigs: "error",
},
},
]);
```
This setting defaults to `"off"`.
This setting is similar to the [`--report-unused-inline-configs`](../command-line-interface#--report-unused-inline-configs) CLI option.
### Using Configuration Files
To configure rules inside of a [configuration file](./configuration-files#configuration-file), use the `rules` key along with an error level and any options you want to use. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
eqeqeq: "off",
"no-unused-vars": "error",
"prefer-const": ["error", { ignoreReadBeforeAssign: true }],
},
},
]);
```
When more than one configuration object specifies the same rule, the rule configuration is merged with the later object taking precedence over any previous objects. For example:
```js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
semi: ["error", "never"],
},
},
{
rules: {
semi: ["warn", "always"],
},
},
]);
```
Using this configuration, the final rule configuration for `semi` is `["warn", "always"]` because it appears last in the array. The array indicates that the configuration is for the severity and any options. You can change just the severity by defining only a string or number, as in this example:
```js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
semi: ["error", "never"],
},
},
{
rules: {
semi: "warn",
},
},
]);
```
Here, the second configuration object only overrides the severity, so the final configuration for `semi` is `["warn", "never"]`.
::: important
Rules configured via configuration comments have the highest priority and are applied after all configuration files settings.
:::
## Rules from Plugins
To configure a rule that is defined within a plugin, prefix the rule ID with the plugin namespace and `/`.
In a [configuration file](./configuration-files#configuration-file), for example:
```js
// eslint.config.js
import example from "eslint-plugin-example";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
plugins: {
example,
},
rules: {
"example/rule1": "warn",
},
},
]);
```
In this configuration file, the rule `example/rule1` comes from the plugin named `eslint-plugin-example`.
You can also use this format with configuration comments, such as:
```js
/* eslint "example/rule1": "error" */
```
:::important
In order to use plugin rules in configuration comments, your configuration file must load the plugin and specify it in the `plugins` object of your config. Configuration comments can not load plugins on their own.
:::
## Disabling Rules
### Using configuration comments
- **Use with Caution.** Disabling ESLint rules inline should be restricted and used only in situations with a clear and
valid reason for doing so. Disabling rules inline should not be the default solution to resolve linting errors.
- **Document the Reason.** Provide a comment explaining the reason for disabling a particular rule after the `--` section of the comment. This
documentation should clarify why the rule is being disabled and why it is necessary in that specific situation.
- **Temporary Solutions.** If a disable comment is added as a temporary measure to address a pressing issue, create a follow-up task to address the underlying problem adequately. This ensures that the
disable comment is revisited and resolved at a later stage.
- **Code Reviews and Pair Programming.** Encourage team members to review each other's code regularly. Code reviews can help
identify the reasons behind disable comments and ensure that they are used appropriately.
- **Configurations.** Whenever possible, prefer using ESLint configuration files over disable comments. Configuration
files allow for consistent and project-wide rule handling.
To disable rule warnings in a part of a file, use block comments in the following format:
```js
/* eslint-disable */
alert("foo");
/* eslint-enable */
```
You can also disable or enable warnings for specific rules:
```js
/* eslint-disable no-alert, no-console */
alert("foo");
console.log("bar");
/* eslint-enable no-alert, no-console */
```
::: warning
`/* eslint-enable */` without any specific rules listed causes all disabled rules to be re-enabled.
:::
To disable rule warnings in an entire file, put a `/* eslint-disable */` block comment at the top of the file:
```js
/* eslint-disable */
alert("foo");
```
You can also disable or enable specific rules for an entire file:
```js
/* eslint-disable no-alert */
alert("foo");
```
To ensure that a rule is never applied (regardless of any future enable/disable lines):
```js
/* eslint no-alert: "off" */
alert("foo");
```
To disable all rules on a specific line, use a line or block comment in one of the following formats:
```js
alert("foo"); // eslint-disable-line
// eslint-disable-next-line
alert("foo");
/* eslint-disable-next-line */
alert("foo");
alert("foo"); /* eslint-disable-line */
```
To disable a specific rule on a specific line:
```js
alert("foo"); // eslint-disable-line no-alert
// eslint-disable-next-line no-alert
alert("foo");
alert("foo"); /* eslint-disable-line no-alert */
/* eslint-disable-next-line no-alert */
alert("foo");
```
To disable multiple rules on a specific line:
```js
alert("foo"); // eslint-disable-line no-alert, quotes, semi
// eslint-disable-next-line no-alert, quotes, semi
alert("foo");
alert("foo"); /* eslint-disable-line no-alert, quotes, semi */
/* eslint-disable-next-line no-alert, quotes, semi */
alert("foo");
/* eslint-disable-next-line
no-alert,
quotes,
semi
*/
alert("foo");
```
All of the above methods also work for plugin rules. For example, to disable `eslint-plugin-example`'s `rule-name` rule, combine the plugin's name (`example`) and the rule's name (`rule-name`) into `example/rule-name`:
```js
foo(); // eslint-disable-line example/rule-name
foo(); /* eslint-disable-line example/rule-name */
```
::: tip
Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript.
:::
#### Comment descriptions
Configuration comments can include descriptions to explain why disabling or re-enabling the rule is necessary. The description must come after the configuration and needs to be separated from the configuration by two or more consecutive `-` characters. For example:
```js
// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
console.log("hello");
/* eslint-disable-next-line no-console --
* Here's a very long description about why this configuration is necessary
* along with some additional information
**/
console.log("hello");
```
### Using configuration files
To disable rules inside of a [configuration file](./configuration-files#configuration-file) for a group of files, use a subsequent config object with a `files` key. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
"no-unused-expressions": "error",
},
},
{
files: ["*-test.js", "*.spec.js"],
rules: {
"no-unused-expressions": "off",
},
},
]);
```
### Disabling Inline Comments
To disable all inline config comments, use the `noInlineConfig` setting in your configuration file. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
linterOptions: {
noInlineConfig: true,
},
rules: {
"no-unused-expressions": "error",
},
},
]);
```
You can also use the [`--no-inline-config`](../command-line-interface#--no-inline-config) CLI option to disable rule comments, in addition to other in-line configuration.
#### Report unused `eslint-disable` comments
To report unused `eslint-disable` comments (those that disable rules which would not report on the disabled line), use the `reportUnusedDisableDirectives` setting. For example:
```js
// eslint.config.js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
linterOptions: {
reportUnusedDisableDirectives: "error",
},
},
]);
```
This setting defaults to `"warn"`.
This setting is similar to [`--report-unused-disable-directives`](../command-line-interface#--report-unused-disable-directives) and [`--report-unused-disable-directives-severity`](../command-line-interface#--report-unused-disable-directives-severity) CLI options.
---
---
title: Glossary
eleventyNavigation:
key: glossary
title: Glossary
parent: core concepts
---
This page serves as a reference for common terms associated with ESLint.
## A
### Abstract Syntax Tree (AST)
A structured representation of code syntax.
Each section of source code in an AST is referred to as a [node](#node).
Each node may have any number of properties, including properties that store child nodes.
The AST format used by ESLint is the [ESTree](#estree) format.
ESLint [rules](#rule) are given an AST and may produce [violations](#violation) on parts of the AST when they detect a [violation](#violation).
## C
### Config File (Configuration File)
A file containing preferences for how ESLint should parse files and run [rules](#rule).
ESLint config files are named like `eslint.config.(c|m)js`.
Each config file exports a [config array](#config-array) containing [config objects](#config-object).
For example, this `eslint.config.js` file enables the `prefer-const` [rule](#rule) at the _error_ [severity](#severity):
```js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
"prefer-const": "error",
},
},
]);
```
See [Configuration Files](../configure/configuration-files) for more details.
### Config Array
An array of [config objects](#config-object) within a [config file](#config-file-configuration-file).
Each config file exports an array of config objects.
The objects in the array are evaluated in order: later objects may override settings specified in earlier objects.
See [Configuration Files](../configure/configuration-files) for more details.
### Config Object
A [config file](#config-file-configuration-file) entry specifying all of the information ESLint needs to execute on a set of files.
Each configuration object may include properties describing which files to run on, how to handle different file types, which [plugins](#plugin) to include, and how to run [rules](#rule).
See [Configuration Files > Configuration Objects](../configure/configuration-files#configuration-objects) for more details.
## E
### ESQuery
The library used by ESLint to parse [selector](#selector) syntax for querying [nodes](#node) in an [AST](#abstract-syntax-tree-ast).
ESQuery interprets CSS syntax for AST node properties.
Examples of ESQuery selectors include:
- `BinaryExpression`: selects all nodes of type _BinaryExpression_
- `BinaryExpression[operator='+']`: selects all _BinaryExpression_ nodes whose _operator_ is `+`
- `BinaryExpression > Literal[value=1]`: selects all _Literal_ nodes with _value_ `1` whose direct parent is a _BinaryExpression_
See [github.com/estools/esquery](https://github.com/estools/esquery) for more information on the ESQuery format.
### ESTree
The format used by ESLint for how to represent JavaScript syntax as an [AST](#abstract-syntax-tree-ast).
For example, the ESTree representation of the code `1 + 2;` would be an object roughly like:
```json
{
"type": "ExpressionStatement",
"expression": {
"type": "BinaryExpression",
"left": {
"type": "Literal",
"value": 1,
"raw": "1"
},
"operator": "+",
"right": {
"type": "Literal",
"value": 2,
"raw": "2"
}
}
}
```
[Static analysis](#static-analysis) tools such as ESLint typically operate by converting syntax into an AST in the ESTree format.
See [github.com/estree/estree](https://github.com/estree/estree) for more information on the ESTree specification.
## F
### Fix
An optional augmentation to a [rule](#rule) [violation](#violation) that describes how to automatically correct the violation.
Fixes are generally "safe" to apply automatically: they shouldn't cause code behavior changes.
ESLint attempts to apply as many fixes as possible in a [report](#report) when run with the `--fix` flag, though there is no guarantee that all fixes will be applied.
Fixes may also be applied by common editor extensions.
Rule violations may also include file changes that are unsafe and not automatically applied in the form of [suggestions](#suggestion).
### Flat Config
The current configuration file format for ESLint.
Flat config files are named in the format `eslint.config.(c|m)?js`.
"Flat" config files are named as such because all nesting must be done in one configuration file.
In contrast, the ["Legacy" config format](#legacy-config) allowed nesting configuration files in sub-directories within a project.
You can read more about the motivations behind flat configurations in [ESLint's new config system, Part 2: Introduction to flat config](https://eslint.org/blog/2022/08/new-config-system-part-2).
### Formatter (Linting)
A package that presents the [report](#report) generated by ESLint.
ESLint ships with several built-in reporters, including `stylish` (default), `json`, and `html`.
For more information, see [Formatters](../formatters).
### Formatter (Tool)
A [static analysis](#static-analysis) tool that quickly reformats code without changing its logic or names.
Formatters generally only modify the "trivia" of code, such as semicolons, spacing, newlines, and whitespace in general.
Trivia changes generally don't modify the [AST](#abstract-syntax-tree-ast) of code.
Common formatters in the ecosystem include [Prettier](https://prettier.io) and [dprint](https://dprint.dev).
Note that although ESLint is a [linter](#linter) rather than a formatter, ESLint rules can also apply formatting changes to source code.
See [Formatting (Rule)](#formatting-rule) for more information on formatting rules.
### Formatting (Rule)
A rule that solely targets [formatting](#formatter-tool) concerns, such as semicolons and whitespace.
These rules don't change application logic and are a subset of [Stylistic rules](#stylistic-rule).
ESLint no longer recommends formatting rules and previously deprecated its built-in formatting rules.
ESLint recommends instead using a dedicated formatter such as [Prettier](https://prettier.io) or [dprint](https://dprint.dev).
Alternately, the [ESLint Stylistic project](https://eslint.style) provides formatting-related lint rules.
For more information, see [Deprecation of formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules).
## G
### Global Declaration
A description to ESLint of a JavaScript [global variable](#global-variable) that should exist at runtime.
Global declarations inform lint rules that check for proper uses of global variables.
For example, the [`no-undef` rule](../../rules/no-undef) will create a violation for references to global variables not defined in the configured list of globals.
[Config files](#config-file-configuration-file) have globals defined as JavaScript objects.
For information about configuring globals, see [Configure Language Options > Specifying Globals](../configure/language-options#specifying-globals).
### Global Variable
A runtime variable that exists in the global scope, meaning all modules and scripts have access to it.
Global variables in JavaScript are declared on the `globalThis` object (generally aliased as `global` in Node.js and `window` in browsers).
You can let ESLint know which global variables your code uses with [global declarations](#global-declaration).
## I
### Inline Config (Configuration Comment)
A source code comment that configures a rule to a different severity and/or set of options.
Inline configs use similar syntax as [config files](#config-file-configuration-file) to specify any number of rules by name, their new severity, and optionally new options for the rules.
For example, the following inline config comment simultaneously disables the [`eqeqeq`](../../rules/eqeqeq) rule and sets the [`curly`](../../rules/curly) rule to `"error"`:
```js
/* eslint eqeqeq: "off", curly: "error" */
```
For documentation on inline config comments, see [Rules > Using configuration comments](../configure/rules#using-configuration-comments).
## L
### Legacy Config
The previous configuration file format for ESLint, now superseded by ["Flat" config](#flat-config).
Legacy ESLint configurations are named in the format `.eslintrc.*` and allowed to be nested across files within sub-directories in a project.
You can read more about the lifetime of legacy configurations in [ESLint's new config system, Part 1: Background](https://eslint.org/blog/2022/08/new-config-system-part-1).
### Linter
A [static analysis](#static-analysis) tool that can [report](#report) the results from running a set of [rules](#rule) on source code.
Each rule may report any number of [violations](#violation) in the source code.
ESLint is a commonly used linter for JavaScript and other web technologies.
Note that a _linter_ is separate from [formatters](#formatter-tool) and [type checkers](#type-checker).
### Logical Rule
A [rule](#rule) that inspects how code operates to find problems.
Many logical rules look for likely crashes (e.g. [`no-undef`](../../rules/no-undef)), unintended behavior (e.g. [`no-sparse-arrays`](../../rules/no-sparse-arrays)), and unused code (e.g [`no-unused-vars`](../../rules/no-unused-vars)).
You can see the full list of logical rules that ship with ESLint under [Rules > Possible Problems](../../rules/#possible-problems)
## N
### Node
A section of code within an [AST](#abstract-syntax-tree-ast).
Each node represents a type of syntax found in source code.
For example, the `1 + 2` in the AST for `1 + 2;` is a _BinaryExpression_.
See [#esquery](#esquery) for the library ESLint uses to parse [selectors](#selector) that allow [rules](#rule) to search for nodes.
## O
### Override
When a [config object](#config-object) or [inline config](#inline-config-configuration-comment) sets a new severity and/or rule options that supersede previously set severity and/or options.
The following [config file](#config-file-configuration-file) overrides `no-unused-expressions` from `"error"` to `"off"` in `*.test.js` files:
```js
import { defineConfig } from "eslint/config";
export default defineConfig([
{
rules: {
"no-unused-expressions": "error",
},
},
{
files: ["*.test.js"],
rules: {
"no-unused-expressions": "off",
},
},
]);
```
The following [inline config](#inline-config-configuration-comment) sets `no-unused-expressions` to `"error"`:
```js
/* eslint no-unused-expressions: "error" */
```
For more information on overrides in legacy configs, see [Configuration Files (Deprecated) > How do overrides work?](../configure/configuration-files-deprecated#how-do-overrides-work).
## P
### Parser
An object containing a method that reads in a string and converts it to a standardized format.
ESLint uses parsers to convert source code strings into an [AST](#abstract-syntax-tree-ast) shape.
By default, ESLint uses the [Espree](https://github.com/eslint/js/tree/main/packages/espree) parser, which generates an AST compatible with standard JavaScript runtimes and versions.
Custom parsers let ESLint parse non-standard JavaScript syntax.
Often custom parsers are included as part of shareable configurations or plugins, so you don’t have to use them directly.
For example, [@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser) is a custom parser included in the [typescript-eslint](https://typescript-eslint.io) project that lets ESLint parse TypeScript code.
For more information on using parsers with ESLint, see [Configure a Parser](../configure/parser).
### Plugin
A package that can contain a set of [configurations](#shareable-config-configuration), [processors](#processor), and/or [rules](#rule).
A popular use case for plugins is to enforce best practices for a framework.
For example, [@angular-eslint/eslint-plugin](https://www.npmjs.com/package/@angular-eslint/eslint-plugin) contains best practices for using the Angular framework.
For more information, refer to [Configure Plugins](../configure/plugins).
### Processor
A part of a plugin that extracts JavaScript code from other kinds of files, then lets ESLint lint the JavaScript code.
For example, [`@eslint/markdown`](https://github.com/eslint/markdown) includes a processor that converts the text of ``` code blocks in Markdown files into code that can be linted.
For more information on configuring processor, see [Plugins > Specify a Processor](../configure/plugins#specify-a-processor).
## R
### Report
A collection of [violations](#violation) from a single ESLint run.
When ESLint runs on source files, it will pass an [AST](#abstract-syntax-tree-ast) for each source file to each configured [rule](#rule).
The collection of violations from each of the rules will be packaged together and passed to a [formatter](#formatter-linting) to be presented to the user.
### Rule
Code that checks an [AST](#abstract-syntax-tree-ast) for expected patterns. When a rule's expectation is not met, it creates a [violation](#violation).
ESLint provides a large collection of rules that check for common JavaScript code issues.
Many more rules may be loaded in by [plugins](#plugin).
For an overview of rules provided, see [Core Concepts > Rules](../core-concepts/#rules).
## S
### Selector
Syntax describing how to search for [nodes](#node) within an [AST](#abstract-syntax-tree-ast).
ESLint [rules](#rule) use [ESQuery](#esquery) selectors to find nodes that should be checked.
### Severity
What level of reporting a rule is configured to run, if at all.
ESLint supports three levels of severity:
- `"off"` (`0`): Do not run the rule.
- `"warn"` (`1`): Run the rule, but don't exit with a non-zero status code based on its violations (excluding the [`--max-warnings` flag](../command-line-interface#--max-warnings))
- `"error"` (`2`): Run the rule, and exit with a non-zero status code if it produces any violations
For documentation on configuring rules, see [Configure Rules](../configure/rules).
### Shareable Config (Configuration)
A module that provides a predefined [config file](#config-file-configuration-file) configurations.
Shareable configs can configure all the same information from config files, including [plugins](#plugin) and [rules](#rule).
Shareable configs are often provided alongside [plugins](#plugin).
Many plugins provide configs with names like _"recommended"_ that enable their suggested starting set of rules.
For example, [`eslint-plugin-solid`](https://github.com/solidjs-community/eslint-plugin-solid) provides a shareable recommended config:
```js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
import solid from "eslint-plugin-solid/configs/recommended";
export default defineConfig([js.configs.recommended, solid]);
```
For information on shareable configs, see [Share Configurations](../../extend/shareable-configs).
### Static Analysis
The process of analyzing source code without building or running it.
[Linters](#linter) such as ESLint, [formatters](#formatter-tool), and [type checkers](#type-checker) are examples of static analysis tools.
Static analysis is different from _dynamic_ analysis, which is the process of evaluating source code after it is built and executed.
Unit, integration, and end-to-end tests are common examples of dynamic analysis.
### Stylistic (Rule)
A rule that enforces a preference rather than a logical issue.
Stylistic areas include [Formatting rules](#formatting-rule), naming conventions, and consistent choices between equivalent syntaxes.
ESLint's built-in stylistic rules are feature frozen: except for supporting new ECMAScript versions, they won't receive new features.
For more information, see [Changes to our rules policies](https://eslint.org/blog/2020/05/changes-to-rules-policies) and [Deprecation of formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules).
### Suggestion
An optional augmentation to a [rule](#rule) [violation](#violation) that describes how one may manually adjust the code to address the violation.
Suggestions are not generally safe to apply automatically because they cause code behavior changes.
ESLint does not apply suggestions directly but does provide suggestion to integrations that may choose to apply suggestions (such as an editor extension).
Rule violations may also include file changes that are safe and may be automatically applied in the form of [fixes](#fix).
## T
### Type Checker
A [static analysis](#static-analysis) tool that builds a full understanding of a project's code constructs and data shapes.
Type checkers are generally slower and more comprehensive than linters.
Whereas linters traditionally operate only on a single file's or snippet's [AST](#abstract-syntax-tree-ast) at a time, type checkers understand cross-file dependencies and types.
[TypeScript](https://typescriptlang.org) is the most common type checker for JavaScript.
The [typescript-eslint](https://typescript-eslint.io) project provides integrations that allow using type checker in lint rules.
## V
### Violation
An indication from a [rule](#rule) that an area of code doesn't meet the expectation of the rule.
Rule violations indicate a range in source code and error message explaining the violation.
Violations may also optionally include a [fix](#fix) and/or [suggestions](#suggestion) that indicate how to improve the violating code.
---
---
title: Core Concepts
eleventyNavigation:
key: core concepts
title: Core Concepts
parent: use eslint
order: 2
---
This page contains a high-level overview of some of the core concepts of ESLint.
## What is ESLint?
ESLint is a configurable JavaScript linter. It helps you find and fix problems in your JavaScript code. Problems can be anything from potential runtime bugs, to not following best practices, to styling issues.
## Rules
Rules are the core building block of ESLint. A rule validates if your code meets a certain expectation, and what to do if it does not meet that expectation. Rules can also contain additional configuration options specific to that rule.
For example, the [`semi`](../../rules/semi) rule lets you specify whether or not JavaScript statements should end with a semicolon (`;`). You can set the rule to either always require semicolons or require that a statement never ends with a semicolon.
ESLint contains hundreds of built-in rules that you can use. You can also create custom rules or use rules that others have created with [plugins](#plugins).
For more information, refer to [Rules](../../rules/).
### Rule Fixes
Rules may optionally provide fixes for violations that they find. Fixes safely correct the violation without changing application logic.
Fixes may be applied automatically with the [`--fix` command line option](../command-line-interface#--fix) and via editor extensions.
Rules that may provide fixes are marked with 🔧 in [Rules](../../rules/).
### Rule Suggestions
Rules may optionally provide suggestions in addition to or instead of providing fixes. Suggestions differ from fixes in two ways:
1. Suggestions may change application logic and so cannot be automatically applied.
1. Suggestions cannot be applied through the ESLint CLI and are only available through editor integrations.
Rules that may provide suggestions are marked with 💡 in [Rules](../../rules/).
## Configuration Files
An ESLint configuration file is a place where you put the configuration for ESLint in your project. You can include built-in rules, how you want them enforced, plugins with custom rules, shareable configurations, which files you want rules to apply to, and more.
For more information, refer to [Configuration Files](../configure/configuration-files).
## Shareable Configurations
Shareable configurations are ESLint configurations that are shared via npm.
Often shareable configurations are used to enforce style guides using ESLint's built-in rules. For example the shareable configuration [eslint-config-airbnb-base](https://www.npmjs.com/package/eslint-config-airbnb-base) implements the popular Airbnb JavaScript style guide.
For more information, refer to [Using a Shareable Configuration Package](../configure/configuration-files#using-a-shareable-configuration-package).
## Plugins
An ESLint plugin is an npm module that can contain a set of ESLint rules, configurations, processors, and languages. Often plugins include custom rules. Plugins can be used to enforce a style guide and support JavaScript extensions (like [TypeScript](https://www.typescriptlang.org)), libraries (like [React](https://react.dev)), and frameworks (like [Angular](https://angular.dev)).
A popular use case for plugins is to enforce best practices for a framework. For example, [@angular-eslint/eslint-plugin](https://www.npmjs.com/package/@angular-eslint/eslint-plugin) contains best practices for using the Angular framework.
For more information, refer to [Configure Plugins](../configure/plugins).
## Parsers
An ESLint parser converts code into an abstract syntax tree that ESLint can evaluate. By default, ESLint uses the built-in [Espree](https://github.com/eslint/js/tree/main/packages/espree) parser, which is compatible with standard JavaScript runtimes and versions.
Custom parsers let ESLint parse non-standard JavaScript syntax. Often custom parsers are included as part of shareable configurations or plugins, so you don't have to use them directly.
For example, [@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser) is a custom parser included in the [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) project that lets ESLint parse TypeScript code.
## Custom Processors
An ESLint processor extracts JavaScript code from other kinds of files, then lets ESLint lint the JavaScript code. Alternatively, you can use a processor to manipulate JavaScript code before parsing it with ESLint.
For example, [@eslint/markdown](https://github.com/eslint/markdown) contains a custom processor that lets you lint JavaScript code inside of Markdown code blocks.
## Formatters
An ESLint formatter controls the appearance of the linting results in the CLI.
For more information, refer to [Formatters](../formatters/).
## Integrations
One of the things that makes ESLint such a useful tool is the ecosystem of integrations that surrounds it. For example, many code editors have ESLint extensions that show you the ESLint results of your code in the file as you work so that you don't need to use the ESLint CLI to see linting results.
For more information, refer to [Integrations](../integrations).
## CLI & Node.js API
The ESLint CLI is a command line interface that lets you execute linting from the terminal. The CLI has a variety of options that you can pass to its commands.
The ESLint Node.js API lets you use ESLint programmatically from Node.js code. The API is useful when developing plugins, integrations, and other tools related to ESLint.
Unless you are extending ESLint in some way, you should use the CLI.
For more information, refer to [Command Line Interface](../command-line-interface) and [Node.js API](../../integrate/nodejs-api).
---
---
title: Formatters Reference
eleventyNavigation:
key: formatters
parent: use eslint
title: Formatters Reference
order: 7
edit_link: https://github.com/eslint/eslint/edit/main/templates/formatter-examples.md.ejs
---
ESLint comes with several built-in formatters to control the appearance of the linting results, and supports third-party formatters as well.
You can specify a formatter using the [`--format` or `-f`](../command-line-interface#-f---format) flag in the CLI. For example, `--format json` uses the `json` formatter.
The built-in formatter options are:
* [html](#html)
* [json-with-metadata](#json-with-metadata)
* [json](#json)
* [stylish](#stylish)
## Example Source
Examples of each formatter were created from linting `fullOfProblems.js` using the `eslint.config.js` configuration shown below.
`fullOfProblems.js`:
```js
function addOne(i) {
if (i != NaN) {
return i ++
} else {
return
}
};
```
`eslint.config.js`:
```js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
js,
},
extends: ["js/recommended"],
rules: {
"consistent-return": 2,
"indent" : [1, 4],
"no-else-return" : 1,
"semi" : [1, "always"],
"space-unary-ops" : 2
}
}
]);
```
Tests the formatters with the CLI:
```shell
npx eslint --format fullOfProblems.js
```
## Built-In Formatter Options
### html
Outputs results to HTML. The `html` formatter is useful for visual presentation in the browser.
Example output:
### json-with-metadata
Outputs JSON-serialized results. The `json-with-metadata` provides the same linting results as the [`json`](#json) formatter with additional metadata about the rules applied. The linting results are included in the `results` property and the rules metadata is included in the `metadata` property.
Alternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint.
Example output (formatted for easier reading):
```json
{
"results": [
{
"filePath": "/var/lib/jenkins/workspace/eslint Release/eslint/fullOfProblems.js",
"messages": [
{
"ruleId": "no-unused-vars",
"severity": 2,
"message": "'addOne' is defined but never used.",
"line": 1,
"column": 10,
"messageId": "unusedVar",
"endLine": 1,
"endColumn": 16,
"suggestions": [
{
"messageId": "removeVar",
"data": {
"varName": "addOne"
},
"fix": {
"range": [
0,
94
],
"text": ""
},
"desc": "Remove unused variable 'addOne'."
}
]
},
{
"ruleId": "use-isnan",
"severity": 2,
"message": "Use the isNaN function to compare with NaN.",
"line": 2,
"column": 9,
"messageId": "comparisonWithNaN",
"endLine": 2,
"endColumn": 17,
"suggestions": [
{
"messageId": "replaceWithIsNaN",
"fix": {
"range": [
29,
37
],
"text": "!Number.isNaN(i)"
},
"desc": "Replace with Number.isNaN."
},
{
"messageId": "replaceWithCastingAndIsNaN",
"fix": {
"range": [
29,
37
],
"text": "!Number.isNaN(Number(i))"
},
"desc": "Replace with Number.isNaN and cast to a Number."
}
]
},
{
"ruleId": "space-unary-ops",
"severity": 2,
"message": "Unexpected space before unary operator '++'.",
"line": 3,
"column": 16,
"messageId": "unexpectedBefore",
"endLine": 3,
"endColumn": 20,
"fix": {
"range": [
57,
58
],
"text": ""
}
},
{
"ruleId": "no-useless-assignment",
"severity": 2,
"message": "This assigned value is not used in subsequent statements.",
"line": 3,
"column": 16,
"messageId": "unnecessaryAssignment",
"endLine": 3,
"endColumn": 17
},
{
"ruleId": "semi",
"severity": 1,
"message": "Missing semicolon.",
"line": 3,
"column": 20,
"messageId": "missingSemi",
"endLine": 4,
"endColumn": 1,
"fix": {
"range": [
60,
60
],
"text": ";"
}
},
{
"ruleId": "no-else-return",
"severity": 1,
"message": "Unnecessary 'else' after 'return'.",
"line": 4,
"column": 12,
"messageId": "unexpected",
"endLine": 6,
"endColumn": 6,
"fix": {
"range": [
0,
94
],
"text": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"
}
},
{
"ruleId": "indent",
"severity": 1,
"message": "Expected indentation of 8 spaces but found 6.",
"line": 5,
"column": 1,
"messageId": "wrongIndentation",
"endLine": 5,
"endColumn": 7,
"fix": {
"range": [
74,
80
],
"text": " "
}
},
{
"ruleId": "consistent-return",
"severity": 2,
"message": "Function 'addOne' expected a return value.",
"line": 5,
"column": 7,
"messageId": "missingReturnValue",
"endLine": 5,
"endColumn": 13
},
{
"ruleId": "semi",
"severity": 1,
"message": "Missing semicolon.",
"line": 5,
"column": 13,
"messageId": "missingSemi",
"endLine": 6,
"endColumn": 1,
"fix": {
"range": [
86,
86
],
"text": ";"
}
}
],
"suppressedMessages": [],
"errorCount": 5,
"fatalErrorCount": 0,
"warningCount": 4,
"fixableErrorCount": 1,
"fixableWarningCount": 4,
"source": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};",
"usedDeprecatedRules": [
{
"ruleId": "indent",
"replacedBy": [
"@stylistic/indent"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "indent",
"url": "https://eslint.style/rules/indent"
}
}
]
}
},
{
"ruleId": "semi",
"replacedBy": [
"@stylistic/semi"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "semi",
"url": "https://eslint.style/rules/semi"
}
}
]
}
},
{
"ruleId": "space-unary-ops",
"replacedBy": [
"@stylistic/space-unary-ops"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "space-unary-ops",
"url": "https://eslint.style/rules/space-unary-ops"
}
}
]
}
}
]
}
],
"metadata": {
"cwd": "/var/lib/jenkins/workspace/eslint Release/eslint",
"rulesMeta": {
"no-unused-vars": {
"type": "problem",
"docs": {
"description": "Disallow unused variables",
"recommended": true,
"url": "https://eslint.org/docs/latest/rules/no-unused-vars"
},
"hasSuggestions": true,
"schema": [
{
"oneOf": [
{
"enum": [
"all",
"local"
]
},
{
"type": "object",
"properties": {
"vars": {
"enum": [
"all",
"local"
]
},
"varsIgnorePattern": {
"type": "string"
},
"args": {
"enum": [
"all",
"after-used",
"none"
]
},
"ignoreRestSiblings": {
"type": "boolean"
},
"argsIgnorePattern": {
"type": "string"
},
"caughtErrors": {
"enum": [
"all",
"none"
]
},
"caughtErrorsIgnorePattern": {
"type": "string"
},
"destructuredArrayIgnorePattern": {
"type": "string"
},
"ignoreClassWithStaticInitBlock": {
"type": "boolean"
},
"ignoreUsingDeclarations": {
"type": "boolean"
},
"reportUsedIgnorePattern": {
"type": "boolean"
}
},
"additionalProperties": false
}
]
}
],
"messages": {
"unusedVar": "'{{varName}}' is {{action}} but never used{{additional}}.",
"usedIgnoredVar": "'{{varName}}' is marked as ignored but is used{{additional}}.",
"removeVar": "Remove unused variable '{{varName}}'."
}
},
"use-isnan": {
"hasSuggestions": true,
"type": "problem",
"docs": {
"description": "Require calls to `isNaN()` when checking for `NaN`",
"recommended": true,
"url": "https://eslint.org/docs/latest/rules/use-isnan"
},
"schema": [
{
"type": "object",
"properties": {
"enforceForSwitchCase": {
"type": "boolean"
},
"enforceForIndexOf": {
"type": "boolean"
}
},
"additionalProperties": false
}
],
"defaultOptions": [
{
"enforceForIndexOf": false,
"enforceForSwitchCase": true
}
],
"messages": {
"comparisonWithNaN": "Use the isNaN function to compare with NaN.",
"switchNaN": "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.",
"caseNaN": "'case NaN' can never match. Use Number.isNaN before the switch.",
"indexOfNaN": "Array prototype method '{{ methodName }}' cannot find NaN.",
"replaceWithIsNaN": "Replace with Number.isNaN.",
"replaceWithCastingAndIsNaN": "Replace with Number.isNaN and cast to a Number.",
"replaceWithFindIndex": "Replace with Array.prototype.{{ methodName }}."
}
},
"space-unary-ops": {
"deprecated": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "space-unary-ops",
"url": "https://eslint.style/rules/space-unary-ops"
}
}
]
},
"type": "layout",
"docs": {
"description": "Enforce consistent spacing before or after unary operators",
"recommended": false,
"url": "https://eslint.org/docs/latest/rules/space-unary-ops"
},
"fixable": "whitespace",
"schema": [
{
"type": "object",
"properties": {
"words": {
"type": "boolean",
"default": true
},
"nonwords": {
"type": "boolean",
"default": false
},
"overrides": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
}
},
"additionalProperties": false
}
],
"messages": {
"unexpectedBefore": "Unexpected space before unary operator '{{operator}}'.",
"unexpectedAfter": "Unexpected space after unary operator '{{operator}}'.",
"unexpectedAfterWord": "Unexpected space after unary word operator '{{word}}'.",
"wordOperator": "Unary word operator '{{word}}' must be followed by whitespace.",
"operator": "Unary operator '{{operator}}' must be followed by whitespace.",
"beforeUnaryExpressions": "Space is required before unary expressions '{{token}}'."
}
},
"no-useless-assignment": {
"type": "problem",
"docs": {
"description": "Disallow variable assignments when the value is not used",
"recommended": true,
"url": "https://eslint.org/docs/latest/rules/no-useless-assignment"
},
"schema": [],
"messages": {
"unnecessaryAssignment": "This assigned value is not used in subsequent statements."
}
},
"semi": {
"deprecated": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "semi",
"url": "https://eslint.style/rules/semi"
}
}
]
},
"type": "layout",
"docs": {
"description": "Require or disallow semicolons instead of ASI",
"recommended": false,
"url": "https://eslint.org/docs/latest/rules/semi"
},
"fixable": "code",
"schema": {
"anyOf": [
{
"type": "array",
"items": [
{
"enum": [
"never"
]
},
{
"type": "object",
"properties": {
"beforeStatementContinuationChars": {
"enum": [
"always",
"any",
"never"
]
}
},
"additionalProperties": false
}
],
"minItems": 0,
"maxItems": 2
},
{
"type": "array",
"items": [
{
"enum": [
"always"
]
},
{
"type": "object",
"properties": {
"omitLastInOneLineBlock": {
"type": "boolean"
},
"omitLastInOneLineClassBody": {
"type": "boolean"
}
},
"additionalProperties": false
}
],
"minItems": 0,
"maxItems": 2
}
]
},
"messages": {
"missingSemi": "Missing semicolon.",
"extraSemi": "Extra semicolon."
}
},
"no-else-return": {
"type": "suggestion",
"defaultOptions": [
{
"allowElseIf": true
}
],
"docs": {
"description": "Disallow `else` blocks after `return` statements in `if` statements",
"recommended": false,
"frozen": true,
"url": "https://eslint.org/docs/latest/rules/no-else-return"
},
"schema": [
{
"type": "object",
"properties": {
"allowElseIf": {
"type": "boolean"
}
},
"additionalProperties": false
}
],
"fixable": "code",
"messages": {
"unexpected": "Unnecessary 'else' after 'return'."
}
},
"indent": {
"deprecated": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "indent",
"url": "https://eslint.style/rules/indent"
}
}
]
},
"type": "layout",
"docs": {
"description": "Enforce consistent indentation",
"recommended": false,
"url": "https://eslint.org/docs/latest/rules/indent"
},
"fixable": "whitespace",
"schema": [
{
"oneOf": [
{
"enum": [
"tab"
]
},
{
"type": "integer",
"minimum": 0
}
]
},
{
"type": "object",
"properties": {
"SwitchCase": {
"type": "integer",
"minimum": 0,
"default": 0
},
"VariableDeclarator": {
"oneOf": [
{
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
{
"type": "object",
"properties": {
"var": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"let": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"const": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
}
},
"additionalProperties": false
}
]
},
"outerIIFEBody": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"off"
]
}
]
},
"MemberExpression": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"off"
]
}
]
},
"FunctionDeclaration": {
"type": "object",
"properties": {
"parameters": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"body": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
},
"FunctionExpression": {
"type": "object",
"properties": {
"parameters": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"body": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
},
"StaticBlock": {
"type": "object",
"properties": {
"body": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
},
"CallExpression": {
"type": "object",
"properties": {
"arguments": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
}
},
"additionalProperties": false
},
"ArrayExpression": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"ObjectExpression": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"ImportDeclaration": {
"oneOf": [
{
"type": "integer",
"minimum": 0
},
{
"enum": [
"first",
"off"
]
}
]
},
"flatTernaryExpressions": {
"type": "boolean",
"default": false
},
"offsetTernaryExpressions": {
"type": "boolean",
"default": false
},
"ignoredNodes": {
"type": "array",
"items": {
"type": "string",
"not": {
"pattern": ":exit$"
}
}
},
"ignoreComments": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false
}
],
"messages": {
"wrongIndentation": "Expected indentation of {{expected}} but found {{actual}}."
}
},
"consistent-return": {
"type": "suggestion",
"docs": {
"description": "Require `return` statements to either always or never specify values",
"recommended": false,
"url": "https://eslint.org/docs/latest/rules/consistent-return"
},
"schema": [
{
"type": "object",
"properties": {
"treatUndefinedAsUnspecified": {
"type": "boolean"
}
},
"additionalProperties": false
}
],
"defaultOptions": [
{
"treatUndefinedAsUnspecified": false
}
],
"messages": {
"missingReturn": "Expected to return a value at the end of {{name}}.",
"missingReturnValue": "{{name}} expected a return value.",
"unexpectedReturnValue": "{{name}} expected no return value."
}
}
}
}
}
```
### json
Outputs JSON-serialized results. The `json` formatter is useful when you want to programmatically work with the CLI's linting results.
Alternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint.
Example output (formatted for easier reading):
```json
[
{
"filePath": "/var/lib/jenkins/workspace/eslint Release/eslint/fullOfProblems.js",
"messages": [
{
"ruleId": "no-unused-vars",
"severity": 2,
"message": "'addOne' is defined but never used.",
"line": 1,
"column": 10,
"messageId": "unusedVar",
"endLine": 1,
"endColumn": 16,
"suggestions": [
{
"messageId": "removeVar",
"data": {
"varName": "addOne"
},
"fix": {
"range": [
0,
94
],
"text": ""
},
"desc": "Remove unused variable 'addOne'."
}
]
},
{
"ruleId": "use-isnan",
"severity": 2,
"message": "Use the isNaN function to compare with NaN.",
"line": 2,
"column": 9,
"messageId": "comparisonWithNaN",
"endLine": 2,
"endColumn": 17,
"suggestions": [
{
"messageId": "replaceWithIsNaN",
"fix": {
"range": [
29,
37
],
"text": "!Number.isNaN(i)"
},
"desc": "Replace with Number.isNaN."
},
{
"messageId": "replaceWithCastingAndIsNaN",
"fix": {
"range": [
29,
37
],
"text": "!Number.isNaN(Number(i))"
},
"desc": "Replace with Number.isNaN and cast to a Number."
}
]
},
{
"ruleId": "space-unary-ops",
"severity": 2,
"message": "Unexpected space before unary operator '++'.",
"line": 3,
"column": 16,
"messageId": "unexpectedBefore",
"endLine": 3,
"endColumn": 20,
"fix": {
"range": [
57,
58
],
"text": ""
}
},
{
"ruleId": "no-useless-assignment",
"severity": 2,
"message": "This assigned value is not used in subsequent statements.",
"line": 3,
"column": 16,
"messageId": "unnecessaryAssignment",
"endLine": 3,
"endColumn": 17
},
{
"ruleId": "semi",
"severity": 1,
"message": "Missing semicolon.",
"line": 3,
"column": 20,
"messageId": "missingSemi",
"endLine": 4,
"endColumn": 1,
"fix": {
"range": [
60,
60
],
"text": ";"
}
},
{
"ruleId": "no-else-return",
"severity": 1,
"message": "Unnecessary 'else' after 'return'.",
"line": 4,
"column": 12,
"messageId": "unexpected",
"endLine": 6,
"endColumn": 6,
"fix": {
"range": [
0,
94
],
"text": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"
}
},
{
"ruleId": "indent",
"severity": 1,
"message": "Expected indentation of 8 spaces but found 6.",
"line": 5,
"column": 1,
"messageId": "wrongIndentation",
"endLine": 5,
"endColumn": 7,
"fix": {
"range": [
74,
80
],
"text": " "
}
},
{
"ruleId": "consistent-return",
"severity": 2,
"message": "Function 'addOne' expected a return value.",
"line": 5,
"column": 7,
"messageId": "missingReturnValue",
"endLine": 5,
"endColumn": 13
},
{
"ruleId": "semi",
"severity": 1,
"message": "Missing semicolon.",
"line": 5,
"column": 13,
"messageId": "missingSemi",
"endLine": 6,
"endColumn": 1,
"fix": {
"range": [
86,
86
],
"text": ";"
}
}
],
"suppressedMessages": [],
"errorCount": 5,
"fatalErrorCount": 0,
"warningCount": 4,
"fixableErrorCount": 1,
"fixableWarningCount": 4,
"source": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};",
"usedDeprecatedRules": [
{
"ruleId": "indent",
"replacedBy": [
"@stylistic/indent"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "indent",
"url": "https://eslint.style/rules/indent"
}
}
]
}
},
{
"ruleId": "semi",
"replacedBy": [
"@stylistic/semi"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "semi",
"url": "https://eslint.style/rules/semi"
}
}
]
}
},
{
"ruleId": "space-unary-ops",
"replacedBy": [
"@stylistic/space-unary-ops"
],
"info": {
"message": "Formatting rules are being moved out of ESLint core.",
"url": "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
"deprecatedSince": "8.53.0",
"availableUntil": "11.0.0",
"replacedBy": [
{
"message": "ESLint Stylistic now maintains deprecated stylistic core rules.",
"url": "https://eslint.style/guide/migration",
"plugin": {
"name": "@stylistic/eslint-plugin",
"url": "https://eslint.style"
},
"rule": {
"name": "space-unary-ops",
"url": "https://eslint.style/rules/space-unary-ops"
}
}
]
}
}
]
}
]
```
### stylish
Human-readable output format. This is the default formatter.
Example output:
```text
/var/lib/jenkins/workspace/eslint Release/eslint/fullOfProblems.js
1:10 error 'addOne' is defined but never used no-unused-vars
2:9 error Use the isNaN function to compare with NaN use-isnan
3:16 error Unexpected space before unary operator '++' space-unary-ops
3:16 error This assigned value is not used in subsequent statements no-useless-assignment
3:20 warning Missing semicolon semi
4:12 warning Unnecessary 'else' after 'return' no-else-return
5:1 warning Expected indentation of 8 spaces but found 6 indent
5:7 error Function 'addOne' expected a return value consistent-return
5:13 warning Missing semicolon semi
✖ 9 problems (5 errors, 4 warnings)
1 error and 4 warnings potentially fixable with the `--fix` option.
```
---
---
title: Getting Started with ESLint
eleventyNavigation:
key: getting started
parent: use eslint
title: Getting Started
order: 1
---
{%- from 'components/npm_tabs.macro.html' import npm_tabs with context %}
{%- from 'components/npx_tabs.macro.html' import npx_tabs %}
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.
ESLint is completely pluggable. Every single rule is a plugin and you can add more at runtime. You can also add community plugins, configurations, and parsers to extend the functionality of ESLint.
## Prerequisites
To use ESLint, you must have [Node.js](https://nodejs.org/en/) (`^20.19.0`, `^22.13.0`, or `>=24`) installed and built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
## Quick start
You can install and configure ESLint using this command:
{{ npm_tabs({
command: "init-create",
packages: ["@eslint/config@latest"],
args: []
}) }}
If you want to use a specific shareable config that is hosted on npm, you can use the `--config` option and specify the package name:
{{ npm_tabs({
command: "init-create",
packages: ["@eslint/config@latest", "--", "--config", "eslint-config-xo"],
args: [],
comment: "use `eslint-config-xo` shared config - npm 7+"
}) }}
**Note:** `npm init @eslint/config` assumes you have a `package.json` file already. If you don't, make sure to run `npm init` or `yarn init` beforehand.
After that, you can run ESLint on any file or directory like this:
{{ npx_tabs({
package: "eslint",
args: ["yourfile.js"]
}) }}
## Configuration
**Note:** If you are coming from a version before 9.0.0 please see the [migration guide](configure/migration-guide).
When you run `npm init @eslint/config`, you'll be asked a series of questions to determine how you're using ESLint and what options should be included. After answering these questions, you'll have an `eslint.config.js` (or `eslint.config.mjs`) file created in your directory.
For example, one of the questions is "Where does your code run?" If you select "Browser" then your configuration file will contain the definitions for global variables found in web browsers. Here's an example:
```js
import { defineConfig } from "eslint/config";
import globals from "globals";
import js from "@eslint/js";
export default defineConfig([
{ files: ["**/*.js"], languageOptions: { globals: globals.browser } },
{ files: ["**/*.js"], plugins: { js }, extends: ["js/recommended"] },
]);
```
The `"js/recommended"` configuration ensures all of the rules marked as recommended on the [rules page](../rules) will be turned on. Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config). ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration.
You can configure rules individually by defining a new object with a `rules` key, as in this example:
```js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
export default defineConfig([
{ files: ["**/*.js"], plugins: { js }, extends: ["js/recommended"] },
{
rules: {
"no-unused-vars": "warn",
"no-undef": "warn",
},
},
]);
```
The names `"no-unused-vars"` and `"no-undef"` are the names of [rules](../rules) in ESLint. The first value is the error level of the rule and can be one of these values:
- `"off"` or `0` - turn the rule off
- `"warn"` or `1` - turn the rule on as a warning (doesn’t affect exit code)
- `"error"` or `2` - turn the rule on as an error (exit code will be 1)
The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the configuration docs).
## Global Install
It is also possible to install ESLint globally, rather than locally, using `npm install eslint --global`. However, this is not recommended, and any plugins or shareable configs that you use must still be installed locally even if you install ESLint globally.
## Manual Set Up
You can also manually set up ESLint in your project.
::: important
If you are using [pnpm](https://pnpm.io), be sure to create a `.npmrc` file with at least the following settings:
```text
auto-install-peers=true
node-linker=hoisted
```
This ensures that pnpm installs dependencies in a way that is more compatible with npm and is less likely to produce errors.
:::
Before you begin, you must already have a `package.json` file. If you don't, make sure to run `npm init` or `yarn init` to create the file beforehand.
1. Install the ESLint packages in your project:
{{ npm_tabs({
command: "install",
packages: ["eslint@latest", "@eslint/js@latest"],
args: ["--save-dev"]
}) }}
2. Add an `eslint.config.js` file:
```shell
# Create JavaScript configuration file
touch eslint.config.js
```
3. Add configuration to the `eslint.config.js` file. Refer to the [Configure ESLint documentation](configure/) to learn how to add rules, custom configurations, plugins, and more.
```js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";
export default defineConfig([
{
files: ["**/*.js"],
plugins: {
js,
},
extends: ["js/recommended"],
rules: {
"no-unused-vars": "warn",
"no-undef": "warn",
},
},
]);
```
4. Lint code using the ESLint CLI:
{{ npx_tabs({
package: "eslint",
args: ["project-dir/", "file.js"]
}) }}
For more information on the available CLI options, refer to [Command Line Interface](./command-line-interface).
---
## Next Steps
- Learn about [advanced configuration](configure/) of ESLint.
- Get familiar with the [command line options](command-line-interface).
- Explore [ESLint integrations](integrations) into other tools like editors, build systems, and more.
- Can't find just the right rule? Make your own [custom rule](../extend/custom-rules).
- Make ESLint even better by [contributing](../contribute/).
---
---
title: Use ESLint in Your Project
eleventyNavigation:
key: use eslint
title: Use ESLint in Your Project
order: 1
---
This guide is intended for those who wish to use ESLint as an end-user. If you're looking for how to extend ESLint or work with the ESLint source code, please see the [Extend ESLint documentation](../extend/).
## [Getting Started](getting-started)
Want to skip ahead and just start using ESLint? This section gives a high-level overview of installation, setup, and configuration options.
## [Core Concepts](core-concepts)
Understand the main components of ESLint and how to use them in your project.
## [Configure ESLint](configure/)
Once you've got ESLint running, you'll probably want to adjust the configuration to better suit your project. This section explains all the different ways you can configure ESLint.
## [Command Line Interface Reference](command-line-interface)
There are a lot of command line flags for ESLint and this section explains what they do.
## [Rules Reference](../rules/)
ESLint has a lot of rules that you can configure to fine-tune it to your project. This section is an exhaustive list of every rule and link to each rule's documentation.
## [Formatters Reference](formatters)
Control the appearance of the linting results with formatters. View all built-in formatters on this page.
## [Integrations](integrations)
Wondering if ESLint will work with your favorite editor or build system? This page has a list of integrations (submitted by their authors).
## [Rule Deprecation](rule-deprecation)
The ESLint team is committed to making upgrading as easy and painless as possible. This section outlines the guidelines the team has set in place for the deprecation of rules in future releases.
## Migrating
If you were using a prior version of ESLint, you can get help with the transition by reading:
- [migrating-to-1.0.0](migrating-to-1.0.0)
- [migrating-to-2.0.0](migrating-to-2.0.0)
- [migrating-to-3.0.0](migrating-to-3.0.0)
- [migrating-to-4.0.0](migrating-to-4.0.0)
- [migrating-to-5.0.0](migrating-to-5.0.0)
- [migrating-to-6.0.0](migrating-to-6.0.0)
- [migrating-to-7.0.0](migrating-to-7.0.0)
- [migrate-to-8.0.0](migrate-to-8.0.0)
- [migrate-to-9.x](migrate-to-9.0.0)
---
---
title: Integrations
eleventyNavigation:
key: integrations
parent: use eslint
title: Integrations
order: 9
---
This page contains community projects that have integrated ESLint. The projects on this page are not maintained by the ESLint team.
If you would like to recommend an integration to be added to this page, [submit a pull request](../contribute/pull-requests).
## Editors
- Sublime Text 3:
- [SublimeLinter-eslint](https://github.com/SublimeLinter/SublimeLinter-eslint)
- [Build Next](https://github.com/albertosantini/sublimetext-buildnext)
- Vim:
- [ALE](https://github.com/dense-analysis/ale)
- [Syntastic](https://github.com/vim-syntastic/syntastic/tree/master/syntax_checkers/javascript)
- Neovim:
- [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#eslint)
- [nvim-lint](https://github.com/mfussenegger/nvim-lint)
- Emacs: [Flycheck](http://www.flycheck.org/) supports ESLint with the [javascript-eslint](http://www.flycheck.org/en/latest/languages.html#javascript) checker.
- Eclipse Orion: ESLint is the [default linter](https://dev.eclipse.org/mhonarc/lists/orion-dev/msg02718.html)
- Eclipse IDE: [Tern ESLint linter](https://github.com/angelozerr/tern.java/wiki/Tern-Linter-ESLint)
- TextMate 2:
- [eslint.tmbundle](https://github.com/ryanfitzer/eslint.tmbundle)
- [javascript-eslint.tmbundle](https://github.com/natesilva/javascript-eslint.tmbundle)
- IntelliJ IDEA, WebStorm, PhpStorm, PyCharm, RubyMine, and other JetBrains IDEs: [How to use ESLint](https://www.jetbrains.com/help/webstorm/eslint.html)
- Visual Studio: [Linting JavaScript in VS](https://learn.microsoft.com/en-us/visualstudio/javascript/linting-javascript?view=vs-2022)
- Visual Studio Code: [ESLint Extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- Brackets: Included and [Brackets ESLint](https://github.com/brackets-userland/brackets-eslint)
## Build tools
- Grunt: [grunt-eslint](https://www.npmjs.com/package/grunt-eslint)
- Webpack: [eslint-webpack-plugin](https://www.npmjs.com/package/eslint-webpack-plugin)
- Rollup: [@rollup/plugin-eslint](https://www.npmjs.com/package/@rollup/plugin-eslint)
## Command Line Tools
- [ESLint Watch](https://www.npmjs.com/package/eslint-watch)
- [Code Climate CLI](https://github.com/codeclimate/codeclimate)
- [ESLint Nibble](https://github.com/IanVS/eslint-nibble)
## Source Control
- [Git Precommit Hook](https://coderwall.com/p/zq8jlq/eslint-pre-commit-hook)
- [Git pre-commit hook that only lints staged changes](https://gist.github.com/dahjelle/8ddedf0aebd488208a9a7c829f19b9e8)
- [overcommit Git hook manager](https://github.com/brigade/overcommit)
- [Mega-Linter](https://megalinter.io/latest/): Linters aggregator for CI, [embedding eslint](https://megalinter.io/latest/descriptors/javascript_eslint/)
## Other Integration Lists
You can find a curated list of other popular integrations for ESLint in the [awesome-eslint](https://github.com/dustinspecker/awesome-eslint) GitHub repository.
---
---
title: MCP Server Setup
eleventyNavigation:
key: mcp server
parent: use eslint
title: MCP Server Setup
order: 5
---
[Model Context Protocol](https://modelcontextprotocol.io) (MCP) is an open standard that enables AI models to interact with external tools and services through a unified interface. The ESLint CLI contains an MCP server that you can register with your code editor to allow LLMs to use ESLint directly.
## Set Up ESLint MCP Server in VS Code
To use MCP servers in VS Code, you must have the [Copilot Chat](https://code.visualstudio.com/docs/copilot/copilot-chat) extension installed. After that, follow these steps so add the ESLint MCP server:
### 1. Create MCP Configuration File
Create a `.vscode/mcp.json` file in your project with the following configuration:
```json
{
"servers": {
"ESLint": {
"type": "stdio",
"command": "npx",
"args": ["@eslint/mcp@latest"]
}
}
}
```
Alternatively, you can use the Command Palette:
1. Press `Ctrl+Shift+P` (Windows/Linux) or `Cmd+Shift+P` (macOS)
2. Type and select `MCP: Add Server`
3. Select `Command (stdio)` from the dropdown
4. Enter `npx @eslint/mcp@latest` as the command
5. Type `ESLint` as the server ID
6. Choose `Workspace Settings` to create the configuration in `.vscode/mcp.json`
### 2. Enable MCP Server in User Settings (Optional)
If you want to use the ESLint MCP server across all workspaces, you can follow the previous steps and choose `User Settings` instead of `Workspace Settings` to add the MCP server to your `settings.json` file.
### Using the ESLint MCP Server with GitHub Copilot
Once your MCP server is configured, you can use it with [GitHub Copilot's agent mode](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode):
1. Open the Copilot Chat view in VS Code
2. Ensure agent mode is enabled (look for the agent icon in the chat input)
3. Toggle on the ESLint MCP server tools using the "Tools" button in the chat view
4. Ask Copilot to perform ESLint tasks, such as:
- "Check this file for linting errors"
- "Fix all ESLint issues in the current file"
- "Show me what ESLint rules are being violated"
## Troubleshooting
If you encounter issues with the ESLint MCP server:
1. Check the MCP server status by running `MCP: List Servers` from the Command Palette
2. Select the ESLint server and choose `Show Output` to view server logs
3. Ensure that ESLint is installed in your project or globally
4. Verify that your MCP configuration is correct
## Set Up ESLint MCP Server in Cursor
To configure the ESLint MCP server in [Cursor](https://cursor.com), follow these steps:
### 1. Create MCP Configuration File
Create a `.cursor/mcp.json` file in your project directory with the following configuration:
```json
{
"mcpServers": {
"eslint": {
"command": "npx",
"args": ["@eslint/mcp@latest"],
"env": {}
}
}
}
```
### 2. Global Configuration (Optional)
If you want to use the ESLint MCP server across all your Cursor workspaces, create a `~/.cursor/mcp.json` file in your home directory with the same configuration.
### 3. Verify Tool Availability
Once configured, the ESLint MCP server should appear in the "Available Tools" section on the MCP settings page in Cursor.
## Set Up ESLint MCP Server in Windsurf
To configure the ESLint MCP server in [Windsurf](https://docs.windsurf.com/), follow these steps:
### 1. Access Windsurf Settings
Navigate to Windsurf - Settings > Advanced Settings, or open the Command Palette and select "Open Windsurf Settings Page".
### 2. Add ESLint MCP Server
Scroll down to the Cascade section and click the "Add Server" button. Then select "Add custom server +".
### 3. Configure MCP Server
Add the following configuration to your `~/.codeium/windsurf/mcp_config.json` file:
```json
{
"mcpServers": {
"eslint": {
"command": "npx",
"args": ["@eslint/mcp@latest"],
"env": {}
}
}
}
```
### 4. Refresh Server List
After adding the configuration, press the refresh button to update the list of available MCP servers.
### 5. Using ESLint with Cascade
Once configured, you can use ESLint tools with Cascade by asking it to:
- Check files for linting errors
- Explain ESLint rule violations
Note: MCP tool calls in Windsurf will consume credits regardless of success or failure.
## Example Prompts
Here are some example prompts to an LLM for running ESLint and addressing its findings:
```text
Lint the current file and explain any issues found
Lint and fix #file:index.js
```
## Additional Resources
- [Model Context Protocol Documentation](https://modelcontextprotocol.io/introduction)
- [VS Code MCP Servers Documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers)
- [GitHub Copilot in VS Code Documentation](https://code.visualstudio.com/docs/copilot/copilot-chat)
- [Model Context Protocol in Cursor documentation](https://docs.cursor.com/context/model-context-protocol)
- [Model Context Protocol in Windsurf documentation](https://docs.windsurf.com/)
---
---
title: Migrate to v10.x
eleventyNavigation:
key: migrate to v10
parent: use eslint
title: Migrate to v10.x
order: 9
---
ESLint v10.0.0 is a major release of ESLint, and as such, has several breaking changes that you need to be aware of. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Table of Contents
### Breaking changes for users
- [Node.js < v20.19, v21, v23 are no longer supported](#drop-old-node)
- [`eslint:recommended` has been updated](#eslint-recommended)
- [New configuration file lookup algorithm](#config-lookup-from-file)
- [Old config format no longer supported](#remove-eslintrc)
- [JSX references are now tracked](#jsx-reference-tracking)
- [`eslint-env` comments are reported as errors](#eslint-env-comments)
- [Jiti < v2.2.0 are no longer supported](#drop-old-jiti)
- [POSIX character classes in glob patterns](#posix-character-classes)
- [`stylish` formatter now uses native `styleText` instead of `chalk`](#stylish-formatter)
- [Deprecated options of the `radix` rule](#radix)
- [`no-shadow-restricted-names` now reports `globalThis` by default](#no-shadow-restricted-names)
- [`func-names` schema is stricter](#func-names)
- [`allowConstructorFlags` option of `no-invalid-regexp` now accepts only unique items](#no-invalid-regexp)
- [`name` property added to ESLint core configs](#eslint-config-name)
### Breaking changes for plugin developers
- [Node.js < v20.19, v21, v23 are no longer supported](#drop-old-node)
- [Old config format no longer supported](#remove-eslintrc)
- [JSX references are now tracked](#jsx-reference-tracking)
- [Removal of `type` property in errors of invalid `RuleTester` cases](#ruletester-type-removed)
- [`Program` AST node range spans entire source text](#program-node-range)
- [Fixer methods now require string `text` arguments](#fixer-text-must-be-string)
- [New requirements for `ScopeManager` implementations](#scope-manager)
- [Removal of deprecated `context` members](#rule-context)
- [Removal of deprecated `SourceCode` methods](#sourcecode-methods-removed)
- [Prohibiting `errors` or `output` of valid RuleTester test cases](#stricter-rule-tester)
- [POSIX character classes in glob patterns](#posix-character-classes)
### Breaking changes for integration developers
- [Node.js < v20.19, v21, v23 are no longer supported](#drop-old-node)
- [New configuration file lookup algorithm](#config-lookup-from-file)
- [Old config format no longer supported](#remove-eslintrc)
- [Removal of `nodeType` property in `LintMessage` objects](#lintmessage-nodetype-removed)
- [POSIX character classes in glob patterns](#posix-character-classes)
---
## Node.js < v20.19, v21, v23 are no longer supported
ESLint is officially dropping support for these versions of Node.js starting with ESLint v10.0.0. ESLint now supports the following versions of Node.js:
- Node.js v20.19.0 and above
- Node.js v22.13.0 and above
- Node.js v24 and above
**To address:** Make sure you upgrade to at least Node.js v20.19.0 when using ESLint v10.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint v9 until you are able to upgrade Node.js.
**Related issue(s):** [#19969](https://github.com/eslint/eslint/issues/19969)
## `eslint:recommended` has been updated
Three new rules have been enabled in `eslint:recommended`:
- [`no-unassigned-vars`](../rules/no-unassigned-vars)
- [`no-useless-assignment`](../rules/no-useless-assignment)
- [`preserve-caught-error`](../rules/preserve-caught-error)
**To address:** Fix errors or disable these rules.
**Related issue(s):** [#19966](https://github.com/eslint/eslint/issues/19966)
## New configuration file lookup algorithm
In ESLint v9, the alternate config lookup behavior could be enabled with the `v10_config_lookup_from_file` feature flag. This behavior made ESLint locate `eslint.config.*` by starting from the directory of each linted file and searching up towards the filesystem root. In ESLint v10.0.0, this behavior is now the default and the `v10_config_lookup_from_file` flag has been removed. Attempting to use this flag will now result in an error.
**To address:**
- Remove any usage of the flag in your setup:
- CLI: remove `--flag v10_config_lookup_from_file`.
- Environment: remove `v10_config_lookup_from_file` from `ESLINT_FLAGS`.
- API: remove `"v10_config_lookup_from_file"` from the `flags` array passed to `new ESLint()` or `new Linter()`.
- If you relied on the previous (cwd-based) lookup behavior, provide an explicit config path with `--config path/to/eslint.config.js`.
**Related issue(s):** [RFC120](https://github.com/eslint/rfcs/tree/main/designs/2024-config-lookup-from-file), [#19967](https://github.com/eslint/eslint/issues/19967)
## Old config format no longer supported
ESLint v9 introduced a [new default configuration format](./configure/configuration-files) based on the `eslint.config.js` file. The [old format](./configure/configuration-files-deprecated), which used `.eslintrc` or `.eslintrc.json`, could still be enabled in v9 by setting the `ESLINT_USE_FLAT_CONFIG` environment variable to `false`.
Starting with ESLint v10.0.0, the old configuration format is no longer supported.
**To address:**
- Follow the instructions in the [configuration migration guide](./configure/migration-guide).
- Be aware that the deprecated APIs `FlatESLint` and `LegacyESLint` have been removed. Always use `ESLint` instead.
- The `configType` option of the `Linter` class can no longer be set to `"eslintrc"`. Remove the option to use the new configuration format.
**Related issue(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
## JSX references are now tracked
ESLint v10.0.0 now tracks JSX references, enabling correct scope analysis of JSX elements.
Previously, ESLint did not track references created by JSX identifiers, which could lead to incorrect results from rules that rely on scope information. For example:
```jsx
import { Card } from "./card.jsx";
export function createCard(name) {
return ;
}
```
Prior to v10.0.0, ESLint did not recognize that `` is a reference to the imported `Card`, which could result in false positives such as reporting `Card` as "defined but never used" ([`no-unused-vars`](../rules/no-unused-vars)) or false negatives such as failing to report `Card` as undefined ([`no-undef`](../rules/no-undef)) if the import is removed. Starting with v10.0.0, `` is treated as a normal reference to the variable in scope. This brings JSX handling in line with developer expectations and improves the linting experience for modern JavaScript applications using JSX.
**To address:**
- For users:
- New linting reports may appear in files with JSX. Update your code accordingly or adjust rule configurations if needed.
- Rules previously used to work around ESLint’s lack of JSX reference tracking (for example, [`@eslint-react/jsx-uses-vars`](https://www.eslint-react.xyz/docs/rules/jsx-uses-vars)) are no longer needed. Remove or disable them in your configuration.
- For plugin developers: Custom rules relying on scope analysis may now encounter `JSXIdentifier` references. Update rules to handle these correctly.
**Related issue(s):** [#19495](https://github.com/eslint/eslint/issues/19495)
## `eslint-env` comments are reported as errors
In the now obsolete ESLint v8 configuration system, `/* eslint-env */` comments could be used to define globals for a file. The current configuration system does not support such comments, and starting with ESLint v10.0.0, they are reported as errors during linting.
```text
error: /* eslint-env */ comments are no longer supported at file.js:1:1:
> 1 | /* eslint-env node -- Used in Node.js */
| ^
```
**To address:** Remove any `eslint-env` comments from your code. If you are still using the old configuration system and need help migrating, check the [migration guide](./configure/migration-guide#eslint-env-configuration-comments).
**Related issue(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
## Jiti < v2.2.0 are no longer supported
ESLint is officially dropping support for versions of `jiti` that are less than v2.2.0.
**To address:** If you've authored your config file in `TypeScript` and have `jiti` v2.1.2 or earlier installed, be sure to update it to at least `2.2.0` when using ESLint v10.0.0.
**Related issue(s):** [#19765](https://github.com/eslint/eslint/issues/19765)
## POSIX character classes in glob patterns
ESLint v10.0.0 uses the latest version of [minimatch](https://github.com/isaacs/minimatch), which supports [POSIX character classes](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) in bracket expressions. ESLint relies on minimatch to match file names against glob patterns, such as those defined in `files`, `ignores`, and `globalIgnores()` within a config, or passed via the CLI.
For example, to lint all `.js` files whose names begin with an uppercase letter, you can now run:
```shell
npx eslint "**/[[:upper:]]*.js"
```
Here, `[[:upper:]]` is a POSIX character class that matches uppercase letters in different alphabets.
**To address:** If any of the glob patterns in your configuration, CLI arguments, or Node.js API calls look like containing a POSIX character class, verify that they match files as intended.
**Related issue(s):** [eslint/rewrite#66](https://github.com/eslint/rewrite/issues/66)
## `stylish` formatter now uses native `styleText` instead of `chalk`
Starting in ESLint v10.0.0, the built-in [`stylish`](./formatters#stylish) formatter no longer depends on the third-party [`chalk`](https://github.com/chalk/chalk) library for colorized output. Instead, it now uses Node.js's native [`styleText`](https://nodejs.org/api/util.html#utilstyletextformat-text-options) API, which introduces two breaking changes regarding how colorized output is determined:
1. First, `styleText` checks more environment variables when determining whether to disable colorized output and follows Node.js's own rules for when to enable or disable colors. This means it respects a wider set of environment variables and terminal capabilities than ESLint's previous `chalk`-based logic. For example:
- [`NO_COLOR`](https://nodejs.org/api/cli.html#no_colorany) now disables colors consistently across tools that honor this convention.
- [`NODE_DISABLE_COLORS`](https://nodejs.org/api/cli.html#node_disable_colors1) is also respected, aligning ESLint's behavior with Node.js itself.
Please note that the [`FORCE_COLOR`](https://nodejs.org/api/cli.html#force_color1-2-3) environment variable is still supported to force-enable colors.
2. Second, `--color` and `--no-color` CLI flags now have higher precedence than environment variables when determining whether to use colorized output. This change ensures that explicit user preferences via CLI flags are prioritized. However, if neither flag is provided, environment variables will be considered as before.
**To address:**
- Review any environment configuration related to terminal colors (for example, CI defaults or shell profiles). If ESLint's output appears uncolored after upgrading to v10.0.0, check whether `NO_COLOR` or `NODE_DISABLE_COLORS` (or similar settings) are being set in your environment.
- If you rely on mixed approaches (for example, using `--color` flag but also setting `NO_COLOR` environment variable), be aware that the CLI flags now take precedence and adjust your setup accordingly.
**Related issue(s):** [#20012](https://github.com/eslint/eslint/issues/20012)
## Deprecated options of the `radix` rule
As of ESLint v10.0.0, string options `"always"` and `"as-needed"` of the [`radix`](../rules/radix) rule are deprecated. Setting either of these options doesn't change the behavior of this rule, which now always enforces providing a radix, as it was the case when the `"always"` option (default) was specified. Since the default radix depends on the first argument of `parseInt()`, this rule assumes that the second argument (the radix) is always needed.
The default behavior of this rule has not been changed.
**To address:**
- If you are using this rule without any options specified, there is no action required.
- If you are using this rule with the `"always"` option explicitly specified, remove the option. The behavior of this rule will remain the same.
- If you are using this rule with the `"as-needed"` option, remove the option and update your code to always provide the second argument to the `parseInt()` function. Alternatively, you can disable this rule.
**Related issue(s):** [#19916](https://github.com/eslint/eslint/issues/19916)
## `no-shadow-restricted-names` now reports `globalThis` by default
In ESLint v10.0.0, the [`no-shadow-restricted-names`](../rules/no-shadow-restricted-names) rule now treats `globalThis` as a restricted name by default. Consequently, the `reportGlobalThis` option now defaults to `true` (previously `false`). As a result, declarations such as `const globalThis = "foo";` or `function globalThis() {}` will now be reported by default.
**To address:**
- Rename local identifiers named `globalThis` to avoid shadowing the global.
- Or restore the previous behavior by configuring the rule explicitly:
```json
{
"rules": {
"no-shadow-restricted-names": ["error", { "reportGlobalThis": false }]
}
}
```
**Related issue(s):** [#19673](https://github.com/eslint/eslint/issues/19673)
## `func-names` schema is stricter
In ESLint v10.0.0, the [`func-names`](../rules/func-names) rule schema now disallows extra items in the options array. Previously, configurations that included additional array elements beyond the allowed options were accepted but ignored. Such configurations are now considered invalid.
For example, this configuration is now invalid due to the extra element `"foo"`:
```js
/*eslint func-names: ["error", "always", { "generators": "never" }, "foo"]*/
```
**To address:**
- Remove any extra array elements from your `func-names` configuration so that it contains only:
- a base string option: `"always" | "as-needed" | "never"`, and
- optionally, an object option: `{ "generators": "always" | "as-needed" | "never" }`.
**Related issue(s):** [#20134](https://github.com/eslint/eslint/issues/20134)
## `allowConstructorFlags` option of `no-invalid-regexp` now accepts only unique items
In ESLint v10.0.0, the `allowConstructorFlags` option of `no-invalid-regexp` no longer accepts duplicate flags as input. Previously, configurations with duplicate flags in the array were accepted but treated the same as having unique flags. Such configurations are now considered invalid and will result in a configuration error.
For example, this configuration is now invalid due to the duplicate `"u"` flag:
```js
/*eslint no-invalid-regexp: ["error", { "allowConstructorFlags": ["u", "y", "u"] }]*/
```
**To address:** Remove any duplicate flags from your `allowConstructorFlags` array configuration of `no-invalid-regexp` rule. Each flag should appear only once in the array.
**Related issue(s):** [#18755](https://github.com/eslint/eslint/issues/18755)
## `name` property added to ESLint core configs
In ESLint v10.0.0, the `name` property has been restored to the ESLint core configs exported from `@eslint/js`. This property was previously removed due to incompatibility with the legacy eslintrc configuration system. Now that eslintrc is no longer supported, the `name` property has been added back.
This change should not require any action for most users. However, if you are using `@eslint/js` v10.x with the `FlatCompat` utility from `@eslint/eslintrc`, you should upgrade `@eslint/eslintrc` to the latest version to ensure compatibility.
**To address:** Upgrade `@eslint/eslintrc` to the latest version if you are using `FlatCompat`.
**Related issue(s):** [#19864](https://github.com/eslint/eslint/issues/19864)
## Removal of `type` property in errors of invalid `RuleTester` cases
In ESLint v10.0.0, the deprecated `type` property in errors of invalid test cases for rules has been removed. Using the `type` property in test cases now throws an error.
**To address:** Remove the `type` property from error objects in invalid test cases.
**Related issue(s):** [#19029](https://github.com/eslint/eslint/issues/19029)
## `Program` AST node range spans entire source text
ESLint v10.0.0 changes how the `Program` AST node’s range is calculated: it now spans the entire source text, including any leading and trailing comments and whitespace.
Previously, the `Program` node’s range excluded leading and trailing comments/whitespace, which could be unintuitive. For example:
```js
// Leading comment
const x = 1;
// Trailing comment
```
In ESLint v9 and earlier, `Program.range` covers only `const x = 1;` (excludes surrounding comments/whitespace).
Starting with ESLint v10.0.0, `Program.range` covers the entire source text, including the leading and trailing comments/whitespace.
**To address:**
- For rule and plugin authors: If your code depends on the previous `Program.range` behavior, or on `SourceCode` methods that assume it (such as `sourceCode.getCommentsBefore(programNode)` to retrieve all leading comments), update your logic.
- For custom parsers: Set `Program.range` to cover the full source text (typically `[0, code.length]`).
**Related issue(s):** [eslint/js#648](https://github.com/eslint/js/issues/648)
## Fixer methods now require string `text` arguments
In ESLint v10.0.0, all rule fixer methods that accept a `text` argument now require that it be a string. Providing a non-string value will throw a `TypeError`.
Affected methods:
- `insertTextBefore(nodeOrToken, text)`
- `insertTextBeforeRange(range, text)`
- `insertTextAfter(nodeOrToken, text)`
- `insertTextAfterRange(range, text)`
- `replaceText(nodeOrToken, text)`
- `replaceTextRange(range, text)`
**To address:** Ensure the `text` value you pass to fixer methods is a string.
**Related issue(s):** [#18807](https://github.com/eslint/eslint/issues/18807)
## New requirements for `ScopeManager` implementations
In ESLint v10.0.0, custom `ScopeManager` implementations must automatically resolve references to global variables declared in the code, including `var` and `function` declarations, and provide an instance method `addGlobals(names: string[])` that creates variables with the given names in the global scope and resolves references to them.
The default `ScopeManager` implementation [`eslint-scope`](https://www.npmjs.com/package/eslint-scope) has already been updated.
This change does not affect custom rules.
**To address:** If you maintain a custom parser that provides a custom `ScopeManager` implementation, update your custom `ScopeManager` implementation.
**Related issue(s):** [eslint/js#665](https://github.com/eslint/js/issues/665)
## Removal of deprecated `context` members
In ESLint v9.x, we deprecated the following [methods](https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context-methods-becoming-properties) and [properties](https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context-properties%3A-parseroptions-and-parserpath-being-removed):
- `context.getCwd()`
- `context.getFilename()`
- `context.getPhysicalFilename()`
- `context.getSourceCode()`
- `context.parserOptions`
- `context.parserPath`
In ESLint v10.0.0, all of these members have been removed.
**To address:** In your custom rules, make the following changes:
| **Removed on `context`** | **Replacement on `context`** |
| ------------------------------- | -------------------------------------------------------------------- |
| `context.getCwd()` | `context.cwd` |
| `context.getFilename()` | `context.filename` |
| `context.getPhysicalFilename()` | `context.physicalFilename` |
| `context.getSourceCode()` | `context.sourceCode` |
| `context.parserOptions` | `context.languageOptions` or `context.languageOptions.parserOptions` |
| `context.parserPath` | No replacement. |
You can make changes for the removed `context` methods using the [`eslint-transforms`](https://www.npmjs.com/package/eslint-transforms) utility. To use the utility, first install it and then run the `v9-rule-migration` transform, like this:
```shell
# install the utility
npm install eslint-transforms -g
# apply the transform to one file
eslint-transforms v9-rule-migration rule.js
# apply the transform to all files in a directory
eslint-transforms v9-rule-migration rules/
```
The removed `context` properties must be done manually as there may not be a direct one-to-one replacement.
**Related issue(s):** [eslint/eslint#16999](https://github.com/eslint/eslint/issues/16999)
## Removal of deprecated `SourceCode` methods
The following deprecated `SourceCode` methods have been removed in ESLint v10.0.0:
- `getTokenOrCommentBefore()`
- `getTokenOrCommentAfter()`
- `isSpaceBetweenTokens()`
- `getJSDocComment()`
These methods have been deprecated for multiple major versions and were primarily used by deprecated formatting rules and internal ESLint utilities. Custom rules using these methods must be updated to use their modern replacements.
**To address:** In your custom rules, make the following changes:
| **Removed on `SourceCode`** | **Replacement** |
| -------------------------------------------- | -------------------------------------------------------------- |
| `getTokenOrCommentBefore(nodeOrToken, skip)` | `getTokenBefore(nodeOrToken, { includeComments: true, skip })` |
| `getTokenOrCommentAfter(nodeOrToken, skip)` | `getTokenAfter(nodeOrToken, { includeComments: true, skip })` |
| `isSpaceBetweenTokens(first, second)` | `isSpaceBetween(first, second)` |
| `getJSDocComment(node)` | No replacement |
Compatibility patches are available in the [`@eslint/compat`](https://www.npmjs.com/package/@eslint/compat) package to help with the transition.
**Related issue(s):** [#20113](https://github.com/eslint/eslint/issues/20113)
## Prohibiting `errors` or `output` of valid RuleTester test cases
In ESLint v10.0.0, the RuleTester has become more strict about test case structure. Valid test cases (those that should not produce any linting errors) are no longer allowed to have `errors` or `output` properties.
What changed:
- Previously, valid test cases could include `errors` or `output` properties, which were ignored.
- Now, including these properties in valid test cases will cause the test to fail.
Example of invalid usage:
```js
// This will now throw an error in ESLint v10.0.0
const validTestCases = [
{
code: "const foo = 'bar';",
errors: 0, // ❌ Not allowed in valid test cases
output: "const foo = 'bar';", // ❌ Not allowed in valid test cases
},
];
ruleTester.run("rule-id", rule, { valid: validTestCases, invalid: [] });
```
**To address:** Remove any `errors`/`output` properties from valid test cases.
**Related issue(s):** [#18960](https://github.com/eslint/eslint/issues/18960)
## Removal of `nodeType` property in `LintMessage` objects
In ESLint v10.0.0, the deprecated `nodeType` property on `LintMessage` objects has been removed. This affects consumers of the Node.js API (for example, custom formatters and editor/tool integrations) that previously relied on `message.nodeType`.
**To address:** Remove all usages of `message.nodeType` in your integrations and formatters.
**Related issue(s):** [#19029](https://github.com/eslint/eslint/issues/19029)
---
---
title: Migrate to v8.0.0
---
ESLint v8.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Table of Contents
### Breaking changes for users
- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node)
- [Removed `codeframe` and `table` formatters](#removed-formatters)
- [`comma-dangle` rule schema is stricter](#comma-dangle)
- [Unused disable directives are now fixable](#directives)
- [`eslint:recommended` has been updated](#eslint-recommended)
### Breaking changes for plugin developers
- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node)
- [Rules require `meta.hasSuggestions` to provide suggestions](#suggestions)
- [Rules require `meta.fixable` to provide fixes](#fixes)
- [`SourceCode#getComments()` fails in `RuleTester`](#get-comments)
- [Changes to shorthand property AST format](#ast-format)
### Breaking changes for integration developers
- [Node.js 10, 13, and 15 are no longer supported](#drop-old-node)
- [The `CLIEngine` class has been removed](#remove-cliengine)
- [The `linter` object has been removed](#remove-linter)
- [The `/lib` entrypoint has been removed](#remove-lib)
---
## Node.js 10, 13, and 15 are no longer supported
Node.js 10, 13, 15 all reached end of life either in 2020 or early 2021. ESLint is officially dropping support for these versions of Node.js starting with ESLint v8.0.0. ESLint now supports the following versions of Node.js:
- Node.js 12.22 and above
- Node.js 14 and above
- Node.js 16 and above
**To address:** Make sure you upgrade to at least Node.js `12.22.0` when using ESLint v8.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint 7 until you are able to upgrade Node.js.
**Related issue(s):** [#14023](https://github.com/eslint/eslint/issues/14023)
## Removed `codeframe` and `table` formatters
ESLint v8.0.0 has removed the `codeframe` and `table` formatters from the core. These formatters required dependencies that weren't used anywhere else in ESLint, and removing them allows us to reduce the size of ESLint, allowing for faster installation.
**To address:** If you are using the `codeframe` or `table` formatters, you'll need to install the standalone [`eslint-formatter-codeframe`](https://github.com/eslint-community/eslint-formatter-codeframe) or [`eslint-formatter-table`](https://github.com/eslint-community/eslint-formatter-table) packages, respectively, to be able to use them in ESLint v8.0.0.
**Related issue(s):** [#14277](https://github.com/eslint/eslint/issues/14277), [#14316](https://github.com/eslint/eslint/pull/14316)
## `comma-dangle` rule schema is stricter
In ESLint v7.0.0, the `comma-dangle` rule could be configured like this without error:
```json
{
"rules": {
"comma-dangle": ["error", "never", { "arrays": "always" }]
}
}
```
With this configuration, the rule would ignore the third element in the array because only the second element is read. In ESLint v8.0.0, this configuration will cause ESLint to throw an error.
**To address:** Change your rule configuration so that there are only two elements in the array, and the second element is either a string or an object, such as:
```json
{
"comma-dangle": ["error", "never"]
}
```
or
```json
{
"comma-dangle": [
"error",
{
"arrays": "never",
"objects": "never",
"imports": "never",
"exports": "never",
"functions": "never"
}
]
}
```
**Related issue(s):** [#13739](https://github.com/eslint/eslint/issues/13739)
## Unused disable directives are now fixable
In ESLint v7.0.0, using both `--report-unused-disable-directives` and `--fix` on the command line would fix only rules but leave unused disable directives in place. In ESLint v8.0.0, this combination of command-line options will result in the unused disable directives being removed.
**To address:** If you are using `--report-unused-disable-directives` and `--fix` together on the command line, and you don't want unused disable directives to be removed, add `--fix-type problem,suggestion,layout` as a command line option.
**Related issue(s):** [#11815](https://github.com/eslint/eslint/issues/11815)
## `eslint:recommended` has been updated
Four new rules have been enabled in the `eslint:recommended` preset.
- [`no-loss-of-precision`](../rules/no-loss-of-precision)
- [`no-nonoctal-decimal-escape`](../rules/no-nonoctal-decimal-escape)
- [`no-unsafe-optional-chaining`](../rules/no-unsafe-optional-chaining)
- [`no-useless-backreference`](../rules/no-useless-backreference)
**To address:** Fix errors or disable these rules.
**Related issue(s):** [#14673](https://github.com/eslint/eslint/issues/14673)
## Rules require `meta.hasSuggestions` to provide suggestions
In ESLint v7.0.0, rules that [provided suggestions](../extend/custom-rules#providing-suggestions) did not need to let ESLint know. In v8.0.0, rules providing suggestions need to set their `meta.hasSuggestions` to `true`. This informs ESLint that the rule intends to provide suggestions. Without this property, any attempt to provide a suggestion will result in an error.
**To address:** If your rule provides suggestions, add `meta.hasSuggestions` to the object, such as:
```js
module.exports = {
meta: {
hasSuggestions: true,
},
create(context) {
// your rule
},
};
```
The [eslint-plugin/require-meta-has-suggestions](https://github.com/eslint-community/eslint-plugin-eslint-plugin/blob/main/docs/rules/require-meta-has-suggestions.md) rule can automatically fix and enforce that your rules are properly specifying `meta.hasSuggestions`.
**Related issue(s):** [#14312](https://github.com/eslint/eslint/issues/14312)
## Rules require `meta.fixable` to provide fixes
In ESLint v7.0.0, rules that were written as a function (rather than object) were able to provide fixes. In ESLint v8.0.0, only rules written as an object are allowed to provide fixes and must have a `meta.fixable` property set to either `"code"` or `"whitespace"`.
**To address:** If your rule makes fixes and is written as a function, such as:
```js
module.exports = function (context) {
// your rule
};
```
Then rewrite your rule in this format:
```js
module.exports = {
meta: {
fixable: "code", // or "whitespace"
},
create(context) {
// your rule
},
};
```
The [eslint-plugin/require-meta-fixable](https://github.com/eslint-community/eslint-plugin-eslint-plugin/blob/main/docs/rules/require-meta-fixable.md) rule can automatically fix and enforce that your rules are properly specifying `meta.fixable`.
The [eslint-plugin/prefer-object-rule](https://github.com/eslint-community/eslint-plugin-eslint-plugin/blob/main/docs/rules/prefer-object-rule.md) rule can automatically fix and enforce that your rules are written with the object format instead of the deprecated function format.
See the [rule documentation](../extend/custom-rules) for more information on writing rules.
**Related issue(s):** [#13349](https://github.com/eslint/eslint/issues/13349)
## `SourceCode#getComments()` fails in `RuleTester`
Back in ESLint v4.0.0, we deprecated `SourceCode#getComments()`, but we neglected to remove it. Rather than removing it completely in v8.0.0, we are taking the intermediate step of updating `RuleTester` to fail when `SourceCode#getComments()` is used inside of a rule. As such, all existing rules will continue to work, but when the developer runs tests for the rule there will be a failure.
The `SourceCode#getComments()` method will be removed in v9.0.0.
**To address:** If your rule uses `SourceCode#getComments()`, please use [`SourceCode#getCommentsBefore()`, `SourceCode#getCommentsAfter()`, or `SourceCode#getCommentsInside()`](../extend/custom-rules#accessing-comments).
**Related issue(s):** [#14744](https://github.com/eslint/eslint/issues/14744)
## Changes to shorthand property AST format
ESLint v8.0.0 includes an upgrade to Espree v8.0.0 to support new syntax. This Espree upgrade, in turn, contains an upgrade to Acorn v8.0.0, which changed how shorthand properties were represented in the AST. Here's an example:
```js
const version = 8;
const x = {
version,
};
```
This code creates a property node that looks like this:
```json
{
"type": "Property",
"method": false,
"shorthand": true,
"computed": false,
"key": {
"type": "Identifier",
"name": "version"
},
"kind": "init",
"value": {
"type": "Identifier",
"name": "version"
}
}
```
Note that both the `key` and the `value` properties contain the same information. Prior to Acorn v8.0.0 (and therefore prior to ESLint v8.0.0), these two nodes were represented by the same object, so you could use `===` to determine if they represented the same node, such as:
```js
// true in ESLint v7.x, false in ESLint v8.0.0
if (propertyNode.key === propertyNode.value) {
// do something
}
```
In ESLint v8.0.0 (via Acorn v8.0.0), the key and value are now separate objects and therefore no longer equivalent.
**To address:** If your rule makes a comparison between the key and value of a shorthand object literal property to determine if they are the same node, you'll need to change your code in one of two ways:
1. Use `propertyNode.shorthand` to determine if the property is a shorthand property node.
1. Use the `range` property of each node to determine if the key and value occupy the same location.
**Related issue(s):** [#14591](https://github.com/eslint/eslint/pull/14591#issuecomment-887733070)
## The `CLIEngine` class has been removed
The `CLIEngine` class has been removed and replaced by the [`ESLint` class](../integrate/nodejs-api#eslint-class).
**To address:** Update your code to use the new `ESLint` class if you are currently using `CLIEngine`. The following table maps the existing `CLIEngine` methods to their `ESLint` counterparts:
| `CLIEngine` | `ESLint` |
| :------------------------------------------- | :--------------------------------- |
| `executeOnFiles(patterns)` | `lintFiles(patterns)` |
| `executeOnText(text, filePath, warnIgnored)` | `lintText(text, options)` |
| `getFormatter(name)` | `loadFormatter(name)` |
| `getConfigForFile(filePath)` | `calculateConfigForFile(filePath)` |
| `isPathIgnored(filePath)` | `isPathIgnored(filePath)` |
| `static outputFixes(results)` | `static outputFixes(results)` |
| `static getErrorResults(results)` | `static getErrorResults(results)` |
| `static getFormatter(name)` | (removed ※1) |
| `addPlugin(pluginId, definition)` | the `plugins` constructor option |
| `getRules()` | (removed ※2) |
| `resolveFileGlobPatterns()` | (removed ※3) |
- ※1 The `engine.getFormatter()` method currently returns the object of loaded packages as-is, which made it difficult to add new features to formatters for backward compatibility reasons. The new `eslint.loadFormatter()` method returns an adapter object that wraps the object of loaded packages, to ease the process of adding new features. Additionally, the adapter object has access to the `ESLint` instance to calculate default data (using loaded plugin rules to make `rulesMeta`, for example). As a result, the `ESLint` class only implements an instance version of the `loadFormatter()` method.
- ※2 The `CLIEngine#getRules()` method had side effects and so was removed. If you were using `CLIEngine#getRules()` to retrieve meta information about rules based on linting results, use `ESLint#getRulesMetaForResults()` instead. If you were using `CLIEngine#getRules()` to retrieve all built-in rules, import `builtinRules` from `eslint/use-at-your-own-risk` for an unsupported API that allows access to internal rules.
- ※3 Since ESLint v6.0.0, ESLint uses different logic from the `resolveFileGlobPatterns()` method to iterate files, making this method obsolete.
**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654)
## The `linter` object has been removed
The deprecated `linter` object has been removed from the ESLint package in v8.0.0.
**To address:** If you are using the `linter` object, such as:
```js
const { linter } = require("eslint");
```
Change your code to this:
```js
const { Linter } = require("eslint");
const linter = new Linter();
```
**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654)
## The `/lib` entrypoint has been removed
Beginning in v8.0.0, ESLint is strictly defining its public API. Previously, you could reach into individual files such as `require("eslint/lib/rules/semi")` and this is no longer allowed. There are a limited number of existing APIs that are now available through the `/use-at-your-own-risk` entrypoint for backwards compatibility, but these APIs are not formally supported and may break or disappear at any point in time.
**To address:** If you are accessing rules directly through the `/lib` entrypoint, such as:
```js
const rule = require("eslint/lib/rules/semi");
```
Change your code to this:
```js
const { builtinRules } = require("eslint/use-at-your-own-risk");
const rule = builtinRules.get("semi");
```
If you are accessing `FileEnumerator` directly through the `/lib` entrypoint, such as:
```js
const { FileEnumerator } = require("eslint/lib/cli-engine/file-enumerator");
```
Change your code to this:
```js
const { FileEnumerator } = require("eslint/use-at-your-own-risk");
```
**Related issue(s):** [RFC80](https://github.com/eslint/rfcs/tree/main/designs/2021-package-exports), [#14716](https://github.com/eslint/eslint/pull/14716), [#13654](https://github.com/eslint/eslint/issues/13654)
---
---
title: Migrate to v9.x
---
ESLint v9.0.0 is a major release of ESLint, and as such, has several breaking changes that you need to be aware of. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Table of Contents
### Breaking changes for users
- [Node.js < v18.18, v19 are no longer supported](#drop-old-node)
- [New default config format (`eslint.config.js`)](#flat-config)
- [Removed multiple formatters](#removed-formatters)
- [Removed `require-jsdoc` and `valid-jsdoc` rules](#remove-jsdoc-rules)
- [`eslint:recommended` has been updated](#eslint-recommended)
- [`--quiet` no longer runs rules set to `"warn"`](#quiet-warn)
- [`--output-file` now writes a file to disk even with an empty output](#output-file)
- [Change in behavior when no patterns are passed to CLI](#cli-empty-patterns)
- [`/* eslint */` comments with only severity now retain options from the config file](#eslint-comment-options)
- [Multiple `/* eslint */` comments for the same rule are now disallowed](#multiple-eslint-comments)
- [Stricter `/* exported */` parsing](#exported-parsing)
- [`no-constructor-return` and `no-sequences` rule schemas are stricter](#stricter-rule-schemas)
- [New checks in `no-implicit-coercion` by default](#no-implicit-coercion)
- [Case-sensitive flags in `no-invalid-regexp`](#no-invalid-regexp)
- [`varsIgnorePattern` option of `no-unused-vars` no longer applies to catch arguments](#vars-ignore-pattern)
- [`no-restricted-imports` now accepts multiple config entries with the same `name`](#no-restricted-imports)
- [`"eslint:recommended"` and `"eslint:all"` strings no longer accepted in flat config](#string-config)
- [`no-inner-declarations` has a new default behavior with a new option](#no-inner-declarations)
- [`no-unused-vars` now defaults `caughtErrors` to `"all"`](#no-unused-vars)
- [`no-useless-computed-key` flags unnecessary computed member names in classes by default](#no-useless-computed-key)
- [`camelcase` allow option only accepts an array of strings](#camelcase)
### Breaking changes for plugin developers
- [Node.js < v18.18, v19 are no longer supported](#drop-old-node)
- [Removed multiple `context` methods](#removed-context-methods)
- [Removed `sourceCode.getComments()`](#removed-sourcecode-getcomments)
- [Removed `CodePath#currentSegments`](#removed-codepath-currentsegments)
- [Code paths are now precalculated](#codepath-precalc)
- [Function-style rules are no longer supported](#drop-function-style-rules)
- [`meta.schema` is required for rules with options](#meta-schema-required)
- [`FlatRuleTester` is now `RuleTester`](#flat-rule-tester)
- [Stricter `RuleTester` checks](#stricter-rule-tester)
### Breaking changes for integration developers
- [Node.js < v18.18, v19 are no longer supported](#drop-old-node)
- [`FlatESLint` is now `ESLint`](#flat-eslint)
- [`Linter` now expects flat config format](#flat-linter)
---
## Node.js < v18.18, v19 are no longer supported
ESLint is officially dropping support for these versions of Node.js starting with ESLint v9.0.0. ESLint now supports the following versions of Node.js:
- Node.js v18.18.0 and above
- Node.js v20.9.0 and above
- Node.js v21 and above
**To address:** Make sure you upgrade to at least Node.js v18.18.0 when using ESLint v9.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint v8.56.0 until you are able to upgrade Node.js.
**Related issue(s):** [#17595](https://github.com/eslint/eslint/issues/17595)
## New default config format (`eslint.config.js`)
As announced in our [blog post](/blog/2023/10/flat-config-rollout-plans/), in ESLint v9.0.0, [`eslint.config.js`](./configure/configuration-files) is the new default configuration format. The previous format, eslintrc, is now deprecated and will not automatically be searched for.
**To address:** Update your configuration to the new format following the [Configuration Migration Guide](./configure/migration-guide). In case you still need to use the deprecated eslintrc config format, set environment variable `ESLINT_USE_FLAT_CONFIG` to `false`.
**Related Issues(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
## Removed multiple formatters
ESLint v9.0.0 has removed the following formatters from the core:
| **Removed Formatter** | **Replacement npm Package** |
| --------------------- | ------------------------------- |
| `checkstyle` | `eslint-formatter-checkstyle` |
| `compact` | `eslint-formatter-compact` |
| `jslint-xml` | `eslint-formatter-jslint-xml` |
| `junit` | `eslint-formatter-junit` |
| `tap` | `eslint-formatter-tap` |
| `unix` | `eslint-formatter-unix` |
| `visualstudio` | `eslint-formatter-visualstudio` |
**To address:** If you are using any of these formatters via the `-f` command line flag, you'll need to install the respective package for the formatter.
**Related issue(s):** [#17524](https://github.com/eslint/eslint/issues/17524)
## Removed `require-jsdoc` and `valid-jsdoc` rules
The `require-jsdoc` and `valid-jsdoc` rules have been removed in ESLint v9.0.0. These rules were initially deprecated in 2018.
**To address:** Use the [replacement rules](https://github.com/gajus/eslint-plugin-jsdoc/wiki/Comparison-with-deprecated-JSdoc-related-ESLint-rules) in `eslint-plugin-jsdoc`.
**Related issue(s):** [#15820](https://github.com/eslint/eslint/issues/15820)
## `eslint:recommended` has been updated
Four new rules have been enabled in `eslint:recommended`:
- [`no-constant-binary-expression`](../rules/no-constant-binary-expression)
- [`no-empty-static-block`](../rules/no-empty-static-block)
- [`no-new-native-nonconstructor`](../rules/no-new-native-nonconstructor)
- [`no-unused-private-class-members`](../rules/no-unused-private-class-members)
Additionally, the following rules have been removed from `eslint:recommended`:
- [`no-extra-semi`](../rules/no-extra-semi)
- [`no-inner-declarations`](../rules/no-inner-declarations)
- [`no-mixed-spaces-and-tabs`](../rules/no-mixed-spaces-and-tabs)
- [`no-new-symbol`](../rules/no-new-symbol)
**To address:** Fix errors or disable these rules.
**Related issue(s):** [#15576](https://github.com/eslint/eslint/issues/15576), [#17446](https://github.com/eslint/eslint/issues/17446), [#17596](https://github.com/eslint/eslint/issues/17596)
## `--quiet` no longer runs rules set to `"warn"`
Prior to ESLint v9.0.0, the `--quiet` CLI flag would run all rules set to either `"error"` or `"warn"` and then hide the results from rules set to `"warn"`. In ESLint v9.0.0, `--quiet` will prevent rules from being executed when set to `"warn"`. This can result in a performance improvement for configurations containing many rules set to `"warn"`.
If `--max-warnings` is used then `--quiet` will not suppress the execution of rules set to `"warn"` but the output of those rules will be suppressed.
**To address:** In most cases, this change is transparent. If, however, you are running a rule set to `"warn"` that makes changes to the data available to other rules (for example, if the rule uses `sourceCode.markVariableAsUsed()`), then this can result in a behavior change. In such a case, you'll need to either set the rule to `"error"` or stop using `--quiet`.
**Related issue(s):** [#16450](https://github.com/eslint/eslint/issues/16450)
## `--output-file` now writes a file to disk even with an empty output
Prior to ESLint v9.0.0, the `--output-file` flag would skip writing a file to disk if the output was empty. However, in ESLint v9.0.0, `--output-file` now consistently writes a file to disk, even when the output is empty. This update ensures a more consistent and reliable behavior for `--output-file`.
**To address:** Review your usage of the `--output-file` flag, especially if your processes depend on the file's presence or absence based on output content. If necessary, update your scripts or configurations to accommodate this change.
**Related Issues(s):** [#17660](https://github.com/eslint/eslint/issues/17660)
## Change in behavior when no patterns are passed to CLI
Prior to ESLint v9.0.0, running the ESLint CLI without any file or directory patterns would result in no files being linted and would exit with code 0. This was confusing because it wasn't clear that nothing had actually happened. In ESLint v9.0.0, this behavior has been updated:
- **Flat config.** If you are using flat config, you can run `npx eslint` or `eslint` (if globally installed) and ESLint will assume you want to lint the current directory. Effectively, passing no patterns is equivalent to passing `.`.
- **eslintrc.** If you are using the deprecated eslintrc config, you'll now receive an error when running the CLI without any patterns.
**To address:** In most cases, no change is necessary, and you may find some locations where you thought ESLint was running but it wasn't. If you'd like to keep the v8.x behavior, where passing no patterns results in ESLint exiting with code 0, add the `--pass-on-no-patterns` flag to the CLI call.
**Related issue(s):** [#14308](https://github.com/eslint/eslint/issues/14308)
## `/* eslint */` comments with only severity now retain options from the config file
Prior to ESLint v9.0.0, configuration comments such as `/* eslint curly: "warn" */` or `/* eslint curly: ["warn"] */` would completely override any configuration specified for the rule in the config file, and thus enforce the default options of the rule.
In ESLint v9.0.0, the behavior of configuration comments is aligned with how rule configurations in config files are merged, meaning that a configuration comment with only severity now retains options specified in the config file and just overrides the severity.
For example, if you have the following config file:
```js
// eslint.config.js
export default [
{
rules: {
curly: ["error", "multi"],
},
},
];
```
and the following configuration comment:
```js
// my-file.js
/* eslint curly: "warn" */
```
the resulting configuration for the `curly` rule when linting `my-file.js` will be `curly: ["warn", "multi"]`.
Note that this change only affects cases where the same rule is configured in the config file with options and using a configuration comment without options. In all other cases (e.g. the rule is only configured using a configuration comment), the behavior remains the same as prior to ESLint v9.0.0.
**To address:** We expect that in most cases no change is necessary, as rules configured using configuration comments are typically not already configured in the config file. However, if you need a configuration comment to completely override configuration from the config file and enforce the default options, you'll need to specify at least one option:
```js
// my-file.js
/* eslint curly: ["warn", "all"] */
```
**Related issue(s):** [#17381](https://github.com/eslint/eslint/issues/17381)
## Multiple `/* eslint */` comments for the same rule are now disallowed
Prior to ESLint v9.0.0, if the file being linted contained multiple `/* eslint */` configuration comments for the same rule, the last one would be applied, while the others would be silently ignored. For example:
```js
/* eslint semi: ["error", "always"] */
/* eslint semi: ["error", "never"] */
foo(); // valid, because the configuration is "never"
```
In ESLint v9.0.0, the first one is applied, while the others are reported as lint errors:
```js
/* eslint semi: ["error", "always"] */
/* eslint semi: ["error", "never"] */ // error: Rule "semi" is already configured by another configuration comment in the preceding code. This configuration is ignored.
foo(); // error: Missing semicolon
```
**To address:** Remove duplicate `/* eslint */` comments.
**Related issue(s):** [#18132](https://github.com/eslint/eslint/issues/18132)
## Stricter `/* exported */` parsing
Prior to ESLint v9.0.0, the `/* exported */` directive incorrectly allowed the following syntax:
```js
/* exported foo: true, bar: false */
// and
/* exported foo bar */
```
The `true` and `false` in this example had no effect on ESLint's behavior, and in fact, was a parsing bug.
In ESLint v9.0.0, any `/* exported */` variables followed by a colon and value will be ignored as invalid.
**To address:** Update any `/* exported */` directives to eliminate the colons and subsequent values, and ensure there are commas between variable names such as:
```js
/* exported foo, bar */
```
**Related issue(s):** [#17622](https://github.com/eslint/eslint/issues/17622)
## `no-constructor-return` and `no-sequences` rule schemas are stricter
In previous versions of ESLint, `no-constructor-return` and `no-sequences` rules were mistakenly accepting invalid options.
This has been fixed in ESLint v9.0.0:
- The `no-constructor-return` rule does not accept any options.
- The `no-sequences` rule can take one option, an object with a property `"allowInParentheses"` (boolean).
```json
{
"rules": {
"no-constructor-return": ["error"],
"no-sequences": ["error", { "allowInParentheses": false }]
}
}
```
**To address:** If ESLint reports invalid configuration for any of these rules, update your configuration.
**Related issue(s):** [#16879](https://github.com/eslint/eslint/issues/16879)
## New checks in `no-implicit-coercion` by default
In ESLint v9.0.0, the `no-implicit-coercion` rule additionally reports the following cases by default:
```js
-(-foo);
foo - 0;
```
**To address:** If you want to retain the previous behavior of this rule, set `"allow": ["-", "- -"]`.
```json
{
"rules": {
"no-implicit-coercion": [2, { "allow": ["-", "- -"] }]
}
}
```
**Related issue(s):** [#17832](https://github.com/eslint/eslint/pull/17832)
## Case-sensitive flags in `no-invalid-regexp`
In ESLint v9.0.0, the option `allowConstructorFlags` is now case-sensitive.
**To address:** Update your configuration if needed.
**Related issue(s):** [#16574](https://github.com/eslint/eslint/issues/16574)
## `varsIgnorePattern` option of `no-unused-vars` no longer applies to catch arguments
In previous versions of ESLint, the `varsIgnorePattern` option of `no-unused-vars` incorrectly ignored errors specified in a `catch` clause. In ESLint v9.0.0, `varsIgnorePattern` no longer applies to errors in `catch` clauses. For example:
```js
/*eslint no-unused-vars: ["error", { "caughtErrors": "all", "varsIgnorePattern": "^err" }]*/
try {
//...
} catch (err) {
// 'err' will be reported.
console.error("errors");
}
```
**To address:** If you want to specify ignore patterns for `catch` clause variable names, use the `caughtErrorsIgnorePattern` option in addition to `varsIgnorePattern`.
**Related issue(s):** [#17540](https://github.com/eslint/eslint/issues/17540)
## `no-restricted-imports` now accepts multiple config entries with the same `name`
In previous versions of ESLint, if multiple entries in the `paths` array of your configuration for the `no-restricted-imports` rule had the same `name` property, only the last one would apply, while the previous ones would be ignored.
As of ESLint v9.0.0, all entries apply, allowing for specifying different messages for different imported names. For example, you can now configure the rule like this:
```js
{
rules: {
"no-restricted-imports": ["error", {
paths: [
{
name: "react-native",
importNames: ["Text"],
message: "import 'Text' from 'ui/_components' instead"
},
{
name: "react-native",
importNames: ["View"],
message: "import 'View' from 'ui/_components' instead"
}
]
}]
}
}
```
and both `import { Text } from "react-native"` and `import { View } from "react-native"` will be reported, with different messages.
In previous versions of ESLint, with this configuration only `import { View } from "react-native"` would be reported.
**To address:** If your configuration for this rule has multiple entries with the same `name`, you may need to remove unintentional ones.
**Related issue(s):** [#15261](https://github.com/eslint/eslint/issues/15261)
## `"eslint:recommended"` and `"eslint:all"` no longer accepted in flat config
In ESLint v8.x, `eslint.config.js` could refer to `"eslint:recommended"` and `"eslint:all"` configurations by inserting a string into the config array, as in this example:
```js
// eslint.config.js
export default ["eslint:recommended", "eslint:all"];
```
In ESLint v9.0.0, this format is no longer supported and will result in an error.
**To address:** Use the `@eslint/js` package instead:
```js
// eslint.config.js
import js from "@eslint/js";
export default [js.configs.recommended, js.configs.all];
```
**Related issue(s):** [#17488](https://github.com/eslint/eslint/issues/17488)
## `no-inner-declarations` has a new default behavior with a new option
ESLint v9.0.0 introduces a new option in `no-inner-declarations` rule called `blockScopeFunctions` which by default allows block-level `function`s in strict mode when `languageOptions.ecmaVersion` is set to `2015` or above.
```js
/*eslint no-inner-declarations: "error"*/
"use strict";
if (test) {
function foo() {} // no error
}
```
**To address:** If you want to report the block-level `function`s in every condition regardless of strict or non-strict mode, set the `blockScopeFunctions` option to `"disallow"`.
**Related issue(s):** [#15576](https://github.com/eslint/eslint/issues/15576)
## `no-unused-vars` now defaults `caughtErrors` to `"all"`
ESLint v9.0.0 changes the default value for the `no-unused-vars` rule's `caughtErrors` option.
Previously it defaulted to `"none"` to never check whether caught errors were used.
It now defaults to `"all"` to check caught errors for being used.
```js
/*eslint no-unused-vars: "error"*/
try {
} catch (error) {
// 'error' is defined but never used
}
```
**To address:** If you want to allow unused caught errors, such as when writing code that will be directly run in an environment that does not support ES2019 optional catch bindings, set the `caughtErrors` option to `"none"`.
Otherwise, delete the unused caught errors.
```js
/*eslint no-unused-vars: "error"*/
try {
} catch {
// no error
}
```
**Related issue(s):** [#17974](https://github.com/eslint/eslint/issues/17974)
## `no-useless-computed-key` flags unnecessary computed member names in classes by default
In ESLint v9.0.0, the default value of the `enforceForClassMembers` option of the `no-useless-computed-key` rule was changed from `false` to `true`.
The effect of this change is that unnecessary computed member names in classes will be flagged by default.
```js
/*eslint no-useless-computed-key: "error"*/
class SomeClass {
["someMethod"]() {} // ok in ESLint v8, error in ESLint v9.
}
```
**To address:** Fix the problems reported by the rule or revert to the previous behavior by setting the `enforceForClassMembers` option to `false`.
**Related issue(s):** [#18042](https://github.com/eslint/eslint/issues/18042)
## `camelcase` allow option only accepts an array of strings
Previously the camelcase rule didn't enforce the `allow` option to be an array of strings. In ESLint v9.0.0, the `allow` option now only accepts an array of strings.
**To address:** If ESLint reports invalid configuration for this rule, update your configuration.
**Related issue(s):** [#18232](https://github.com/eslint/eslint/pull/18232)
## Removed multiple `context` methods
ESLint v9.0.0 removes multiple deprecated methods from the `context` object and moves them onto the `SourceCode` object:
| **Removed on `context`** | **Replacement(s) on `SourceCode`** |
| -------------------------------- | --------------------------------------------------------------------------------------------------- |
| `context.getSource()` | `sourceCode.getText()` |
| `context.getSourceLines()` | `sourceCode.getLines()` |
| `context.getAllComments()` | `sourceCode.getAllComments()` |
| `context.getNodeByRangeIndex()` | `sourceCode.getNodeByRangeIndex()` |
| `context.getComments()` | `sourceCode.getCommentsBefore()`, `sourceCode.getCommentsAfter()`, `sourceCode.getCommentsInside()` |
| `context.getCommentsBefore()` | `sourceCode.getCommentsBefore()` |
| `context.getCommentsAfter()` | `sourceCode.getCommentsAfter()` |
| `context.getCommentsInside()` | `sourceCode.getCommentsInside()` |
| `context.getJSDocComment()` | `sourceCode.getJSDocComment()` |
| `context.getFirstToken()` | `sourceCode.getFirstToken()` |
| `context.getFirstTokens()` | `sourceCode.getFirstTokens()` |
| `context.getLastToken()` | `sourceCode.getLastToken()` |
| `context.getLastTokens()` | `sourceCode.getLastTokens()` |
| `context.getTokenAfter()` | `sourceCode.getTokenAfter()` |
| `context.getTokenBefore()` | `sourceCode.getTokenBefore()` |
| `context.getTokenByRangeStart()` | `sourceCode.getTokenByRangeStart()` |
| `context.getTokens()` | `sourceCode.getTokens()` |
| `context.getTokensAfter()` | `sourceCode.getTokensAfter()` |
| `context.getTokensBefore()` | `sourceCode.getTokensBefore()` |
| `context.getTokensBetween()` | `sourceCode.getTokensBetween()` |
| `context.parserServices` | `sourceCode.parserServices` |
| `context.getDeclaredVariables()` | `sourceCode.getDeclaredVariables()` |
In addition to the methods in the above table, there are several other methods that are also moved but required different method signatures:
| **Removed on `context`** | **Replacement(s) on `SourceCode`** |
| ---------------------------------- | ------------------------------------------- |
| `context.getAncestors()` | `sourceCode.getAncestors(node)` |
| `context.getScope()` | `sourceCode.getScope(node)` |
| `context.markVariableAsUsed(name)` | `sourceCode.markVariableAsUsed(name, node)` |
**To address:** Use the automated upgrade tool as recommended in the [blog post](https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#automatically-update-your-rules).
**Related Issues(s):** [#16999](https://github.com/eslint/eslint/issues/16999), [#13481](https://github.com/eslint/eslint/issues/13481)
## Removed `sourceCode.getComments()`
ESLint v9.0.0 removes the deprecated `sourceCode.getComments()` method.
**To address:** Replace with `sourceCode.getCommentsBefore()`, `sourceCode.getCommentsAfter()`, or `sourceCode.getCommentsInside()`.
**Related Issues(s):** [#14744](https://github.com/eslint/eslint/issues/14744)
## Removed `CodePath#currentSegments`
ESLint v9.0.0 removes the deprecated `CodePath#currentSegments` property.
**To address:** Update your code following the recommendations in the [blog post](https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#codepath%23currentsegments).
**Related Issues(s):** [#17457](https://github.com/eslint/eslint/issues/17457)
## Code paths are now precalculated
Prior to ESLint v9.0.0, code paths were calculated during the same AST traversal used by rules, meaning that the information passed to methods like `onCodePathStart` and `onCodePathSegmentStart` was incomplete. Specifically, array properties like `CodePath#childCodePaths` and `CodePathSegment#nextSegments` began empty and then were filled with the appropriate information as the traversal completed, meaning that those arrays could have different elements depending on when you checked their values.
ESLint v9.0.0 now precalculates code path information before the traversal used by rules. As a result, the code path information is now complete regardless of where it is accessed inside of a rule.
**To address:** If you are accessing any array properties on `CodePath` or `CodePathSegment`, you'll need to update your code. Specifically:
- If you are checking the `length` of any array properties, ensure you are using relative comparison operators like `<`, `>`, `<=`, and `>=` instead of equals.
- If you are accessing the `nextSegments`, `prevSegments`, `allNextSegments`, or `allPrevSegments` properties on a `CodePathSegment`, or `CodePath#childCodePaths`, verify that your code will still work as expected. To be backwards compatible, consider moving the logic that checks these properties into `onCodePathEnd`.
**Related Issues(s):** [#16999](https://github.com/eslint/eslint/issues/16999)
## Function-style rules are no longer supported
ESLint v9.0.0 drops support for function-style rules. Function-style rules are rules created by exporting a function rather than an object with a `create()` method. This rule format was deprecated in 2016.
**To address:** Update your rules to [the most recent rule format](../extend/custom-rules). For rules written in CommonJS, you can also use [`eslint-transforms`](https://github.com/eslint/eslint-transforms/blob/main/README.md#new-rule-format).
The [eslint-plugin/prefer-object-rule](https://github.com/eslint-community/eslint-plugin-eslint-plugin/blob/main/docs/rules/prefer-object-rule.md) rule can help enforce the usage of object-style rules and autofix any remaining function-style rules.
**Related Issues(s):** [#14709](https://github.com/eslint/eslint/issues/14709)
## `meta.schema` is required for rules with options
As of ESLint v9.0.0, an error will be thrown if any options are [passed](../use/configure/rules#using-configuration-files) to a rule that doesn't specify `meta.schema` property.
**To address:**
- If your rule expects [options](../extend/custom-rules#accessing-options-passed-to-a-rule), set [`meta.schema`](../extend/custom-rules#options-schemas) property to a JSON Schema format description of the rule’s options. This schema will be used by ESLint to validate configured options and prevent invalid or unexpected inputs to your rule.
- If your rule doesn't expect any options, there is no action required. This change ensures that end users will not mistakenly configure options for rules that don't expect options.
- **(not recommended)** you can also set `meta.schema` to `false` to disable this validation, but it is highly recommended to provide a schema if the rule expects options and omit the schema (or set `[]`) if the rule doesn't expect options so that ESLint can ensure that your users' configurations are valid.
The [eslint-plugin/require-meta-schema](https://github.com/eslint-community/eslint-plugin-eslint-plugin/blob/main/docs/rules/require-meta-schema.md) rule can help enforce that rules have schemas when required.
**Related Issues(s):** [#14709](https://github.com/eslint/eslint/issues/14709)
## `FlatRuleTester` is now `RuleTester`
As announced in our [blog post](/blog/2023/10/flat-config-rollout-plans/), the temporary `FlatRuleTester` class has been renamed to `RuleTester`, while the `RuleTester` class from v8.x has been removed. Additionally, the `FlatRuleTester` export from `eslint/use-at-your-own-risk` has been removed.
**To address:** Update your rule tests to use the new `RuleTester`. To do so, here are some of the common changes you'll need to make:
- **Be aware of new defaults for `ecmaVersion` and `sourceType`.** By default, `RuleTester` uses the flat config default of `ecmaVersion: "latest"` and `sourceType: "module"`. This may cause some tests to break if they were expecting the old default of `ecmaVersion: 5` and `sourceType: "script"`. If you'd like to use the old default, you'll need to manually specify that in your `RuleTester` like this:
```js
// use eslintrc defaults
const ruleTester = new RuleTester({
languageOptions: {
ecmaVersion: 5,
sourceType: "script",
},
});
```
- **Change `parserOptions` to `languageOptions`.** If you're setting `ecmaVersion` or `sourceType` on your tests, move those from `parserOptions` to `languageOptions`, like this:
```js
ruleTester.run("my-rule", myRule, {
valid: [
{
code: "foo",
parserOptions: {
ecmaVersion: 6,
},
},
],
});
// becomes
ruleTester.run("my-rule", myRule, {
valid: [
{
code: "foo",
languageOptions: {
ecmaVersion: 6,
},
},
],
});
```
- **Translate other config keys.** Keys such as `env` and `parser` that used to run on the eslintrc config system must be translated into the flat config system. Please refer to the [Configuration Migration Guide](configure/migration-guide) for details on translating other keys you may be using.
**Related Issues(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
## Stricter `RuleTester` checks
In order to aid in the development of high-quality custom rules that are free from common bugs, ESLint v9.0.0 implements several changes to `RuleTester`:
1. **Test case `output` must be different from `code`.** In ESLint v8.x, if `output` is the same as `code`, it asserts that there was no autofix. When looking at a test case, it's not always immediately clear whether `output` differs from `code`, especially if the strings are longer or multiline, making it difficult for developers to determine whether or not the test case expects an autofix. In ESLint v9.0.0, to avoid this ambiguity, `RuleTester` now throws an error if the test `output` has the same value as the test `code`. Therefore, specifying `output` now necessarily means that the test case expects an autofix and asserts its result. If the test case doesn't expect an autofix, omit the `output` property or set it to `null`. This asserts that there was no autofix.
1. **Test error objects must specify `message` or `messageId`.** To improve the quality of test coverage, `RuleTester` now throws an error if neither `message` nor `messageId` is specified on test error objects.
1. **Test error object must specify `suggestions` if the actual error provides suggestions.** In ESLint v8.x, if the `suggestions` property was omitted from test error objects, `RuleTester` wasn't performing any checks related to suggestions, so it was easy to forget to assert if a test case produces suggestions. In ESLint v9.0.0, omitting the `suggestions` property asserts that the actual error does not provide suggestions, while you need to specify the `suggestions` property if the actual error does provide suggestions. We highly recommend that you test suggestions in detail by specifying an array of test suggestion objects, but you can also specify `suggestions: ` to assert just the number of suggestions.
1. **Test suggestion objects must specify `output`.** To improve the quality of test coverage, `RuleTester` now throws an error if `output` property is not specified on test suggestion objects.
1. **Test suggestion objects must specify `desc` or `messageId`.** To improve the quality of test coverage, `RuleTester` now throws an error if neither `desc` nor `messageId` property is specified on test suggestion objects. It's also not allowed to specify both. If you want to assert the suggestion description text in addition to the `messageId`, then also add the `data` property.
1. **Suggestion messages must be unique.** Because suggestions are typically displayed in an editor as a dropdown list, it's important that no two suggestions for the same lint problem have the same message. Otherwise, it's impossible to know what any given suggestion will do. This additional check runs automatically.
1. **Suggestions must change the code.** Suggestions are expected to fix the reported problem by changing the code. `RuleTester` now throws an error if the suggestion test `output` is the same as the test `code`.
1. **Suggestions must generate valid syntax.** In order for rule suggestions to be helpful, they need to be valid syntax. `RuleTester` now parses the output of suggestions using the same language options as the `code` value and throws an error if parsing fails.
1. **Test cases must be unique.** Identical test cases can cause confusion and be hard to detect manually in a long test file. Duplicates are now automatically detected and can be safely removed.
1. **`filename` and `only` must be of the expected type.** `RuleTester` now checks the type of `filename` and `only` properties of test objects. If specified, `filename` must be a string value. If specified, `only` must be a boolean value.
1. **Messages cannot have unsubstituted placeholders.** The `RuleTester` now also checks if there are {% raw %}`{{ placeholder }}` {% endraw %} still in the message as their values were not passed via `data` in the respective `context.report()` call.
**To address:** Run your rule tests using `RuleTester` and fix any errors that occur. The changes you'll need to make to satisfy `RuleTester` are compatible with ESLint v8.x.
**Related Issues(s):** [#15104](https://github.com/eslint/eslint/issues/15104), [#15735](https://github.com/eslint/eslint/issues/15735), [#16908](https://github.com/eslint/eslint/issues/16908), [#18016](https://github.com/eslint/eslint/issues/18016)
## `FlatESLint` is now `ESLint`
As announced in our [blog post](/blog/2023/10/flat-config-rollout-plans/), the temporary `FlatESLint` class has been renamed to `ESLint`, while the `ESLint` class from v8.x has been renamed to `LegacyESLint`.
**To address:** If you are currently using the `ESLint` class, verify that your tests pass using the new `ESLint` class. Not all of the old options are supported, so you may need to update the arguments passed to the constructor. See the [Node.js API Reference](../integrate/nodejs-api) for details.
If you still need the v8.x `ESLint` functionality, use the `LegacyESLint` class like this:
```js
const { LegacyESLint } = require("eslint/use-at-your-own-risk");
```
**Related Issues(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
## `Linter` now expects flat config format
In ESLint v9.0.0, the `config` argument passed to `Linter#verify()` and `Linter#verifyAndFix()` methods should be in the flat config format.
Additionally, methods `Linter#defineRule()`, `Linter#defineRules()`, `Linter#defineParser()`, and `Linter#getRules()` are no longer available.
**To address:** If you are using the `Linter` class, verify that your tests pass.
If you're passing configuration objects that are incompatible with the flat config format, you'll need to update the code.
```js
// eslintrc config format
linter.verify(code, {
parserOptions: {
ecmaVersion: 6,
},
});
// flat config format
linter.verify(code, {
languageOptions: {
ecmaVersion: 6,
},
});
```
Please refer to the [Configuration Migration Guide](configure/migration-guide) for details on translating other keys you may be using.
Rules and parsers can be defined directly in the configuration.
```js
// eslintrc mode
linter.defineRule("my-rule1", myRule1);
linter.defineRules({
"my-rule2": myRule2,
"my-rule3": myRule3,
});
linter.defineParser("my-parser", myParser);
linter.verify(code, {
rules: {
"my-rule1": "error",
"my-rule2": "error",
"my-rule3": "error",
},
parser: "my-parser",
});
// flat config mode
linter.verify(code, {
plugins: {
"my-plugin-foo": {
rules: {
"my-rule1": myRule1,
},
},
"my-plugin-bar": {
rules: {
"my-rule2": myRule2,
"my-rule3": myRule3,
},
},
},
rules: {
"my-plugin-foo/my-rule1": "error",
"my-plugin-bar/my-rule2": "error",
"my-plugin-bar/my-rule3": "error",
},
languageOptions: {
parser: myParser,
},
});
```
If you still need the v8.x `Linter` functionality, pass `configType: "eslintrc"` to the constructor like this:
```js
const linter = new Linter({ configType: "eslintrc" });
linter.verify(code, {
parserOptions: {
ecmaVersion: 6,
},
});
linter.getRules();
```
**Related Issues(s):** [#13481](https://github.com/eslint/eslint/issues/13481)
---
---
title: Migrating from JSCS
---
{%- from 'components/npm_tabs.macro.html' import npm_tabs with context %}
In April 2016, we [announced](https://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) that the JSCS project was shutting down and the JSCS team would be joining the ESLint team. This guide is intended to help those who are using JSCS to migrate their settings and projects to use ESLint. We've tried to automate as much of the conversion as possible, but there are some manual changes that are needed.
## Terminology
Before beginning the process of migrating to ESLint, it's helpful to understand some of the terminology that ESLint uses and how it relates to terminology that JSCS uses.
- **Configuration File** - In JSCS, the configuration file is `.jscsrc`, `.jscsrc.json`, `.jscsrc.yaml`, or `.jscsrs.js`. In ESLint, the configuration file can be `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc.js` (there is also a deprecated `.eslintrc` file format).
- **Presets** - In JSCS, there were numerous predefined configurations shipped directly within JSCS. ESLint ships with just one predefined configuration (`eslint:recommended`) that has no style rules enabled. However, ESLint does support [shareable configs](../extend/shareable-configs). Shareable configs are configurations that are published on their own to npm and there are shareable configs available for almost all of the JSCS presets (see [the "Converting Presets" section](#converting-presets) below). Additionally, the `preset` option in a configuration file is the equivalent of the ESLint `extends` option.
## Convert Configuration Files Using Polyjuice
[Polyjuice](https://github.com/brenolf/polyjuice) is a utility for converting JSCS (and JSHint) configuration files into ESLint configuration files automatically. It understands the equivalent rules from each utility and will automatically output an ESLint configuration file that is a good approximation of your existing JSCS file.
To install Polyjuice:
{{ npm_tabs({
command: "install",
packages: ["polyjuice"],
args: ["--global"]
}) }}
Polyjuice works with JSON configuration files, so if you're using a JavaScript or YAML JSCS configuration file, you should first convert it into a JSON configuration file.
To convert your configuration file, pass in the location of your `.jscs.json` file using the `--jscs` flag:
```shell
polyjuice --jscs .jscsrc.json > .eslintrc.json
```
This creates an `.eslintrc.json` with the equivalent rules from `.jscsrc.json`.
If you have multiple `.jscsrc.json` files, you can pass them all and Polyjuice will combine them into one `.eslintrc.json` file:
```shell
polyjuice --jscs .jscsrc.json ./foo/.jscsrc.json > .eslintrc.json
```
**Note:** Polyjuice does a good job of creating a reasonable ESLint configuration from your JSCS configuration, but it may not be 100%. You may still see different warnings than you saw with JSCS, and so you may need to further modify your configuration after using Polyjuice. This is especially true if you're using inline comments to enable/disable certain rules in JSCS (you'll need to manually convert those to use ESLint-style comments instead, [see "Disabling Rules Inline"](#disabling-rules-inline) later in this page).
### Creating a New Configuration From Scratch
If you don't want to convert your JSCS configuration directly into an ESLint configuration, then you can use ESLint's built-in wizard to get you started. Just run:
{{ npm_tabs({
command: "init-create",
packages: ["@eslint/config@latest"],
args: []
}) }}
You'll be guided through a series of questions that will help you setup a basic configuration file to get you started.
## Converting Presets
There are shareable configs available for most JSCS presets. The equivalent shareable configs for each JSCS preset are listed in the following table:
| **JSCS Preset** | **ESLint Shareable Config** |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `airbnb` | [`eslint-config-airbnb-base`](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base) |
| `crockford` | (not available) |
| `google` | [`eslint-config-google`](https://github.com/google/eslint-config-google) |
| `grunt` | [`eslint-config-grunt`](https://github.com/markelog/eslint-config-grunt) |
| `idiomatic` | [`eslint-config-idiomatic`](https://github.com/jamespamplin/eslint-config-idiomatic) |
| `jquery` | [`eslint-config-jquery`](https://github.com/jquery/eslint-config-jquery) |
| `mdcs` | [`eslint-config-mdcs`](https://github.com/zz85/mrdoobapproves) |
| `node-style-guide` | [`eslint-config-node-style-guide`](https://github.com/pdehaan/eslint-config-node-style-guide) |
| `wikimedia` | [`eslint-config-wikimedia`](https://github.com/wikimedia/eslint-config-wikimedia) |
| `wordpress` | [`eslint-config-wordpress`](https://github.com/WordPress-Coding-Standards/eslint-config-wordpress) |
As an example, suppose that you are using the `airbnb` preset, so your `.jscsrc` file looks like this:
```json
{
"preset": "airbnb"
}
```
In order to get the same functionality in ESLint, you would first need to install the `eslint-config-airbnb` shareable config package:
{{ npm_tabs({
command: "install",
packages: ["eslint-config-airbnb-base"],
args: ["--save-dev"]
}) }}
And then you would modify your configuration file like this:
```json
{
"extends": "airbnb-base"
}
```
ESLint sees `"airbnb-base"` and will look for `eslint-config-airbnb-base` (to save you some typing).
## Disabling Rules Inline
Both JSCS and ESLint use comments inside of files to disable rules around certain parts of your code. The following table lists out the JSCS inline configuration comments and their ESLint equivalents.
| **Description** | **JSCS Comment** | **ESLint Comment** |
| ------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------- |
| Disable all rules | `// jscs:disable` or `/* jscs:disable */` | `/* eslint-disable */` |
| Enable all rules | `// jscs:enable` or `/* jscs:enable */` | `/* eslint-enable */` |
| Disable one rule | `// jscs:disable ruleName` or `/* jscs:disable ruleName */` | `/* eslint-disable rule-name */` |
| Enable one rule | `// jscs:enable ruleName` or `/* jscs:enable ruleName */` | `/* eslint-enable rule-name */` |
| Disable multiple rules | `// jscs:disable ruleName1, ruleName2` or `/* jscs:disable ruleName1, ruleName2 */` | `/* eslint-disable rule-name1, rule-name2 */` |
| Enable multiple rules | `// jscs:enable ruleName1, ruleName2` or `/* jscs:enable ruleName1, ruleName2 */` | `/* eslint-enable rule-name1, rule-name2 */` |
| Disable one rule on single line | `// jscs:ignore ruleName` | `// eslint-disable-line rule-name` |
## Command Line Options
Both JSCS and ESLint have command line arguments corresponding to many of their configuration options. The following are the ESLint equivalents of JSCS command line options.
### `--fix`
JSCS uses the `--fix` option to apply automatic fixes to code:
```shell
jscs --fix file.js
```
ESLint has the same option:
```shell
eslint --fix file.js
```
### `--auto-configure`
The JSCS `--auto-configure` option created a configuration based on what it found in a given file:
```shell
jscs --auto-configure file.js
```
In ESLint, there's a similar option when you use `--init`. Just select "Inspect your JavaScript file(s)":
```shell
eslint --init
? How would you like to configure ESLint? (Use arrow keys)
> Answer questions about your style
Use a popular style guide
Inspect your JavaScript file(s)
```
## `--config`, `-c`
JSCS allows you to specify a configuration file to use on the command line using either `--config` or `-c`, such as:
```shell
jscs --config myconfig.json file.js
jscs -c myconfig.json file.js
```
Both flags are also supported by ESLint:
```shell
eslint --config myconfig.json file.js
eslint -c myconfig.json file.js
```
## Piping Code Into ESLint
In JSCS, you can pipe code in like this:
```shell
cat file.js | jscs
```
In ESLint, you can also pipe in code, but you need to use the `--stdin` flag:
```shell
cat file.js | eslint --stdin
```
---
---
title: Migrating to v1.0.0
---
ESLint v1.0.0 is the first major version release. As a result, there are some significant changes between how ESLint worked during its life in 0.x and how it will work going forward. These changes are the direct result of feedback from the ESLint community of users and were not made without due consideration for the upgrade path. We believe that these changes make ESLint even better, and while some work is necessary to upgrade, we hope the pain of this upgrade is small enough that you will see the benefit of upgrading.
## All Rules Off by Default
The most important difference in v1.0.0 is that all rules are off by default. We made this change after numerous requests to allow turning off the default rules from within configuration files. While that wasn't technically feasible, it was feasible to have all rules off by default and then re-enable rules in configuration files using `extends`. As such, we've made the `--reset` behavior the default and removed this command line option.
When using `--init`, your configuration file will automatically include the following line:
```json
{
"extends": "eslint:recommended"
}
```
This setting mimics some of the default behavior from 0.x, but not all. If you don't want to use any of the recommended rules, you can delete this line.
**To address:** If you are currently using `--reset`, then you should stop passing `--reset` on the command line; no other changes are necessary. If you are not using `--reset`, then you should review your configuration to determine which rules should be on by default. You can partially restore some of the default behavior by adding the following to your configuration file:
The `"eslint:recommended"` configuration contains many of the same default rule settings from 0.x, but not all. These rules are no longer on by default, so you should review your settings to ensure they are still as you expect:
- [no-alert](../rules/no-alert)
- [no-array-constructor](../rules/no-array-constructor)
- [no-caller](../rules/no-caller)
- [no-catch-shadow](../rules/no-catch-shadow)
- [no-empty-label](../rules/no-empty-label)
- [no-eval](../rules/no-eval)
- [no-extend-native](../rules/no-extend-native)
- [no-extra-bind](../rules/no-extra-bind)
- [no-extra-strict](../rules/no-extra-strict)
- [no-implied-eval](../rules/no-implied-eval)
- [no-iterator](../rules/no-iterator)
- [no-label-var](../rules/no-label-var)
- [no-labels](../rules/no-labels)
- [no-lone-blocks](../rules/no-lone-blocks)
- [no-loop-func](../rules/no-loop-func)
- [no-multi-spaces](../rules/no-multi-spaces)
- [no-multi-str](../rules/no-multi-str)
- [no-native-reassign](../rules/no-native-reassign)
- [no-new](../rules/no-new)
- [no-new-func](../rules/no-new-func)
- [no-new-object](../rules/no-new-object)
- [no-new-wrappers](../rules/no-new-wrappers)
- [no-octal-escape](../rules/no-octal-escape)
- [no-process-exit](../rules/no-process-exit)
- [no-proto](../rules/no-proto)
- [no-return-assign](../rules/no-return-assign)
- [no-script-url](../rules/no-script-url)
- [no-sequences](../rules/no-sequences)
- [no-shadow](../rules/no-shadow)
- [no-shadow-restricted-names](../rules/no-shadow-restricted-names)
- [no-spaced-func](../rules/no-spaced-func)
- [no-trailing-spaces](../rules/no-trailing-spaces)
- [no-undef-init](../rules/no-undef-init)
- [no-underscore-dangle](../rules/no-underscore-dangle)
- [no-unused-expressions](../rules/no-unused-expressions)
- [no-use-before-define](../rules/no-use-before-define)
- [no-with](../rules/no-with)
- [no-wrap-func](../rules/no-wrap-func)
- [camelcase](../rules/camelcase)
- [comma-spacing](../rules/comma-spacing)
- [consistent-return](../rules/consistent-return)
- [curly](../rules/curly)
- [dot-notation](../rules/dot-notation)
- [eol-last](../rules/eol-last)
- [eqeqeq](../rules/eqeqeq)
- [key-spacing](../rules/key-spacing)
- [new-cap](../rules/new-cap)
- [new-parens](../rules/new-parens)
- [quotes](../rules/quotes)
- [semi](../rules/semi)
- [semi-spacing](../rules/semi-spacing)
- [space-infix-ops](../rules/space-infix-ops)
- [space-return-throw-case](../rules/space-return-throw-case)
- [space-unary-ops](../rules/space-unary-ops)
- [strict](../rules/strict)
- [yoda](../rules/yoda)
See also: the [full diff](https://github.com/eslint/eslint/commit/e3e9dbd9876daf4bdeb4e15f8a76a9d5e6e03e39#diff-b01a5cfd9361ca9280a460fd6bb8edbbL1) where the defaults were changed.
Here's a configuration file with the closest equivalent of the old defaults:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-alert": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-catch-shadow": 2,
"no-empty-label": 2,
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-implied-eval": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-loop-func": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-native-reassign": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-wrappers": 2,
"no-octal-escape": 2,
"no-process-exit": 2,
"no-proto": 2,
"no-return-assign": 2,
"no-script-url": 2,
"no-sequences": 2,
"no-shadow": 2,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-trailing-spaces": 2,
"no-undef-init": 2,
"no-underscore-dangle": 2,
"no-unused-expressions": 2,
"no-use-before-define": 2,
"no-with": 2,
"camelcase": 2,
"comma-spacing": 2,
"consistent-return": 2,
"curly": [2, "all"],
"dot-notation": [2, { "allowKeywords": true }],
"eol-last": 2,
"no-extra-parens": [2, "functions"],
"eqeqeq": 2,
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"new-cap": 2,
"new-parens": 2,
"quotes": [2, "double"],
"semi": 2,
"semi-spacing": [2, { "before": false, "after": true }],
"space-infix-ops": 2,
"space-return-throw-case": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"strict": [2, "function"],
"yoda": [2, "never"]
}
}
```
## Removed Rules
Over the past several releases, we have been deprecating rules and introducing new rules to take their place. The following is a list of the removed rules and their replacements:
- [generator-star](../rules/generator-star) is replaced by [generator-star-spacing](../rules/generator-star-spacing)
- [global-strict](../rules/global-strict) is replaced by [strict](../rules/strict)
- [no-comma-dangle](../rules/no-comma-dangle) is replaced by [comma-dangle](../rules/comma-dangle)
- [no-empty-class](../rules/no-empty-class) is replaced by [no-empty-character-class](../rules/no-empty-character-class)
- [no-extra-strict](../rules/no-extra-strict) is replaced by [strict](../rules/strict)
- [no-reserved-keys](../rules/no-reserved-keys) is replaced by [quote-props](../rules/quote-props)
- [no-space-before-semi](../rules/no-space-before-semi) is replaced by [semi-spacing](../rules/semi-spacing)
- [no-wrap-func](../rules/no-wrap-func) is replaced by [no-extra-parens](../rules/no-extra-parens)
- [space-after-function-name](../rules/space-after-function-name) is replaced by [space-before-function-paren](../rules/space-before-function-paren)
- [space-before-function-parentheses](../rules/space-before-function-parentheses) is replaced by [space-before-function-paren](../rules/space-before-function-paren)
- [space-in-brackets](../rules/space-in-brackets) is replaced by[object-curly-spacing](../rules/object-curly-spacing) and [array-bracket-spacing](../rules/array-bracket-spacing)
- [space-unary-word-ops](../rules/space-unary-word-ops) is replaced by [space-unary-ops](../rules/space-unary-ops)
- [spaced-line-comment](../rules/spaced-line-comment) is replaced by [spaced-comment](../rules/spaced-comment)
**To address:** You'll need to update your rule configurations to use the new rules. ESLint v1.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process.
## Column Numbers are 1-based
From the beginning, ESLint has reported errors using 0-based columns because that's what Esprima, and later Espree, reported. However, most tools and editors use 1-based columns, which made for some tricky integrations with ESLint. In v1.0.0, we've switched over to reporting errors using 1-based columns to fall into line with the tools developers use everyday.
**To address:** If you've created an editor integration, or a tool that had to correct the column number, you'll need to update to just pass through the column number from ESLint. Otherwise, no change is necessary.
## No Longer Exporting cli
In 0.x, the `cli` object was exported for use by external tools. It was later deprecated in favor of `CLIEngine`. In v1.0.0, we are no longer exporting `cli` as it should not be used by external tools. This will break existing tools that make use of it.
**To address:** If you are using the exported `cli` object, switch to using `CLIEngine` instead.
## Deprecating eslint-tester
The `eslint-tester` module, which has long been the primary tester for ESLint rules, has now been moved into the `eslint` module. This was the result of a difficult relationship between these two modules that created circular dependencies and was causing a lot of problems in rule tests. Moving the tester into the `eslint` module fixed a lot of those issues.
The replacement for `eslint-tester` is called `RuleTester`. It's a simplified version of `ESLintTester` that's designed to work with any testing framework. This object is exposed by the package.
**To address:** Convert all of your rule tests to use `RuleTester`. If you have this as a test using `ESLintTester`:
```js
var eslint = require("../../../lib/eslint"),
ESLintTester = require("eslint-tester");
var eslintTester = new ESLintTester(eslint);
eslintTester.addRuleTest("lib/rules/your-rule", {
valid: [],
invalid: [],
});
```
Then you can change to:
```js
var rule = require("../../../lib/rules/your-rule"),
RuleTester = require("eslint").RuleTester;
var ruleTester = new RuleTester();
ruleTester.run("your-rule", rule, {
valid: [],
invalid: [],
});
```
---
---
title: Migrating to v2.0.0
---
ESLint v2.0.0 is the second major version release. As a result, there are some significant changes between how ESLint worked during its life in 0.x and 1.x and how it will work going forward. These changes are the direct result of feedback from the ESLint community of users and were not made without due consideration for the upgrade path. We believe that these changes make ESLint even better, and while some work is necessary to upgrade, we hope the pain of this upgrade is small enough that you will see the benefit of upgrading.
**Important:** If you are upgrading from 0.x, please refer to [Migrating to 1.0.0](./migrating-to-1.0.0) as your starting point.
## Rule Schema Changes
Due to a quirk in the way rule schemas worked, it was possible that you'd need to account for the rule severity (0, 1, or 2) in a rule schema if the options were sufficiently complex. That would result in a schema such as:
```js
module.exports = {
type: "array",
items: [
{
enum: [0, 1, 2],
},
{
enum: ["always", "never"],
},
],
minItems: 1,
maxItems: 2,
};
```
This was confusing to rule developers as it seemed that rules shouldn't be in charge of validating their own severity. In 2.0.0, rules no longer need to check their own severity.
**To address:** If you are exporting a rule schema that checks severity, you need to make several changes:
1. Remove the severity from the schema
1. Adjust `minItems` from 1 to 0
1. Adjust `maxItems` by subtracting 1
Here's what the schema from above looks like when properly converted:
```js
module.exports = {
type: "array",
items: [
{
enum: ["always", "never"],
},
],
minItems: 0,
maxItems: 1,
};
```
## Removed Rules
The following rules have been deprecated with new rules created to take their place. The following is a list of the removed rules and their replacements:
- [no-arrow-condition](../rules/no-arrow-condition) is replaced by a combination of [no-confusing-arrow](../rules/no-confusing-arrow) and [no-constant-condition](../rules/no-constant-condition). Turn on both of these rules to get the same functionality as `no-arrow-condition`.
- [no-empty-label](../rules/no-empty-label) is replaced by [no-labels](../rules/no-labels) with `{"allowLoop": true, "allowSwitch": true}` option.
- [space-after-keywords](../rules/space-after-keywords) is replaced by [keyword-spacing](../rules/keyword-spacing).
- [space-before-keywords](../rules/space-before-keywords) is replaced by [keyword-spacing](../rules/keyword-spacing).
- [space-return-throw-case](../rules/space-return-throw-case) is replaced by [keyword-spacing](../rules/keyword-spacing).
**To address:** You'll need to update your rule configurations to use the new rules. ESLint v2.0.0 will also warn you when you're using a rule that has been removed and will suggest the replacement rules. Hopefully, this will result in few surprises during the upgrade process.
## Configuration Cascading Changes
Prior to 2.0.0, if a directory contained both an `.eslintrc` file and a `package.json` file with ESLint configuration information, the settings from the two files would be merged together. In 2.0.0, only the settings from the `.eslintrc.*` file are used and the ones in `package.json` are ignored when both are present. Otherwise, `package.json` can still be used with ESLint configuration, but only if no other `.eslintrc.*` files are present.
**To address:** If you have both an `.eslintrc.*` and `package.json` with ESLint configuration information in the same directory, combine your configurations into just one of those files.
## Built-In Global Variables
Prior to 2.0.0, new global variables that were standardized as part of ES6 such as `Promise`, `Map`, `Set`, and `Symbol` were included in the built-in global environment. This could lead to potential issues when, for example, `no-undef` permitted use of the `Promise` constructor even in ES5 code where promises are unavailable. In 2.0.0, the built-in environment only includes the standard ES5 global variables, and the new ES6 global variables have been moved to the `es6` environment.
**To address:** If you are writing ES6 code, enable the `es6` environment if you have not already done so:
```js
// In your .eslintrc
{
env: {
es6: true;
}
}
// Or in a configuration comment
/*eslint-env es6*/
```
## Language Options
Prior to 2.0.0, the way to enable language options was by using `ecmaFeatures` in your configuration. In 2.0.0:
- The `ecmaFeatures` property is now under a top-level `parserOptions` property.
- All ECMAScript 6 `ecmaFeatures` flags have been removed in favor of a `ecmaVersion` property under `parserOptions` that can be set to 3, 5 (default), or 6.
- The `ecmaFeatures.modules` flag has been replaced by a `sourceType` property under `parserOptions` which can be set to `"script"` (default) or `"module"` for ES6 modules.
**To address:** If you are using any ECMAScript 6 feature flags in `ecmaFeatures`, you'll need to use `ecmaVersion: 6` instead. The ECMAScript 6 feature flags are:
- `arrowFunctions` - enable [arrow functions](https://leanpub.com/understandinges6/read#leanpub-auto-arrow-functions)
- `binaryLiterals` - enable [binary literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals)
- `blockBindings` - enable `let` and `const` (aka [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings))
- `classes` - enable classes
- `defaultParams` - enable [default function parameters](https://leanpub.com/understandinges6/read/#leanpub-auto-default-parameters)
- `destructuring` - enable [destructuring](https://leanpub.com/understandinges6/read#leanpub-auto-destructuring-assignment)
- `forOf` - enable [`for-of` loops](https://leanpub.com/understandinges6/read#leanpub-auto-iterables-and-for-of)
- `generators` - enable [generators](https://leanpub.com/understandinges6/read#leanpub-auto-generators)
- `modules` - enable modules and global strict mode
- `objectLiteralComputedProperties` - enable [computed object literal property names](https://leanpub.com/understandinges6/read#leanpub-auto-computed-property-names)
- `objectLiteralDuplicateProperties` - enable [duplicate object literal properties](https://leanpub.com/understandinges6/read#leanpub-auto-duplicate-object-literal-properties) in strict mode
- `objectLiteralShorthandMethods` - enable [object literal shorthand methods](https://leanpub.com/understandinges6/read#leanpub-auto-method-initializer-shorthand)
- `objectLiteralShorthandProperties` - enable [object literal shorthand properties](https://leanpub.com/understandinges6/read#leanpub-auto-property-initializer-shorthand)
- `octalLiterals` - enable [octal literals](https://leanpub.com/understandinges6/read#leanpub-auto-octal-and-binary-literals)
- `regexUFlag` - enable the [regular expression `u` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-u-flag)
- `regexYFlag` - enable the [regular expression `y` flag](https://leanpub.com/understandinges6/read#leanpub-auto-the-regular-expression-y-flag)
- `restParams` - enable the [rest parameters](https://leanpub.com/understandinges6/read#leanpub-auto-rest-parameters)
- `spread` - enable the [spread operator](https://leanpub.com/understandinges6/read#leanpub-auto-the-spread-operator) for arrays
- `superInFunctions` - enable `super` references inside of functions
- `templateStrings` - enable [template strings](https://leanpub.com/understandinges6/read/#leanpub-auto-template-strings)
- `unicodeCodePointEscapes` - enable [code point escapes](https://leanpub.com/understandinges6/read/#leanpub-auto-escaping-non-bmp-characters)
If you're using any of these flags, such as:
```js
{
ecmaFeatures: {
arrowFunctions: true;
}
}
```
Then you should enable ES6 using `ecmaVersion`:
```js
{
parserOptions: {
ecmaVersion: 6;
}
}
```
If you're using any non-ES6 flags in `ecmaFeatures`, you need to move those inside of `parserOptions`. For instance:
```js
{
ecmaFeatures: {
jsx: true;
}
}
```
Then you should move `ecmaFeatures` under `parserOptions`:
```js
{
parserOptions: {
ecmaFeatures: {
jsx: true;
}
}
}
```
If you were using `ecmaFeatures.modules` to enable ES6 module support like this:
```js
{
ecmaFeatures: {
modules: true;
}
}
```
```js
{
parserOptions: {
sourceType: "module";
}
}
```
Additionally, if you are using `context.ecmaFeatures` inside of your rules, then you'll need to update your code in the following ways:
1. If you're using an ES6 feature flag such as `context.ecmaFeatures.blockBindings`, rewrite to check for `context.parserOptions.ecmaVersion > 5`.
1. If you're using `context.ecmaFeatures.modules`, rewrite to check that the `sourceType` property of the Program node is `"module"`.
1. If you're using a non-ES6 feature flag such as `context.ecmaFeatures.jsx`, rewrite to check for `context.parserOptions.ecmaFeatures.jsx`.
If you have a plugin with rules and you are using RuleTester, then you also need to update the options you pass for rules that use `ecmaFeatures`. For example:
```js
var ruleTester = new RuleTester();
ruleTester.run("no-var", rule, {
valid: [
{
code: "let x;",
parserOptions: { ecmaVersion: 6 },
},
],
});
```
If you're not using `ecmaFeatures` in your configuration or your custom/plugin rules and tests, then no change is needed.
## New Rules in `"eslint:recommended"`
```json
{
"extends": "eslint:recommended"
}
```
In 2.0.0, the following 11 rules were added to `"eslint:recommended"`.
- [constructor-super](../rules/constructor-super)
- [no-case-declarations](../rules/no-case-declarations)
- [no-class-assign](../rules/no-class-assign)
- [no-const-assign](../rules/no-const-assign)
- [no-dupe-class-members](../rules/no-dupe-class-members)
- [no-empty-pattern](../rules/no-empty-pattern)
- [no-new-symbol](../rules/no-new-symbol)
- [no-self-assign](../rules/no-self-assign)
- [no-this-before-super](../rules/no-this-before-super)
- [no-unexpected-multiline](../rules/no-unexpected-multiline)
- [no-unused-labels](../rules/no-unused-labels)
**To address:** If you don't want to be notified by those rules, you can simply disable those rules.
```json
{
"extends": "eslint:recommended",
"rules": {
"no-case-declarations": 0,
"no-class-assign": 0,
"no-const-assign": 0,
"no-dupe-class-members": 0,
"no-empty-pattern": 0,
"no-new-symbol": 0,
"no-self-assign": 0,
"no-this-before-super": 0,
"no-unexpected-multiline": 0,
"no-unused-labels": 0,
"constructor-super": 0
}
}
```
## Scope Analysis Changes
We found some bugs in our scope analysis that needed to be addressed. Specifically, we were not properly accounting for global variables in all the ways they are defined.
Originally, `Variable` objects and `Reference` objects refer each other:
- `Variable#references` property is an array of `Reference` objects which are referencing the variable.
- `Reference#resolved` property is a `Variable` object which are referenced.
But until 1.x, the following variables and references had the wrong value (empty) in those properties:
- `var` declarations in the global.
- `function` declarations in the global.
- Variables defined in config files.
- Variables defined in `/* global */` comments.
Now, those variables and references have correct values in these properties.
`Scope#through` property has references where `Reference#resolved` is `null`. So as a result of this change, the value of `Scope#through` property was changed also.
**To address:** If you are using `Scope#through` to find references of a built-in global variable, you need to make several changes.
For example, this is how you might locate the `window` global variable in 1.x:
```js
var globalScope = context.getScope();
globalScope.through.forEach(function (reference) {
if (reference.identifier.name === "window") {
checkForWindow(reference);
}
});
```
This was a roundabout way to find the variable because it was added after the fact by ESLint. The `window` variable was in `Scope#through` because the definition couldn't be found.
In 2.0.0, `window` is no longer located in `Scope#through` because we have added back the correct declaration. That means you can reference the `window` object (or any other global object) directly. So the previous example would change to this:
```js
var globalScope = context.getScope();
var variable = globalScope.set.get("window");
if (variable) {
variable.references.forEach(checkForWindow);
}
```
Further Reading:
## Default Changes When Using `eslint:recommended`
This will affect you if you are extending from `eslint:recommended`, and are enabling [`no-multiple-empty-lines`] or [`func-style`] with only a severity, such as:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-multiple-empty-lines": 2,
"func-style": 2
}
}
```
The rule `no-multiple-empty-lines` has no default exceptions, but in ESLint `1.x`, a default from `eslint:recommended` was applied such that a maximum of two empty lines would be permitted.
The rule `func-style` has a default configuration of `"expression"`, but in ESLint `1.x`, `eslint:recommended` defaulted it to `"declaration"`.
ESLint 2.0.0 removes these conflicting defaults, and so you may begin seeing linting errors related to these rules.
**To address:** If you would like to maintain the previous behavior, update your configuration for `no-multiple-empty-lines` by adding `{"max": 2}`, and change `func-style` to `"declaration"`. For example:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-multiple-empty-lines": [2, { "max": 2 }],
"func-style": [2, "declaration"]
}
}
```
[`no-multiple-empty-lines`]: ../rules/no-multiple-empty-lines
[`func-style`]: ../rules/func-style
## SourceCode constructor (Node API) changes
`SourceCode` constructor got to handle Unicode BOM.
If the first argument `text` has BOM, `SourceCode` constructor sets `true` to `this.hasBOM` and strips BOM from the text.
```js
var SourceCode = require("eslint").SourceCode;
var code = new SourceCode("\uFEFFvar foo = bar;", ast);
assert(code.hasBOM === true);
assert(code.text === "var foo = bar;");
```
So the second argument `ast` also should be parsed from stripped text.
**To address:** If you are using `SourceCode` constructor in your code, please parse the source code after it stripped BOM:
```js
var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options);
var sourceCode = new SourceCode(text, ast);
```
## Rule Changes
- [`strict`](../rules/strict) - defaults to `"safe"` (previous default was `"function"`)
## Plugins No Longer Have Default Configurations
Prior to v2.0.0, plugins could specify a `rulesConfig` for the plugin. The `rulesConfig` would automatically be applied whenever someone uses the plugin, which is the opposite of what ESLint does in every other situation (where nothing is on by default). To bring plugins behavior in line, we have removed support for `rulesConfig` in plugins.
**To address:** If you are using a plugin in your configuration file, you will need to manually enable the plugin rules in the configuration file.
---
---
title: Migrating to v3.0.0
---
ESLint v3.0.0 is the third major version release. We have made several breaking changes in this release, however, we believe the changes to be small enough that they should not require significant changes for ESLint users. This guide is intended to walk you through the changes.
## Dropping Support for Node.js < 4
With ESLint v3.0.0, we are dropping support for Node.js versions prior to 4. Node.js 0.10 and 0.12 are in [maintenance mode](https://github.com/nodejs/Release) and Node.js 4 is the current LTS version. If you are using an older version of Node.js, we recommend upgrading to at least Node.js 4 as soon as possible. If you are unable to upgrade to Node.js 4 or higher, then we recommend continuing to use ESLint v2.x until you are ready to upgrade Node.js.
**Important:** We will not be updating the ESLint v2.x versions going forward. All bug fixes and enhancements will land in ESLint v3.x.
## Requiring Configuration to Run
ESLint v3.0.0 now requires that you use a configuration to run. A configuration can be any of the following:
1. An `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc.yaml`, or `.eslintrc` file either in your project or home directory.
2. Configuration options passed on the command line using `--rule` (or to CLIEngine using `rules`).
3. A configuration file passed on the command line using `-c` (or to CLIEngine using `configFile`).
4. A base configuration is provided to CLIEngine using the `baseConfig` option.
If ESLint can't find a configuration, then it will throw an error and ask you to provide one.
This change was made to help new ESLint users who are frequently confused that ESLint does nothing by default besides reporting parser errors. We anticipate this change will have minimal impact on most established users because you're more likely to have configuration files already.
**To Address:** You should be sure to use a configuration whenever you run ESLint. However, you can still run ESLint without a configuration by passing the `--no-eslintrc` option on the command line or setting the `useEslintrc` option to `false` for `CLIEngine`.
To create a new configuration, use `eslint --init`.
## Changes to `"eslint:recommended"`
```json
{
"extends": "eslint:recommended"
}
```
In 3.0.0, the following rules were added to `"eslint:recommended"`:
- [`no-unsafe-finally`](../rules/no-unsafe-finally) helps catch `finally` clauses that may not behave as you think.
- [`no-native-reassign`](../rules/no-native-reassign) was previously part of `no-undef`, but was split out because it didn't make sense as part of another rule. The `no-native-reassign` rule warns whenever you try to overwrite a read-only global variable.
- [`require-yield`](../rules/require-yield) helps to identify generator functions that do not have the `yield` keyword.
The following rules were removed from `"eslint:recommended"`:
- [`comma-dangle`](../rules/comma-dangle) used to be recommended because Internet Explorer 8 and earlier threw a syntax error when it found a dangling comma on object literal properties. However, [Internet Explorer 8 was end-of-lifed](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support) in January 2016 and all other active browsers allow dangling commas. As such, we consider dangling commas to now be a stylistic issue instead of a possible error.
The following rules were modified:
- [`complexity`](../rules/complexity) used to have a hardcoded default of 11 in `eslint:recommended` that would be used if you turned the rule on without specifying a maximum. The default is now 20. The rule actually always had a default of 20, but `eslint:recommended` was overriding it by mistake.
**To address:** If you want to mimic how `eslint:recommended` worked in v2.x, you can use the following:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-unsafe-finally": "off",
"no-native-reassign": "off",
"complexity": ["off", 11],
"comma-dangle": "error",
"require-yield": "error"
}
}
```
## Changes to `CLIEngine#executeOnText()`
The `CLIEngine#executeOnText()` method has changed to work more like `CLIEngine#executeOnFiles()`. In v2.x, `CLIEngine#executeOnText()` warned about ignored files by default and didn't have a way to opt-out of those warnings whereas `CLIEngine#executeOnFiles()` did not warn about ignored files by default and allowed you to opt-in to warning about them. The `CLIEngine#executeOnText()` method now also does not warn about ignored files by default and allows you to opt-in with a new, third argument (a boolean, `true` to warn about ignored files and `false` to not warn).
**To address:** If you are currently using `CLIEngine#executeOnText()` in your project like this:
```js
var result = engine.executeOnText(text, filename);
```
You can get the equivalent behavior using this:
```js
var result = engine.executeOnText(text, filename, true);
```
If you do not want ignored file warnings output to the console, you can omit the third argument or pass `false`.
---
---
title: Migrating to v4.0.0
---
ESLint v4.0.0 is the fourth major version release. We have made several breaking changes in this release; however, we expect that most of the changes will only affect a very small percentage of users. This guide is intended to walk you through the changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Breaking changes for users
1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes)
1. [The `indent` rule is more strict](#indent-rewrite)
1. [Unrecognized properties in config files now cause a fatal error](#config-validation)
1. [.eslintignore patterns are now resolved from the location of the file](#eslintignore-patterns)
1. [The `padded-blocks` rule is more strict by default](#padded-blocks-defaults)
1. [The `space-before-function-paren` rule is more strict by default](#space-before-function-paren-defaults)
1. [The `no-multi-spaces` rule is more strict by default](#no-multi-spaces-eol-comments)
1. [References to scoped plugins in config files are now required to include the scope](#scoped-plugin-resolution)
## Breaking changes for plugin/custom rule developers
1. [`RuleTester` now validates properties of test cases](#rule-tester-validation)
1. [AST nodes no longer have comment properties](#comment-attachment)
1. [`LineComment` and `BlockComment` events will no longer be emitted during AST traversal](#event-comments)
1. [Shebangs are now returned from comment APIs](#shebangs)
## Breaking changes for integration developers
1. [The `global` property in the `linter.verify()` API is no longer supported](#global-property)
1. [More report messages now have full location ranges](#report-locations)
1. [Some exposed APIs are now ES2015 classes](#exposed-es2015-classes)
---
## `eslint:recommended` changes
Two new rules have been added to the [`eslint:recommended`](configure#using-eslintrecommended) config:
- [`no-compare-neg-zero`](../rules/no-compare-neg-zero) disallows comparisons to `-0`
- [`no-useless-escape`](../rules/no-useless-escape) disallows uselessly-escaped characters in strings and regular expressions
**To address:** To mimic the `eslint:recommended` behavior from 3.x, you can disable these rules in a config file:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-compare-neg-zero": "off",
"no-useless-escape": "off"
}
}
```
## The `indent` rule is more strict
Previously, the [`indent`](../rules/indent) rule was fairly lenient about checking indentation; there were many code patterns where indentation was not validated by the rule. This caused confusion for users, because they were accidentally writing code with incorrect indentation, and they expected ESLint to catch the issues.
In 4.0.0, the `indent` rule has been rewritten. The new version of the rule will report some indentation errors that the old version of the rule did not catch. Additionally, the indentation of `MemberExpression` nodes, function parameters, and function arguments will now be checked by default (it was previously ignored by default for backwards compatibility).
To make the upgrade process easier, we've introduced the [`indent-legacy`](../rules/indent-legacy) rule as a snapshot of the `indent` rule from 3.x. If you run into issues from the `indent` rule when you upgrade, you should be able to use the `indent-legacy` rule to replicate the 3.x behavior. However, the `indent-legacy` rule is deprecated and will not receive bugfixes or improvements in the future, so you should eventually switch back to the `indent` rule.
**To address:** We recommend upgrading without changing your `indent` configuration, and fixing any new indentation errors that appear in your codebase. However, if you want to mimic how the `indent` rule worked in 3.x, you can update your configuration:
```js
{
rules: {
indent: "off",
"indent-legacy": "error" // replace this with your previous `indent` configuration
}
}
```
## Unrecognized properties in config files now cause a fatal error
When creating a config, users sometimes make typos or misunderstand how the config is supposed to be structured. Previously, ESLint did not validate the properties of a config file, so a typo in a config could be very tedious to debug. Starting in 4.0.0, ESLint will raise an error if a property in a config file is unrecognized or has the wrong type.
**To address:** If you see a config validation error after upgrading, verify that your config doesn't contain any typos. If you are using an unrecognized property, you should be able to remove it from your config to restore the previous behavior.
## .eslintignore patterns are now resolved from the location of the file
Due to a bug, glob patterns in an `.eslintignore` file were previously resolved from the current working directory of the process, rather than the location of the `.eslintignore` file. Starting in 4.0, patterns in an `.eslintignore` file will be resolved from the `.eslintignore` file's location.
**To address:** If you use an `.eslintignore` file and you frequently run ESLint from somewhere other than the project root, it's possible that the patterns will be matched differently. You should update the patterns in the `.eslintignore` file to ensure they are relative to the file, not to the working directory.
## The `padded-blocks` rule is more strict by default
By default, the [`padded-blocks`](../rules/padded-blocks) rule will now enforce padding in class bodies and switch statements. Previously, the rule would ignore these cases unless the user opted into enforcing them.
**To address:** If this change results in more linting errors in your codebase, you should fix them or reconfigure the rule.
## The `space-before-function-paren` rule is more strict by default
By default, the [`space-before-function-paren`](../rules/space-before-function-paren) rule will now enforce spacing for async arrow functions. Previously, the rule would ignore these cases unless the user opted into enforcing them.
**To address:** To mimic the default config from 3.x, you can use:
```json
{
"rules": {
"space-before-function-paren": [
"error",
{
"anonymous": "always",
"named": "always",
"asyncArrow": "ignore"
}
]
}
}
```
## The `no-multi-spaces` rule is more strict by default
By default, the [`no-multi-spaces`](../rules/no-multi-spaces) rule will now disallow multiple spaces before comments at the end of a line. Previously, the rule did not check this case.
**To address:** To mimic the default config from 3.x, you can use:
```json
{
"rules": {
"no-multi-spaces": ["error", { "ignoreEOLComments": true }]
}
}
```
## References to scoped plugins in config files are now required to include the scope
In 3.x, there was a bug where references to scoped NPM packages as plugins in config files could omit the scope. For example, in 3.x the following config was legal:
```json
{
"plugins": ["@my-organization/foo"],
"rules": {
"foo/some-rule": "error"
}
}
```
In other words, it was possible to reference a rule from a scoped plugin (such as `foo/some-rule`) without explicitly stating the `@my-organization` scope. This was a bug because it could lead to ambiguous rule references if there was also an unscoped plugin called `eslint-plugin-foo` loaded at the same time.
To avoid this ambiguity, in 4.0 references to scoped plugins must include the scope. The config from above should be fixed to:
```json
{
"plugins": ["@my-organization/foo"],
"rules": {
"@my-organization/foo/some-rule": "error"
}
}
```
**To address:** If you reference a scoped NPM package as a plugin in a config file, be sure to include the scope wherever you reference it.
---
## `RuleTester` now validates properties of test cases
Starting in 4.0, the `RuleTester` utility will validate properties of test case objects, and an error will be thrown if an unknown property is encountered. This change was added because we found that it was relatively common for developers to make typos in rule tests, often invalidating the assertions that the test cases were trying to make.
**To address:** If your tests for custom rules have extra properties, you should remove those properties.
## AST Nodes no longer have comment properties
Prior to 4.0, ESLint required parsers to implement comment attachment, a process where AST nodes would gain additional properties corresponding to their leading and trailing comments in the source file. This made it difficult for users to develop custom parsers, because they would have to replicate the confusing comment attachment semantics required by ESLint.
In 4.0, we have moved away from the concept of comment attachment and have moved all comment handling logic into ESLint itself. This should make it easier to develop custom parsers, but it also means that AST nodes will no longer have `leadingComments` and `trailingComments` properties. Conceptually, rule authors can now think of comments in the context of tokens rather than AST nodes.
**To address:** If you have a custom rule that depends on the `leadingComments` or `trailingComments` properties of an AST node, you can now use `sourceCode.getCommentsBefore()` and `sourceCode.getCommentsAfter()` instead, respectively.
Additionally, the `sourceCode` object now also has `sourceCode.getCommentsInside()` (which returns all the comments inside a node), `sourceCode.getAllComments()` (which returns all the comments in the file), and allows comments to be accessed through various other token iterator methods (such as `getTokenBefore()` and `getTokenAfter()`) with the `{ includeComments: true }` option.
For rule authors concerned about supporting ESLint v3.0 in addition to v4.0, the now deprecated `sourceCode.getComments()` is still available and will work for both versions.
Finally, please note that the following `SourceCode` methods have been deprecated and will be removed in a future version of ESLint:
- `getComments()` - replaced by `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()`
- `getTokenOrCommentBefore()` - replaced by `getTokenBefore()` with the `{ includeComments: true }` option
- `getTokenOrCommentAfter()` - replaced by `getTokenAfter()` with the `{ includeComments: true }` option
## `LineComment` and `BlockComment` events will no longer be emitted during AST traversal
Starting in 4.0, `LineComment` and `BlockComments` events will not be emitted during AST traversal. There are two reasons for this:
- This behavior was relying on comment attachment happening at the parser level, which does not happen anymore, to ensure that all comments would be accounted for.
- Thinking of comments in the context of tokens is more predictable and easier to reason about than thinking about comment tokens in the context of AST nodes.
**To address:** Instead of relying on `LineComment` and `BlockComment`, rules can now use `sourceCode.getAllComments()` to get all comments in a file. To check all comments of a specific type, rules can use the following pattern:
```js
sourceCode.getAllComments().filter(comment => comment.type === "Line");
sourceCode.getAllComments().filter(comment => comment.type === "Block");
```
## Shebangs are now returned from comment APIs
Prior to 4.0, shebang comments in a source file would not appear in the output of `sourceCode.getAllComments()` or `sourceCode.getComments()`, but they would appear in the output of `sourceCode.getTokenOrCommentBefore` as line comments. This inconsistency led to some confusion for rule developers.
In 4.0, shebang comments are treated as comment tokens of type `Shebang` and will be returned by any `SourceCode` method that returns comments. The goal of this change is to make working with shebang comments more consistent with how other tokens are handled.
**To address:** If you have a custom rule that performs operations on comments, some additional logic might be required to ensure that shebang comments are correctly handled or filtered out:
```js
sourceCode.getAllComments().filter(comment => comment.type !== "Shebang");
```
---
## The `global` property in the `linter.verify()` API is no longer supported
Previously, the `linter.verify()` API accepted a `global` config option, which was a synonym for the documented `globals` property. The `global` option was never documented or officially supported, and did not work in config files. It has been removed in 4.0.
**To address:** If you were using the `global` property, please use the `globals` property instead, which does the same thing.
## More report messages now have full location ranges
Starting in 3.1.0, rules have been able to specify the _end_ location of a reported problem, in addition to the start location, by explicitly specifying an end location in the `report` call. This is useful for tools like editor integrations, which can use the range to precisely display where a reported problem occurs. Starting in 4.0, if a _node_ is reported rather than a location, the end location of the range will automatically be inferred from the end location of the node. As a result, many more reported problems will have end locations.
This is not expected to cause breakage. However, it will likely result in larger report locations than before. For example, if a rule reports the root node of the AST, the reported problem's range will be the entire program. In some integrations, this could result in a poor user experience (e.g. if the entire program is highlighted to indicate an error).
**To address:** If you have an integration that deals with the ranges of reported problems, make sure you handle large report ranges in a user-friendly way.
## Some exposed APIs are now ES2015 classes
The `CLIEngine`, `SourceCode`, and `RuleTester` modules from ESLint's Node.js API are now ES2015 classes. This will not break any documented behavior, but it does have some observable effects (for example, the methods on `CLIEngine.prototype` are now non-enumerable).
**To address:** If you rely on enumerating the methods of ESLint's Node.js APIs, use a function that can also access non-enumerable properties such as `Object.getOwnPropertyNames`.
---
---
title: Migrating to v5.0.0
---
ESLint v5.0.0 is the fifth major version release. We have made a few breaking changes in this release, but we expect that most users will be able to upgrade without any modifications to their build. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Breaking changes for users
1. [Node.js 4 is no longer supported](#drop-node-4)
1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes)
1. [The `experimentalObjectRestSpread` option has been deprecated](#experimental-object-rest-spread)
1. [Linting nonexistent files from the command line is now a fatal error](#nonexistent-files)
1. [The default options for some rules have changed](#rule-default-changes)
1. [Deprecated globals have been removed from the `node`, `browser`, and `jest` environments](#deprecated-globals)
1. [Empty files are now linted](#empty-files)
1. [Plugins in scoped packages are now resolvable in configs](#scoped-plugins)
1. [Multi-line `eslint-disable-line` directives are now reported as problems](#multiline-directives)
## Breaking changes for plugin/custom rule developers
1. [The `parent` property of AST nodes is now set before rules start running](#parent-before-rules)
1. [When using the default parser, spread operators now have type `SpreadElement`](#spread-operators)
1. [When using the default parser, rest operators now have type `RestElement`](#rest-operators)
1. [When using the default parser, text nodes in JSX elements now have type `JSXText`](#jsx-text-nodes)
1. [The `context.getScope()` method now returns more proper scopes](#context-get-scope)
1. [The `_linter` property on rule context objects has been removed](#no-context-linter)
1. [`RuleTester` now uses strict equality checks in its assertions](#rule-tester-equality)
1. [Rules are now required to provide messages along with reports](#required-report-messages)
## Breaking changes for integration developers
1. [The `source` property is no longer available on individual linting messages](#source-property)
1. [Fatal errors now result in an exit code of 2](#exit-code-two)
1. [The `eslint.linter` property is now non-enumerable](#non-enumerable-linter)
---
## Node.js 4 is no longer supported
As of April 30th, 2018, Node.js 4 will be at EOL and will no longer be receiving security updates. As a result, we have decided to drop support for it in ESLint v5. We now support the following versions of Node.js:
- Node.js 6 (6.14.0 and above)
- Node.js 8 (8.10.0 and above)
- Anything above Node.js 9.10.0
**To address:** Make sure you upgrade to at least Node.js 6 when using ESLint v5. If you are unable to upgrade, we recommend continuing to use ESLint v4.x until you are able to upgrade Node.js.
## `eslint:recommended` changes
Two new rules have been added to the [`eslint:recommended`](configure/configuration-files#using-eslintrecommended) config:
- [`for-direction`](../rules/for-direction) enforces that a `for` loop update clause moves the counter in the right direction.
- [`getter-return`](../rules/getter-return) enforces that a `return` statement is present in property getters.
**To address:** To mimic the `eslint:recommended` behavior from 4.x, you can disable these rules in a config file:
```json
{
"extends": "eslint:recommended",
"rules": {
"for-direction": "off",
"getter-return": "off"
}
}
```
## The `experimentalObjectRestSpread` option has been deprecated
Previously, when using the default parser it was possible to use the `experimentalObjectRestSpread` option to enable support for [rest/spread properties](https://developers.google.com/web/updates/2017/06/object-rest-spread), as follows:
```json
{
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
}
}
```
Object rest/spread is now an official part of the JavaScript language, so our support for it is no longer experimental. In both ESLint v4 and ESLint v5, object rest/spread can now be enabled with the `"ecmaVersion": 2018` option:
```json
{
"parserOptions": {
"ecmaVersion": 2018
}
}
```
Note that this also enables parsing for other features from ES2018, such as [async iteration](https://github.com/tc39/proposal-async-iteration). When using ESLint v5 with the default parser, it is no longer possible to toggle syntax support for object rest/spread independently of other features.
For compatibility, ESLint v5 will treat `ecmaFeatures: { experimentalObjectRestSpread: true }` as an alias for `ecmaVersion: 2018` when the former is found in a config file. As a result, if you use object rest/spread, your code should still parse successfully with ESLint v5. However, note that this alias will be removed in ESLint v6.
**To address:** If you use the `experimentalObjectRestSpread` option, you should be able to upgrade to ESLint v5 without any changes, but you will encounter a deprecation warning. To avoid the warning, use `ecmaVersion: 2018` in your config file rather than `ecmaFeatures: { experimentalObjectRestSpread: true }`. If you would like to disallow the use of other ES2018 features, consider using rules such as [`no-restricted-syntax`](../rules/no-restricted-syntax).
## Linting nonexistent files from the command line is now a fatal error
Previous versions of ESLint silently ignored any nonexistent files and globs provided on the command line:
```bash
eslint nonexistent-file.js 'nonexistent-folder/**/*.js' # exits without any errors in ESLint v4
```
Many users found this behavior confusing, because if they made a typo in a filename, ESLint would appear to lint that file successfully while actually not linting anything.
ESLint v5 will report a fatal error when either of the following conditions is met:
- A file provided on the command line does not exist.
- A glob or folder provided on the command line does not match any lintable files.
Note that this also affects the [`CLIEngine.executeOnFiles()`](../integrate/nodejs-api#cliengineexecuteonfiles) API.
**To address:** If you encounter an error about missing files after upgrading to ESLint v5, you may want to double-check that there are no typos in the paths you provide to ESLint. To make the error go away, you can simply remove the given files or globs from the list of arguments provided to ESLint on the command line.
If you use a boilerplate generator that relies on this behavior (e.g. to generate a script that runs `eslint tests/` in a new project before any test files are actually present), you can work around this issue by adding a dummy file that matches the given pattern (e.g. an empty `tests/index.js` file).
## The default options for some rules have changed
- The default options for the [`object-curly-newline`](../rules/object-curly-newline) rule have changed from `{ multiline: true }` to `{ consistent: true }`.
- The default options object for the [`no-self-assign`](../rules/no-self-assign) rule has changed from `{ props: false }` to `{ props: true }`.
**To address:** To restore the rule behavior from ESLint v4, you can update your config file to include the previous options:
```json
{
"rules": {
"object-curly-newline": ["error", { "multiline": true }],
"no-self-assign": ["error", { "props": false }]
}
}
```
## Deprecated globals have been removed from the `node`, `browser`, and `jest` environments
Some global variables have been deprecated or removed for code running in Node.js, browsers, and Jest. (For example, browsers used to expose an `SVGAltGlyphElement` global variable to JavaScript code, but this global has been removed from web standards and is no longer present in browsers.) As a result, we have removed these globals from the corresponding `eslint` environments, so use of these globals will trigger an error when using rules such as [`no-undef`](../rules/no-undef).
**To address:** If you use deprecated globals in the `node`, `browser`, or `jest` environments, you can add a `globals` section to your configuration to re-enable any globals you need. For example:
```json
{
"env": {
"browser": true
},
"globals": {
"SVGAltGlyphElement": false
}
}
```
## Empty files are now linted
ESLint v4 had a special behavior when linting files that only contain whitespace: it would skip running the parser and rules, and it would always return zero errors. This led to some confusion for users and rule authors, particularly when writing tests for rules. (When writing a stylistic rule, rule authors would occasionally write a test where the source code only contained whitespace, to ensure that the rule behaved correctly when no applicable code was found. However, a test like this would actually not run the rule at all, so an aspect of the rule would end up untested.)
ESLint v5 treats whitespace-only files the same way as all other files: it parses them and runs enabled rules on them as appropriate. This could lead to additional linting problems if you use a custom rule that reports errors on empty files.
**To address:** If you have an empty file in your project and you don't want it to be linted, consider adding it to an [`.eslintignore` file](configure/ignore).
If you have a custom rule, you should make sure it handles empty files appropriately. (In most cases, no changes should be necessary.)
## Plugins in scoped packages are now resolvable in configs
When ESLint v5 encounters a plugin name in a config starting with `@`, the plugin will be resolved as a [scoped npm package](https://docs.npmjs.com/misc/scope). For example, if a config contains `"plugins": ["@foo"]`, ESLint v5 will attempt to load a package called `@foo/eslint-plugin`. (On the other hand, ESLint v4 would attempt to load a package called `eslint-plugin-@foo`.) This is a breaking change because users might have been relying on ESLint finding a package at `node_modules/eslint-plugin-@foo`. However, we think it is unlikely that many users were relying on this behavior, because packages published to npm cannot contain an `@` character in the middle.
**To address:** If you rely on ESLint loading a package like `eslint-config-@foo`, consider renaming the package to something else.
## Multi-line `eslint-disable-line` directives are now reported as problems
`eslint-disable-line` and `eslint-disable-next-line` directive comments are only allowed to span a single line. For example, the following directive comment is invalid:
```js
alert("foo");
/* eslint-disable-line
no-alert */ alert("bar");
// (which line is the rule disabled on?)
```
Previously, ESLint would ignore these malformed directive comments. ESLint v5 will report an error when it sees a problem like this, so that the issue can be more easily corrected.
**To address:** If you see new reported errors as a result of this change, ensure that your `eslint-disable-line` directives only span a single line. Note that "block comments" (delimited by `/* */`) are still allowed to be used for directives, provided that the block comments do not contain linebreaks.
---
## The `parent` property of AST nodes is now set before rules start running
Previously, ESLint would set the `parent` property on each AST node immediately before running rule listeners for that node. This caused some confusion for rule authors, because the `parent` property would not initially be present on any nodes, and it was sometimes necessary to complicate the structure of a rule to ensure that the `parent` property of a given node would be available when needed.
In ESLint v5, the `parent` property is set on all AST nodes before any rules have access to the AST. This makes it easier to write some rules, because the `parent` property is always available rather than being mutated behind the scenes. However, as a side-effect of having `parent` properties, the AST object has a circular structure the first time a rule sees it (previously, it only had a circular structure after the first rule listeners were called). As a result, a custom rule that enumerates all properties of a node in order to traverse the AST might now loop forever or run out of memory if it does not check for cycles properly.
**To address:** If you have written a custom rule that enumerates all properties of an AST node, consider excluding the `parent` property or implementing cycle detection to ensure that you obtain the correct result.
## When using the default parser, spread operators now have type `SpreadElement`
Previously, when parsing JS code like `const foo = {...data}` with the `experimentalObjectRestSpread` option enabled, the default parser would generate an `ExperimentalSpreadProperty` node type for the `...data` spread element.
In ESLint v5, the default parser will now always give the `...data` AST node the `SpreadElement` type, even if the (now deprecated) [`experimentalObjectRestSpread`](#experimental-object-rest-spread) option is enabled. This makes the AST compliant with the current ESTree spec.
**To address:** If you have written a custom rule that relies on spread operators having the `ExperimentalSpreadProperty` type, you should update it to also work with spread operators that have the `SpreadElement` type.
## When using the default parser, rest operators now have type `RestElement`
Previously, when parsing JS code like `const {foo, ...rest} = data` with the `experimentalObjectRestSpread` option enabled, the default parser would generate an `ExperimentalRestProperty` node type for the `...data` rest element.
In ESLint v5, the default parser will now always give the `...data` AST node the `RestElement` type, even if the (now deprecated) [`experimentalObjectRestSpread`](#experimental-object-rest-spread) option is enabled. This makes the AST compliant with the current ESTree spec.
**To address:** If you have written a custom rule that relies on rest operators having the `ExperimentalRestProperty` type, you should update it to also work with rest operators that have the `RestElement` type.
## When using the default parser, text nodes in JSX elements now have type `JSXText`
When parsing JSX code like `foo`, the default parser will now give the `foo` AST node the `JSXText` type, rather than the `Literal` type. This makes the AST compliant with a recent update to the JSX spec.
**To address:** If you have written a custom rule that relies on text nodes in JSX elements having the `Literal` type, you should update it to also work with nodes that have the `JSXText` type.
## The `context.getScope()` method now returns more proper scopes
Previously, the `context.getScope()` method changed its behavior based on the `parserOptions.ecmaVersion` property. However, this could cause confusing behavior when using a parser that doesn't respond to the `ecmaVersion` option, such as `babel-eslint`.
Additionally, `context.getScope()` incorrectly returned the parent scope of the proper scope on `CatchClause` (in ES5), `ForStatement` (in ≧ES2015), `ForInStatement` (in ≧ES2015), `ForOfStatement`, and `WithStatement` nodes.
In ESLint v5, the `context.getScope()` method has the same behavior regardless of `parserOptions.ecmaVersion` and returns the proper scope. See [the documentation](../extend/scope-manager-interface) for more details on which scopes are returned.
**To address:** If you have written a custom rule that uses the `context.getScope()` method in node handlers, you may need to update it to account for the modified scope information.
## The `_linter` property on rule context objects has been removed
Previously, rule context objects had an undocumented `_linter` property, which was used internally within ESLint to process reports from rules. Some rules used this property to achieve functionality that was not intended to be possible for rules. For example, several plugins used the `_linter` property in a rule to monitor reports from other rules, for the purpose of checking for unused `/* eslint-disable */` directive comments. Although this functionality was useful for users, it could also cause stability problems for projects using ESLint. For example, an upgrade to a rule in one plugin could unexpectedly cause a rule in another plugin to start reporting errors.
The `_linter` property has been removed in ESLint v5.0, so it is no longer possible to implement rules with this functionality. However, the [`--report-unused-disable-directives`](command-line-interface#--report-unused-disable-directives) CLI flag can be used to flag unused directive comments.
## `RuleTester` now uses strict equality checks in its assertions
Previously, `RuleTester` used loose equality when making some of its assertions. For example, if a rule produced the string `"7"` as a result of autofixing, `RuleTester` would allow the number `7` in an `output` assertion, rather than the string `"7"`. In ESLint v5, comparisons from `RuleTester` use strict equality, so an assertion like this will no longer pass.
**To address:** If you use `RuleTester` to write tests for your custom rules, make sure the expected values in your assertions are strictly equal to the actual values.
## Rules are now required to provide messages along with reports
Previously, it was possible for rules to report AST nodes without providing a report message. This was not intended behavior, and as a result the default formatter would crash if a rule omitted a message. However, it was possible to avoid a crash when using a non-default formatter, such as `json`.
In ESLint v5, reporting a problem without providing a message always results in an error.
**To address:** If you have written a custom rule that reports a problem without providing a message, update it to provide a message along with the report.
---
## The `source` property is no longer available on individual linting messages
As announced in [October 2016](/blog/2016/10/eslint-v3.8.0-released#additional-property-on-linting-results), the `source` property has been removed from individual lint message objects.
**To address:** If you have a formatter or integration which relies on using the `source` property on individual linting messages, you should update it to use the `source` property on file results objects instead.
## Fatal errors now result in an exit code of 2
When using ESLint v4, both of the following scenarios resulted in an exit code of 1 when running ESLint on the command line:
- Linting completed successfully, but there are some linting errors
- Linting was unsuccessful due to a fatal error (e.g. an invalid config file)
As a result, it was difficult for an integration to distinguish between the two cases to determine whether it should try to extract linting results from the output.
In ESLint v5, an unsuccessful linting run due to a fatal error will result in an exit code of 2, rather than 1.
**To address:** If you have an integration that detects all problems with linting runs by checking whether the exit code is equal to 1, update it to check whether the exit code is nonzero instead.
## The `eslint.linter` property is now non-enumerable
When using ESLint's Node.js API, the [`linter`](../integrate/nodejs-api#linter-1) property is now non-enumerable. Note that the `linter` property was deprecated in ESLint v4 in favor of the [`Linter`](../integrate/nodejs-api#linter) property.
**To address:** If you rely on enumerating all the properties of the `eslint` object, use something like `Object.getOwnPropertyNames` to ensure that non-enumerable keys are captured.
---
---
title: Migrating to v6.0.0
---
ESLint v6.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Breaking changes for users
1. [Node.js 6 is no longer supported](#drop-node-6)
1. [`eslint:recommended` has been updated](#eslint-recommended-changes)
1. [Plugins and shareable configs are no longer affected by ESLint's location](#package-loading-simplification)
1. [The default parser now validates options more strictly](#espree-validation)
1. [Rule configuration are validated more strictly](#rule-config-validating)
1. [The `no-redeclare` rule is now more strict by default](#no-redeclare-updates)
1. [The `comma-dangle` rule is now more strict by default](#comma-dangle-updates)
1. [The `no-confusing-arrow` rule is now more lenient by default](#no-confusing-arrow-updates)
1. [Overrides in a config file can now match dotfiles](#overrides-dotfiles)
1. [Overrides in an extended config file can now be overridden by a parent config file](#overrides-precedence)
1. [Configuration values for globals are now validated](#globals-validation)
1. [The deprecated `experimentalObjectRestSpread` option has been removed](#experimental-object-rest-spread)
1. [User-provided regular expressions in rule options are parsed with the unicode flag](#unicode-regexes)
## Breaking changes for plugin/custom rule developers
1. [Plugin authors may need to update installation instructions](#plugin-documentation)
1. [`RuleTester` now validates against invalid `default` keywords in rule schemas](#rule-tester-defaults)
1. [`RuleTester` now requires an absolute path on `parser` option](#rule-tester-parser)
1. [The `eslintExplicitGlobalComment` scope analysis property has been removed](#eslintExplicitGlobalComment)
## Breaking changes for integration developers
1. [Plugins and shareable configs are no longer affected by ESLint's location](#package-loading-simplification)
1. [`Linter` no longer tries to load missing parsers from the filesystem](#linter-parsers)
---
## Node.js 6 is no longer supported
As of April 2019, Node.js 6 will be at EOL and will no longer be receiving security updates. As a result, we have decided to drop support for it in ESLint v6. We now support the following versions of Node.js:
- Node.js 8 (8.10.0 and above)
- Node.js 10 (10.13.0 and above)
- Anything above Node.js 11.10.1
**To address:** Make sure you upgrade to at least Node.js 8 when using ESLint v6. If you are unable to upgrade, we recommend continuing to use ESLint v5.x until you are able to upgrade Node.js.
**Related issue(s):** [eslint/eslint#11546](https://github.com/eslint/eslint/issues/11456)
## `eslint:recommended` has been updated
The following rules have been added to the [`eslint:recommended`](../use/configure#using-eslintrecommended) config:
- [`no-async-promise-executor`](../rules/no-async-promise-executor) disallows using an `async` function as the argument to the `Promise` constructor, which is usually a bug.
- [`no-misleading-character-class`](../rules/no-misleading-character-class) reports character classes in regular expressions that might not behave as expected.
- [`no-prototype-builtins`](../rules/no-prototype-builtins) reports method calls like `foo.hasOwnProperty("bar")` (which are a frequent source of bugs), and suggests that they be replaced with `Object.prototype.hasOwnProperty.call(foo, "bar")` instead.
- [`no-shadow-restricted-names`](../rules/no-shadow-restricted-names) disallows shadowing variables like `undefined` (e.g. with code like `let undefined = 5;`), since is likely to confuse readers.
- [`no-useless-catch`](../rules/no-useless-catch) reports `catch` clauses that are redundant and can be removed from the code without changing its behavior.
- [`no-with`](../rules/no-with) disallows use of the [`with` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with), which can make code difficult to understand and cause compatibility problems.
- [`require-atomic-updates`](../rules/require-atomic-updates) reports race condition bugs that can occur when reassigning variables in async functions.
Additionally, the following rule has been _removed_ from `eslint:recommended`:
- [`no-console`](../rules/no-console) disallows calling functions like `console.log`. While this rule is useful in many cases (e.g. to avoid inadvertently leaving debugging statements in production code), it is not as broadly applicable as the other rules in `eslint:recommended`, and it was a source of false positives in cases where `console.log` is acceptable (e.g. in CLI applications).
Finally, in ESLint v5 `eslint:recommended` would explicitly disable all core rules that were not considered "recommended". This could cause confusing behavior if `eslint:recommended` was loaded after another config, since `eslint:recommended` would have the effect of turning off some rules. In ESLint v6, `eslint:recommended` has no effect on non-recommended rules.
**To address:** To mimic the `eslint:recommended` behavior from 5.x, you can explicitly disable/enable rules in a config file as follows:
```json
{
"extends": "eslint:recommended",
"rules": {
"no-async-promise-executor": "off",
"no-misleading-character-class": "off",
"no-prototype-builtins": "off",
"no-shadow-restricted-names": "off",
"no-useless-catch": "off",
"no-with": "off",
"require-atomic-updates": "off",
"no-console": "error"
}
}
```
In rare cases (if you were relying on the previous behavior where `eslint:recommended` disables core rules), you might need to disable additional rules to restore the previous behavior.
**Related issue(s):** [eslint/eslint#10768](https://github.com/eslint/eslint/issues/10768), [eslint/eslint#10873](https://github.com/eslint/eslint/issues/10873)
## Plugins and shareable configs are no longer affected by ESLint's location
Previously, ESLint loaded plugins relative to the location of the ESLint package itself. As a result, we suggested that users with global ESLint installations should also install plugins globally, and users with local ESLint installations should install plugins locally. However, due to a design bug, this strategy caused ESLint to randomly fail to load plugins and shareable configs under certain circumstances, particularly when using package management tools like [`lerna`](https://github.com/lerna/lerna) and [Yarn Plug n' Play](https://yarnpkg.com/lang/en/docs/pnp/).
As a rule of thumb: With ESLint v6, plugins should always be installed locally, even if ESLint was installed globally. More precisely, ESLint v6 resolves plugins relative to the end user's project by default, and always resolves shareable configs and parsers relative to the location of the config file that imports them.
**To address:** If you use a global installation of ESLint (e.g. installed with `npm install eslint --global`) along with plugins, you should install those plugins locally in the projects where you run ESLint. If your config file extends shareable configs and/or parsers, you should ensure that those packages are installed as dependencies of the project containing the config file.
If you use a config file located outside of a local project (with the `--config` flag), consider installing the plugins as dependencies of that config file, and setting the `--resolve-plugins-relative-to` flag to the location of the config file.
**Related issue(s):** [eslint/eslint#10125](https://github.com/eslint/eslint/issues/10125), [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7)
## The default parser now validates options more strictly
`espree`, the default parser used by ESLint, will now raise an error in the following cases:
- The `ecmaVersion` parser option is set to something other than a number, such as the string `"2015"`. (Previously, a non-number option would simply be ignored.)
- The `sourceType: "module"` parser option is set while `ecmaVersion` is set to `5` or left unspecified. (Previously, setting `sourceType: "module"` would implicitly cause `ecmaVersion` to be set to a minimum of 2015, which could be surprising.)
- The `sourceType` is set to anything other than `"script"` or `"module"`.
**To address:** If your config sets `ecmaVersion` to something other than a number, you can restore the previous behavior by removing `ecmaVersion`. (However, you may want to double-check that your config is actually working as expected.) If your config sets `parserOptions: { sourceType: "module" }` without also setting `parserOptions.ecmaVersion`, you should add `parserOptions: { ecmaVersion: 2015 }` to restore the previous behavior.
**Related issue(s):** [eslint/eslint#9687](https://github.com/eslint/eslint/issues/9687), [eslint/espree#384](https://github.com/eslint/espree/issues/384)
## Rule configuration are validated more strictly
To catch config errors earlier, ESLint v6 will report a linting error if you are trying to configure a non-existent rule.
| config | ESLint v5 | ESLint v6 |
| ------------------------------- | --------------- | ------------- |
| `/*eslint-enable foo*/` | no error | linting error |
| `/*eslint-disable(-line) foo*/` | no error | linting error |
| `/*eslint foo: 0*/` | no error | linting error |
| `{rules: {foo: 0}}` | no error | no error |
| `{rules: {foo: 1}` | linting warning | linting error |
**To address:** You can remove the non-existent rule in your (inline) config.
**Related issue(s):** [eslint/eslint#9505](https://github.com/eslint/eslint/issues/9505)
## The `no-redeclare` rule is now more strict by default
The default options for the [`no-redeclare`](../rules/no-redeclare) rule have changed from `{ builtinGlobals: false }` to `{ builtinGlobals: true }`. Additionally, the `no-redeclare` rule will now report an error for globals enabled by comments like `/* global foo */` if those globals were already enabled through configuration anyway.
**To address:**
To restore the previous options for the rule, you can configure it as follows:
```json
{
"rules": {
"no-redeclare": ["error", { "builtinGlobals": false }]
}
}
```
Additionally, if you see new errors for `global` comments in your code, you should remove those comments.
**Related issue(s):** [eslint/eslint#11370](https://github.com/eslint/eslint/issues/11370), [eslint/eslint#11405](https://github.com/eslint/eslint/issues/11405)
## The `comma-dangle` rule is now more strict by default
Previously, the [`comma-dangle`](../rules/comma-dangle) rule would ignore trailing function arguments and parameters, unless explicitly configured to check for function commas. In ESLint v6, function commas are treated the same way as other types of trailing commas.
**To address:** You can restore the previous default behavior of the rule with:
```json
{
"rules": {
"comma-dangle": [
"error",
{
"arrays": "never",
"objects": "never",
"imports": "never",
"exports": "never",
"functions": "ignore"
}
]
}
}
```
To restore the previous behavior of a string option like `"always-multiline"`, replace `"never"` with `"always-multiline"` in the example above.
**Related issue(s):** [eslint/eslint#11502](https://github.com/eslint/eslint/issues/11502)
## The `no-confusing-arrow` rule is now more lenient by default
The default options for the [`no-confusing-arrow`](../rules/no-confusing-arrow) rule have changed from `{ allowParens: false }` to `{ allowParens: true }`.
**To address:** You can restore the previous default behavior of the rule with:
```json
{
"rules": {
"no-confusing-arrow": ["error", { "allowParens": false }]
}
}
```
**Related issue(s):** [eslint/eslint#11503](https://github.com/eslint/eslint/issues/11503)
## Overrides in a config file can now match dotfiles
Due to a bug, the glob patterns in a `files` list in an `overrides` section of a config file would never match dotfiles, making it impossible to have overrides apply to files starting with a dot. This bug has been fixed in ESLint v6.
**To address:** If you don't want dotfiles to be matched by an override, consider adding something like `excludedFiles: [".*"]` to that `overrides` section. See the [documentation](../use/configure#configuration-based-on-glob-patterns) for more details.
**Related issue(s):** [eslint/eslint#11201](https://github.com/eslint/eslint/issues/11201)
## Overrides in an extended config file can now be overridden by a parent config file
Due to a bug, it was previously the case that an `overrides` block in a shareable config had precedence over the top level of a parent config. For example, with the following config setup, the `semi` rule would end up enabled even though it was explicitly disabled in the end user's config:
```js
// .eslintrc.js
module.exports = {
extends: ["foo"],
rules: {
semi: "off",
},
};
```
```js
// eslint-config-foo/index.js
module.exports = {
overrides: {
files: ["*.js"],
rules: {
semi: "error",
},
},
};
```
In ESLint v6.0.0, a parent config always has precedence over extended configs, even with `overrides` blocks.
**To address:** We expect the impact of this issue to be very low because most shareable configs don't use `overrides` blocks. However, if you use a shareable config with `overrides` blocks, you might encounter a change in behavior due to something that is explicitly specified in your config but was inactive until now. If you would rather inherit the behavior from the shareable config, simply remove the corresponding entry from your own config. (In the example above, the previous behavior could be restored by removing `semi: "off"` from `.eslintrc.js`.)
**Related issue(s):** [eslint/eslint#11510](https://github.com/eslint/eslint/issues/11510)
## Configuration values for globals are now validated
Previously, when configuring a set of global variables with an object, it was possible to use anything as the values of the object. An unknown value would be treated the same as `"writable"`.
```js
// .eslintrc.js
module.exports = {
globals: {
foo: "readonly",
bar: "writable",
baz: "hello!", // ???
},
};
```
With this change, any unknown values in a `globals` object result in a config validation error.
**To address:** If you see config validation errors related to globals after updating, ensure that all values configured for globals are either `readonly`, `writable`, or `off`. (ESLint also accepts some alternate spellings and variants for compatibility.)
## The deprecated `experimentalObjectRestSpread` option has been removed
Previously, when using the default parser, a config could use the `experimentalObjectRestSpread` option to enable parsing support for object rest/spread properties:
```json
{
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
}
}
```
Since ESLint v5, `ecmaFeatures: { experimentalObjectRestSpread: true }` has been equivalent to `ecmaVersion: 2018`, and has also emitted a deprecation warning. In ESLint v6, the `experimentalObjectRestSpread` feature has been removed entirely and has no effect. If your config was relying on `experimentalObjectRestSpread` to enable ES2018 parsing, you might start seeing parsing errors for recent syntax.
**To address:** If you use the `experimentalObjectRestSpread` option, you should change your config to contain this instead:
```json
{
"parserOptions": {
"ecmaVersion": 2018
}
}
```
If you're not sure which config file needs to be updated, it may be useful to run ESLint v5 and look at what config file is mentioned in the deprecation warning.
**Related issue(s):** [eslint/eslint#9990](https://github.com/eslint/eslint/issues/9990)
## User-provided regular expressions in rule options are parsed with the unicode flag
Rules like [`max-len`](../rules/max-len) accept a string option which is interpreted as a regular expression. In ESLint v6.0.0, these regular expressions are interpreted with the [unicode flag](https://mathiasbynens.be/notes/es6-unicode-regex), which should exhibit more reasonable behavior when matching characters like astral symbols. Unicode regexes also validate escape sequences more strictly than non-unicode regexes.
**To address:** If you get rule option validation errors after upgrading, ensure that any regular expressions in your rule options have no invalid escape sequences.
**Related issue(s):** [eslint/eslint#11423](https://github.com/eslint/eslint/issues/11423)
---
## Plugin authors may need to update installation instructions
If you maintain a plugin and provide installation instructions, you should ensure that the installation instructions are up to date with the [user-facing changes to how plugins are loaded](#package-loading-simplification). In particular, if your plugin was generated with the [`generator-eslint`](https://github.com/eslint/generator-eslint) package, it likely contains outdated instructions for how to use the plugin with global ESLint installations.
**Related issue(s):** [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7)
## `RuleTester` now validates against invalid `default` keywords in rule schemas
In some cases, rule schemas can use the `default` keyword to automatically specify default values for rule options. However, the `default` keyword is only effective in certain schema locations, and is ignored elsewhere, which creates a risk of bugs if a rule incorrectly expects a default value to be provided as a rule option. In ESLint v6.0.0, `RuleTester` will raise an error if a rule has an invalid `default` keyword in its schema.
**To address:** If `RuleTester` starts reporting an error about an invalid default, you can remove the `default` property at the indicated location in your rule schema, and the rule will behave the same way. (If this happens, you might also want to verify that the rule behaves correctly when no option value is provided in that location.)
**Related issue(s):** [eslint/eslint#11473](https://github.com/eslint/eslint/issues/11473)
## `RuleTester` now requires an absolute path on `parser` option
To use custom parsers in tests, we could use `parser` property with a package name or file path. However, if a package name was given, it's unclear where the tester should load the parser package from because the tester doesn't know which files are running the tester. In ESLint v6.0.0, `RuleTester` disallows `parser` property with a package name.
**To address:** If you use `parser` property with package names in test cases, update it with `require.resolve()` function to resolve the package name to the absolute path to the package.
**Related issue(s):** [eslint/eslint#11728](https://github.com/eslint/eslint/issues/11728), [eslint/eslint#10125](https://github.com/eslint/eslint/issues/10125), [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7)
## The `eslintExplicitGlobalComment` scope analysis property has been removed
Previously, ESLint would add an `eslintExplicitGlobalComment` property to `Variable` objects in scope analysis to indicate that a variable was introduced as a result of a `/* global */` comment. This property was undocumented, and the ESLint team was unable to find any usage of the property outside of ESLint core. The property has been removed in ESLint v6, and replaced with the `eslintExplicitGlobalComments` property, which can contain a list of all `/* global */` comments if a variable was declared with more than one of them.
**To address:** If you maintain a rule that uses the `eslintExplicitGlobalComment` property, update it to use the `eslintExplicitGlobalComments` property as a list instead.
**Related issue(s):** [eslint/rfcs#17](https://github.com/eslint/rfcs/pull/17)
---
## `Linter` no longer tries to load missing parsers from the filesystem
Previously, when linting code with a parser that had not been previously defined, the `Linter` API would attempt to load the parser from the filesystem. However, this behavior was confusing because `Linter` never access the filesystem in any other cases, and it was difficult to ensure that the correct parser would be found when loading the parser from the filesystem.
In ESLint v6, `Linter` will no longer perform any filesystem operations, including loading parsers.
**To address:** If you're using `Linter` with a custom parser, use [`Linter#defineParser`](../integrate/nodejs-api#linterdefineparser) to explicitly define the parser before linting any code.
**Related issue(s):** [eslint/rfcs#7](https://github.com/eslint/rfcs/pull/7)
---
---
title: Migrating to v7.0.0
---
ESLint v7.0.0 is a major release of ESLint. We have made a few breaking changes in this release. This guide is intended to walk you through the breaking changes.
The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
## Table of Content
### Breaking changes for users
- [Node.js 8 is no longer supported](#drop-node-8)
- [Lint files matched by `overrides[].files` by default](#additional-lint-targets)
- [The base path of `overrides` and `ignorePatterns` is changed if the config file is given by the `--config`/`--ignore-path` options](#base-path-change)
- [The place where ESLint loads plugins from is changed](#plugin-loading-change)
- [Runtime deprecation warnings for `~/.eslintrc.*` config files](#runtime-deprecation-on-personal-config-files)
- [Default ignore patterns have changed](#default-ignore-patterns)
- [Description in directive comments](#description-in-directive-comments)
- [Node.js/CommonJS rules are deprecated](#deprecate-node-rules)
- [Several rules have been updated to cover more cases](#rules-strict)
- [`eslint:recommended` has been updated](#eslint-recommended)
### Breaking changes for plugin developers
- [Node.js 8 is no longer supported](#drop-node-8)
- [Lint files matched by `overrides[].files` by default](#additional-lint-targets)
- [Plugin resolution has been updated](#plugin-loading-change)
- [Additional validation added to the `RuleTester` class](#rule-tester-strict)
### Breaking changes for integration developers
- [Node.js 8 is no longer supported](#drop-node-8)
- [Plugin resolution has been updated](#plugin-loading-change)
- [The `CLIEngine` class has been deprecated](#deprecate-cliengine)
---
## Node.js 8 is no longer supported
Node.js 8 reached EOL in December 2019, and we are officially dropping support for it in this release. ESLint now supports the following versions of Node.js:
- Node.js 10 (`10.12.0` and above)
- Node.js 12 and above
**To address:** Make sure you upgrade to at least Node.js `10.12.0` when using ESLint v7.0.0. One important thing to double check is the Node.js version supported by your editor when using ESLint via editor integrations. If you are unable to upgrade, we recommend continuing to use ESLint 6 until you are able to upgrade Node.js.
**Related issue(s):** [RFC44](https://github.com/eslint/rfcs/blob/master/designs/2019-drop-node8/README.md), [#12700](https://github.com/eslint/eslint/pull/12700)
## Lint files matched by `overrides[].files` by default
Previously to v7.0.0, ESLint would only lint files with a `.js` extension by default if you give directories like `eslint src`.
ESLint v7.0.0 will now additionally lint files with other extensions (`.ts`, `.vue`, etc.) if the extension is explicitly matched by an `overrides[].files` entry. This will allow for users to lint files that don't end with `*.js` to be linted without having to use the `--ext` command line flag, as well as allow shared configuration authors to enable linting of these files without additional overhead for the end user. Please note that patterns that end with `*` are exempt from this behavior and will behave as they did previously. For example, if the following config file is present,
```yml
# .eslintrc.yml
extends: my-config-js
overrides:
- files: "*.ts"
extends: my-config-ts
```
then running `eslint src` would check both `*.js` and `*.ts` files in the `src` directory.
**To address:** Using the `--ext` CLI option will override this new behavior. Run ESLint with `--ext .js` if you are using `overrides` but only want to lint files that have a `.js` extension.
If you maintain plugins that check files with extensions other than `.js`, this feature will allow you to check these files by default by configuring an `overrides` setting in your `recommended` preset.
**Related issue(s):** [RFC20](https://github.com/eslint/rfcs/blob/master/designs/2019-additional-lint-targets/README.md), [#12677](https://github.com/eslint/eslint/pull/12677)
## The base path of `overrides` and `ignorePatterns` has changed when using the `--config`/`--ignore-path` options
Up until now, ESLint has resolved the following paths relative to the directory path of the _entry_ configuration file:
- Configuration files (`.eslintrc.*`)
- relative paths in the `overrides[].files` setting
- relative paths in the `overrides[].excludedFiles` setting
- paths which start with `/` in the `ignorePatterns` setting
- Ignore files (`.eslintignore`)
- paths which start with `/`
Starting in ESLint v7.0.0, configuration files and ignore files passed to ESLint using the `--config path/to/a-config` and `--ignore-path path/to/a-ignore` CLI flags, respectively, will resolve from the current working directory rather than the file location. This allows for users to utilize shared plugins without having to install them directly in their project.
**To address:** Update the affected paths if you are using a configuration or ignore file via the `--config` or `--ignore-path` CLI options.
**Related issue(s):** [RFC37](https://github.com/eslint/rfcs/blob/master/designs/2019-changing-base-path-in-config-files-that-cli-options-specify/README.md), [#12887](https://github.com/eslint/eslint/pull/12887)
## Plugin resolution has been updated
In previous versions, ESLint resolved all plugins from the current working directory by default.
Starting in ESLint v7.0.0, `plugins` are resolved relative to the directory path of the _entry_ configuration file.
This will not change anything in most cases. If a configuration file in a subdirectory has `plugins` defined, the plugins will be loaded from the subdirectory (or ancestor directories that include the current working directory if not found).
This means that if you are using a config file from a shared location via `--config` option, the plugins that the config file declare will be loaded from the shared config file location.
**To address:** Ensure that plugins are installed in a place that can be resolved relative to your configuration file or use `--resolve-plugins-relative-to .` to override this change.
**Related issue(s):** [RFC47](https://github.com/eslint/rfcs/blob/master/designs/2019-plugin-loading-improvement/README.md), [#12922](https://github.com/eslint/eslint/pull/12922)
## Runtime deprecation warnings for `~/.eslintrc.*` config files
Personal config files have been deprecated since [v6.7.0](https://eslint.org/blog/2019/11/eslint-v6.7.0-released). ESLint v7.0.0 will start printing runtime deprecation warnings. It will print a warning for the following situations:
1. When a project does not have a configuration file present and ESLint loads configuration from `~/.eslintrc.*`.
1. When a project has a configuration file and ESLint ignored a `~/.eslintrc.*` configuration file. This occurs when the `$HOME` directory is an ancestor directory of the project and the project's configuration files doesn't contain `root:true`.
**To address:** Remove `~/.eslintrc.*` configuration files and add an `.eslintrc.*` configuration file to your project. Alternatively, use the `--config` option to use shared config files.
**Related issue(s):** [RFC32](https://github.com/eslint/rfcs/tree/master/designs/2019-deprecating-personal-config/README.md), [#12678](https://github.com/eslint/eslint/pull/12678)
## Default ignore patterns have changed
Up until now, ESLint has ignored the following files by default:
- Dotfiles (`.*`)
- `node_modules` in the current working directory (`/node_modules/*`)
- `bower_components` in the current working directory (`/bower_components/*`)
ESLint v7.0.0 ignores `node_modules/*` of subdirectories as well, but no longer ignores `bower_components/*` and `.eslintrc.js`. Therefore, the new default ignore patterns are:
- Dotfiles except `.eslintrc.*` (`.*` but not `.eslintrc.*`)
- `node_modules` (`/**/node_modules/*`)
**To address:** Modify your `.eslintignore` or the `ignorePatterns` property of your config file if you don't want to lint `bower_components/*` and `.eslintrc.js`.
**Related issue(s):** [RFC51](https://github.com/eslint/rfcs/blob/master/designs/2019-update-default-ignore-patterns/README.md), [#12888](https://github.com/eslint/eslint/pull/12888)
## Descriptions in directive comments
In older version of ESLint, there was no convenient way to indicate why a directive comment – such as `/*eslint-disable*/` – was necessary.
To allow for the colocation of comments that provide context with the directive, ESLint v7.0.0 adds the ability to append arbitrary text in directive comments by ignoring text following `--` surrounded by whitespace. For example:
```js
// eslint-disable-next-line a-rule, another-rule -- those are buggy!!
```
**To address:** If you have `--` surrounded by whitespace in directive comments, consider moving it into your configuration file.
**Related issue(s):** [RFC33](https://github.com/eslint/rfcs/blob/master/designs/2019-description-in-directive-comments/README.md), [#12699](https://github.com/eslint/eslint/pull/12699)
## Node.js/CommonJS rules have been deprecated
The ten Node.js/CommonJS rules in core have been deprecated and moved to the [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) plugin (for ESLint v8.0.0 and later, use the maintained [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) fork instead) .
**To address:** As per [our deprecation policy](../use/rule-deprecation), the deprecated rules will remain in core for the foreseeable future and are still available for use. However, we will no longer be updating or fixing any bugs in those rules. To use a supported version of the rules, we recommend using the corresponding rules in the plugin instead.
| Deprecated Rules | Replacement |
| :------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------ |
| [callback-return](../rules/callback-return) | [node/callback-return](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/callback-return.md) |
| [global-require](../rules/global-require) | [node/global-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/global-require.md) |
| [handle-callback-err](../rules/handle-callback-err) | [node/handle-callback-err](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/handle-callback-err.md) |
| [no-mixed-requires](../rules/no-mixed-requires) | [node/no-mixed-requires](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-mixed-requires.md) |
| [no-new-require](../rules/no-new-require) | [node/no-new-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-new-require.md) |
| [no-path-concat](../rules/no-path-concat) | [node/no-path-concat](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-path-concat.md) |
| [no-process-env](../rules/no-process-env) | [node/no-process-env](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-process-env.md) |
| [no-process-exit](../rules/no-process-exit) | [node/no-process-exit](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-process-exit.md) |
| [no-restricted-modules](../rules/no-restricted-modules) | [node/no-restricted-require](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-restricted-require.md) |
| [no-sync](../rules/no-sync) | [node/no-sync](https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-sync.md) |
**Related issue(s):** [#12898](https://github.com/eslint/eslint/pull/12898)
## Several rules have been updated to cover more cases
Several rules have been enhanced and now report additional errors:
- [accessor-pairs](../rules/accessor-pairs) rule now recognizes class members by default.
- [array-callback-return](../rules/array-callback-return) rule now recognizes `flatMap` method.
- [computed-property-spacing](../rules/computed-property-spacing) rule now recognizes class members by default.
- [func-names](../rules/func-names) rule now recognizes function declarations in default exports.
- [no-extra-parens](../rules/no-extra-parens) rule now recognizes parentheses in assignment targets.
- [no-dupe-class-members](../rules/no-dupe-class-members) rule now recognizes computed keys for static class members.
- [no-magic-numbers](../rules/no-magic-numbers) rule now recognizes bigint literals.
- [radix](../rules/radix) rule now recognizes invalid numbers for the second parameter of `parseInt()`.
- [use-isnan](../rules/use-isnan) rule now recognizes class members by default.
- [yoda](../rules/yoda) rule now recognizes bigint literals.
**To address:** Fix errors or disable these rules.
**Related issue(s):** [#12490](https://github.com/eslint/eslint/pull/12490), [#12608](https://github.com/eslint/eslint/pull/12608), [#12670](https://github.com/eslint/eslint/pull/12670), [#12701](https://github.com/eslint/eslint/pull/12701), [#12765](https://github.com/eslint/eslint/pull/12765), [#12837](https://github.com/eslint/eslint/pull/12837), [#12913](https://github.com/eslint/eslint/pull/12913), [#12915](https://github.com/eslint/eslint/pull/12915), [#12919](https://github.com/eslint/eslint/pull/12919)
## `eslint:recommended` has been updated
Three new rules have been enabled in the `eslint:recommended` preset.
- [no-dupe-else-if](../rules/no-dupe-else-if)
- [no-import-assign](../rules/no-import-assign)
- [no-setter-return](../rules/no-setter-return)
**To address:** Fix errors or disable these rules.
**Related issue(s):** [#12920](https://github.com/eslint/eslint/pull/12920)
## Additional validation added to the `RuleTester` class
The `RuleTester` now validates the following:
- It fails test cases if the rule under test uses the non-standard `node.start` or `node.end` properties. Rules should use `node.range` instead.
- It fails test cases if the rule under test provides an autofix but a test case doesn't have an `output` property. Add an `output` property to test cases to test the rule's autofix functionality.
- It fails test cases if any unknown properties are found in the objects in the `errors` property.
**To address:** Modify your rule or test case if existing test cases fail.
**Related issue(s):** [RFC25](https://github.com/eslint/rfcs/blob/master/designs/2019-rule-tester-improvements/README.md), [#12096](https://github.com/eslint/eslint/pull/12096), [#12955](https://github.com/eslint/eslint/pull/12955)
## The `CLIEngine` class has been deprecated
The [`CLIEngine` class](../integrate/nodejs-api#cliengine) has been deprecated and replaced by the new [`ESLint` class](../integrate/nodejs-api#eslint-class).
The `CLIEngine` class provides a synchronous API that is blocking the implementation of features such as parallel linting, supporting ES modules in shareable configs/parsers/plugins/formatters, and adding the ability to visually display the progress of linting runs. The new `ESLint` class provides an asynchronous API that ESLint core will now using going forward. `CLIEngine` will remain in core for the foreseeable future but may be removed in a future major version.
**To address:** Update your code to use the new `ESLint` class if you are currently using `CLIEngine`. The following table maps the existing `CLIEngine` methods to their `ESLint` counterparts:
| `CLIEngine` | `ESLint` |
| :------------------------------------------- | :--------------------------------- |
| `executeOnFiles(patterns)` | `lintFiles(patterns)` |
| `executeOnText(text, filePath, warnIgnored)` | `lintText(text, options)` |
| `getFormatter(name)` | `loadFormatter(name)` |
| `getConfigForFile(filePath)` | `calculateConfigForFile(filePath)` |
| `isPathIgnored(filePath)` | `isPathIgnored(filePath)` |
| `static outputFixes(results)` | `static outputFixes(results)` |
| `static getErrorResults(results)` | `static getErrorResults(results)` |
| `static getFormatter(name)` | (removed ※1) |
| `addPlugin(pluginId, definition)` | the `plugins` constructor option |
| `getRules()` | (not implemented yet) |
| `resolveFileGlobPatterns()` | (removed ※2) |
- ※1 The `engine.getFormatter()` method currently returns the object of loaded packages as-is, which made it difficult to add new features to formatters for backward compatibility reasons. The new `eslint.loadFormatter()` method returns an adapter object that wraps the object of loaded packages, to ease the process of adding new features. Additionally, the adapter object has access to the `ESLint` instance to calculate default data (using loaded plugin rules to make `rulesMeta`, for example). As a result, the `ESLint` class only implements an instance version of the `loadFormatter()` method.
- ※2 Since ESLint 6, ESLint uses different logic from the `resolveFileGlobPatterns()` method to iterate files, making this method obsolete.
**Related issue(s):** [RFC40](https://github.com/eslint/rfcs/blob/master/designs/2019-move-to-async-api/README.md), [#12939](https://github.com/eslint/eslint/pull/12939)
---
---
title: Rule Deprecation
---
Balancing the trade-offs of improving a tool and the frustration these changes can cause is a difficult task. One key area in which this affects our users is in the removal of rules.
The ESLint team is committed to making upgrading as easy and painless as possible. To that end, the team has agreed upon the following set of guidelines for deprecating rules in the future. The goal of these guidelines is to allow for improvements and changes to be made without breaking existing configurations.
- Rules will never be removed from ESLint unless one of the following is true:
- The rule has been replaced by another core rule.
- A plugin exists with a functionally equivalent rule.
- Rules will be deprecated as needed, and marked as such in all documentation.
- After a rule has been deprecated, the team will no longer do any work on it. This includes bug fixes, enhancements, and updates to the rule's documentation. Issues and pull requests related to the deprecated rule will not be accepted and will be closed.
You can continue to use deprecated rules indefinitely if they are working for you. However, keep in mind that deprecated rules will effectively be unmaintained and may be removed at some point.
We hope that by following these guidelines we will be able to continue improving and working to make ESLint the best tool it can be while causing as little disruption to our users as possible during the process.
---
---
title: Bulk Suppressions
eleventyNavigation:
key: suppressions
parent: use eslint
title: Bulk Suppressions
order: 8
---
Enabling a new lint rule as `"error"` can be challenging when the codebase has many violations and the rule isn't auto-fixable. Unless the rule is enabled during the early stages of the project, it becomes harder and harder to enable it as the codebase grows. Existing violations must be resolved before enabling the rule, but while doing that other violations may occur.
To address this, ESLint provides a way to suppress existing violations for one or more rules. While the rule will be enforced for new code, the existing violations will not be reported. This way, you can address the existing violations at your own pace.
::: important
Only rules configured as `"error"` are suppressed. If a rule is enabled as `"warn"`, ESLint will not suppress the violations.
:::
After you enable a rule as `"error"` in your configuration file, you can suppress all the existing violations at once by using the `--suppress-all` flag. It is recommended to execute the command with the `--fix` flag so that you don't suppress violations that can be auto-fixed.
```bash
eslint --fix --suppress-all
```
This command will suppress all the existing violations of all the rules that are enabled as `"error"`. Running the `eslint` command again will not report these violations.
If you would like to suppress violations of a specific rule, you can use the `--suppress-rule` flag.
```bash
eslint --fix --suppress-rule no-unused-expressions
```
You can also suppress violations of multiple rules by providing multiple rule names.
```bash
eslint --fix --suppress-rule no-unused-expressions --suppress-rule no-unsafe-assignment
```
## Suppressions File
When you suppress violations, ESLint creates a `eslint-suppressions.json` file in the root of the project. This file contains the list of rules that have been suppressed. You should commit this file to the repository so that the suppressions are shared with all the developers.
If necessary, you can change the location of the suppressions file by using the `--suppressions-location` argument. Note that the argument must be provided not only when suppressing violations but also when running ESLint. This is necessary so that ESLint picks up the correct suppressions file.
```bash
eslint --suppressions-location .github/.eslint-suppressions
```
## Resolving Suppressions
You can address any of the reported violations by making the necessary changes to the code as usual. If you run ESLint again you will notice that it exits with a non-zero exit code and an error is reported about unused suppressions. This is because the violations have been resolved but the suppressions are still in place.
```bash
> eslint
There are suppressions left that do not occur anymore. Consider re-running the command with `--prune-suppressions`.
```
To remove the suppressions that are no longer needed, you can use the [`--prune-suppressions`](./command-line-interface#--prune-suppressions) flag.
```bash
eslint --prune-suppressions
```
To ignore unused suppressions when calculating the exit code and not report an error about unused suppressions, you can use the `--pass-on-unpruned-suppressions` flag.
```bash
eslint --pass-on-unpruned-suppressions
```
For more information on the available CLI options, refer to [Command Line Interface](./command-line-interface).
---
---
title: Circular fixes detected …
eleventyNavigation:
key: circular fixes
parent: troubleshooting
title: Circular fixes detected …
---
## Symptoms
When running ESLint with the `--fix` option, you may see the following warning:
```plaintext
ESLintCircularFixesWarning: Circular fixes detected while fixing path/to/file. It is likely that you have conflicting rules in your configuration.
```
## Cause
You have conflicting fixable rules in your configuration. ESLint autofixes code in multiple passes, meaning it's possible that a fix in one pass is undone in a subsequent pass. For example, in the first pass a rule removes a trailing comma and in the following pass a different rule adds a trailing comma in the same place, effectively changing the code back to the previous version. ESLint emits a warning when it detects cycles like this.
## Resolution
Common resolutions for this issue include:
- Remove or reconfigure one of the conflicting rules in your configuration file.
How to find the conflicting rules:
1. Open the file specified in the warning in an editor that supports applying individual fixes (for example, VS Code).
1. In the list of lint problems, find a fixable rule. That is one of the conflicting rules.
1. Apply the fix ("Fix this (rule-name) problem" action in VS Code).
1. Check what new lint problem has appeared in the list. That is the other conflicting rule.
## Resources
For more information, see:
- [Configure Rules](../configure/rules) for documentation on how to configure rules
---
---
title: ESLint couldn't determine the plugin … uniquely
eleventyNavigation:
key: couldn't determine plugin uniquely
parent: troubleshooting
title: ESLint couldn't determine the plugin … uniquely
---
## Symptoms
When using the [legacy ESLint config system](../configure/configuration-files-deprecated), you may see this error running ESLint after installing dependencies:
```plaintext
ESLint couldn't determine the plugin "${pluginId}" uniquely.
- ${filePath} (loaded in "${importerName}")
- ${filePath} (loaded in "${importerName}")
...
Please remove the "plugins" setting from either config or remove either plugin installation.
```
## Cause
ESLint configuration files allow loading in plugins that may include other plugins.
A plugin package might be specified as a dependency of both your package and one or more ESLint plugins.
Legacy ESLint configuration files may use `extends` to include other configurations.
Those configurations may depend on plugins to provide certain functionality in the configuration.
For example, if your config depends on `eslint-plugin-a@2` and `eslint-plugin-b@3`, and you extend `eslint-config-b` that depends on `eslint-plugin-a@1`, then the `eslint-plugin-a` package might have two different versions on disk:
- `node_modules/eslint-plugin-a`
- `node_modules/eslint-plugin-b/node_modules/eslint-plugin-a`
If the legacy ESLint configuration system sees that both plugins exists in multiple places with different versions, it won't know which one to use.
Note that this issue is only present in the legacy eslintrc configurations.
The new ["flat" config system](../configure/configuration-files) has you `import` the dependencies yourself, removing the need for ESLint to attempt to determine their version uniquely.
## Resolution
Common resolutions for this issue include:
- Upgrading all versions of all packages to their latest version.
- Running `npm dedupe` or the equivalent package manager command to deduplicate packages, if their version ranges are compatible.
- Using `overrides` or the equivalent package manager `package.json` field, to force a specific version of a plugin package.
- Note that this may cause bugs in linting if the plugin package had breaking changes between versions.
## Resources
For more information, see:
- [Configure Plugins](../configure/plugins) for documentation on how to extend from plugins
- [Create Plugins](../../extend/plugins#configs-in-plugins) for documentation on how to define plugins
---
---
title: ESLint couldn't find the config … to extend from
eleventyNavigation:
key: couldn't find the config to extend from
parent: troubleshooting
title: ESLint couldn't find the config … to extend from
---
## Symptoms
When using the [legacy ESLint config system](../configure/configuration-files-deprecated), you may see this error running ESLint after installing dependencies:
```plaintext
ESLint couldn't find the config "${configName}" to extend from. Please check that the name of the config is correct.
The config "${configName}" was referenced from the config file in "${importerName}".
```
## Cause
ESLint configuration files specify shareable configs by their package name in the `extends` array.
That package name is passed to the Node.js `require()`, which looks up the package under local `node_modules/` directories.
For example, the following ESLint config will first try to load a module located at `node_modules/eslint-config-yours`:
```js
module.exports = {
extends: ["eslint-config-yours"],
};
```
The error is output when you attempt to extend from a configuration and the package for that configuration is not found in any searched `node_modules/`.
Common reasons for this occurring include:
- Not running `npm install` or the equivalent package manager command
- Mistyping the case-sensitive name of the package and/or configuration
### Config Name Variations
Note that ESLint supports several config name formats:
- The `eslint-config-` config name prefix may be omitted for brevity, e.g. `extends: ["yours"]`
- [`@` npm scoped packages](https://docs.npmjs.com/cli/v10/using-npm/scope) put the `eslint-config-` prefix after the org scope, e.g. `extends: ["@org/yours"]` to load from `@org/eslint-config-yours`
- A `plugin:` prefix indicates a config is loaded from a shared plugin, e.g. `extends: [plugin:yours/recommended]` to load from `eslint-plugin-yours`
## Resolution
Common resolutions for this issue include:
- Upgrading all versions of all packages to their latest version.
- Adding the config as a `devDependency` in your `package.json`.
- Running `npm install` or the equivalent package manager command.
- Checking that the name in your config file matches the name of the config package.
## Resources
For more information, see:
- [Legacy ESLint configuration files](../configure/configuration-files-deprecated#using-a-shareable-configuration-package) for documentation on the legacy ESLint configuration format
- [Legacy ESLint configuration files > Using a shareable configuration package](../configure/configuration-files-deprecated#using-a-shareable-configuration-package) for documentation on using shareable configurations
- [Share Configurations](../../extend/shareable-configs) for documentation on how to define standalone shared configs
- [Create Plugins > Configs in Plugins](../../extend/plugins#configs-in-plugins) for documentation on how to define shared configs in plugins
---
---
title: ESLint couldn't find the plugin …
eleventyNavigation:
key: couldn't find the plugin
parent: troubleshooting
title: ESLint couldn't find the plugin …
---
## Symptoms
When using the [legacy ESLint config system](../configure/configuration-files-deprecated), you may see this error running ESLint after installing dependencies:
```plaintext
ESLint couldn't find the plugin "${pluginName}".
(The package "${pluginName}" was not found when loaded as a Node module from the directory "${resolvePluginsRelativeTo}".)
It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
npm install ${pluginName}@latest --save-dev
The plugin "${pluginName}" was referenced from the config file in "${importerName}".
```
## Cause
[Legacy ESLint configuration files](../configure/configuration-files-deprecated) specify shareable configs by their package name.
That package name is passed to the Node.js `require()`, which looks up the package under local `node_modules/` directories.
For example, the following ESLint config will first try to load a module located at `node_modules/eslint-plugin-yours`:
```js
module.exports = {
extends: ["plugin:eslint-plugin-yours/config-name"],
};
```
If the package is not found in any searched `node_modules/`, ESLint will print the aforementioned error.
Common reasons for this occurring include:
- Not running `npm install` or the equivalent package manager command
- Mistyping the case-sensitive name of the plugin
### Plugin Name Variations
Note that the `eslint-plugin-` plugin name prefix may be omitted for brevity, e.g. `extends: ["yours"]`.
[`@` npm scoped packages](https://docs.npmjs.com/cli/v10/using-npm/scope) put the `eslint-plugin-` prefix after the org scope, e.g. `extends: ["@org/yours"]` to load from `@org/eslint-plugin-yours`.
## Resolution
Common resolutions for this issue include:
- Upgrading all versions of all packages to their latest version.
- Adding the plugin as a `devDependency` in your `package.json`.
- Running `npm install` or the equivalent package manager command.
- Checking that the name in your config file matches the name of the plugin package.
## Resources
For more information, see:
- [Legacy ESLint configuration files](../configure/configuration-files-deprecated#using-a-shareable-configuration-package) for documentation on the legacy ESLint configuration format.
- [Configure Plugins](../configure/plugins) for documentation on how to extend from plugins.
- [Create Plugins](../../extend/plugins#configs-in-plugins) for documentation on how to define plugins.
---
---
title: Troubleshooting
eleventyNavigation:
key: troubleshooting
title: Troubleshooting
parent: use eslint
order: 11
---
This page serves as a reference for common issues working with ESLint.
## Configuration
- [`Circular fixes detected …`](./circular-fixes)
- [`TypeError: context.getScope is not a function`](./v9-rule-api-changes)
## Legacy (eslintrc) Configuration
- [`ESLint couldn't determine the plugin … uniquely`](./couldnt-determine-the-plugin-uniquely)
- [`ESLint couldn't find the config … to extend from`](./couldnt-find-the-config)
- [`ESLint couldn't find the plugin …`](./couldnt-find-the-plugin)
Issues oftentimes can be resolved by updating the to latest versions of the `eslint` package and any related packages, such as for ESLint shareable configs and plugins.
If you still can't figure out the problem, please stop by to chat with the team.
---
---
title: "TypeError: context.getScope is not a function"
eleventyNavigation:
key: v9 rule api changes
parent: troubleshooting
title: "TypeError: context.getScope is not a function"
---
## Symptoms
When using ESLint v9.0.0 or later with a plugin, you may see one of the following errors:
```plaintext
TypeError: context.getScope is not a function
TypeError: context.getAncestors is not a function
TypeError: context.markVariableAsUsed is not a function
TypeError: context.getDeclaredVariables is not a function
```
## Cause
ESLint v9.0.0 introduces [changes to the rules API](https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/) that plugin rules use, which included moving some methods from the `context` object to the `sourceCode` object. If you're seeing one of these errors, that means the plugin has not yet been updated to use the new rules API.
## Resolution
Common resolutions for this issue include:
- Upgrade the plugin to the latest version.
- Use the [compatibility utilities](https://eslint.org/blog/2024/05/eslint-compatibility-utilities/) to patch the plugin in your config file.
::: important
If you are already using the latest version of the plugin and you need to use the compatibility utilities to make the plugin work with ESLint v9.0.0 and later, make sure to open an issue on the plugin's repository to ask the maintainer to make the necessary API changes.
:::
## Resources
For more information, see:
- [Configure Plugins](../configure/plugins) for documentation on how to configure plugins
- [Create Plugins](../../extend/plugins#configs-in-plugins) for documentation on how to define plugins
---
---
eleventyNavigation:
key: Version Support
url: https://eslint.org/version-support/
parent: use eslint
title: Version Support
order: 10
---