Skip to content

noUnusedVariables (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": "error"
}
}
}
}

Disallow unused variables.

There is an exception to this rule: variables that start with underscore, e.g. let _something;.

The pattern of having an underscore as a prefix of a variable is a very diffuse pattern among programmers, and Biome follows it.

This rule won’t report unused imports. If you want to report unused imports, enable noUnusedImports.

let a = 4;
a++;
code-block.js:1:5 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This variable a is unused.

> 1 │ let a = 4;
│ ^
2 │ a++;
3 │

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ Unsafe fix: If this is intentional, prepend a with an underscore.

1 │ - let·a·=·4;
2 │ - a++;
1 │ + let·_a·=·4;
2 │ + _a++;
3 3 │

function foo() {}
code-block.js:1:10 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This function foo is unused.

> 1 │ function foo() {}
│ ^^^
2 │

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ Unsafe fix: If this is intentional, prepend foo with an underscore.

1 │ - function·foo()·{}
1 │ + function·_foo()·{}
2 2 │

function foo() {
foo();
}
code-block.js:1:10 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This function foo is unused.

> 1 │ function foo() {
│ ^^^
2 │ foo();
3 │ }

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ Unsafe fix: If this is intentional, prepend foo with an underscore.

1 │ - function·foo()·{
2 │ - ····foo();
1 │ + function·_foo()·{
2 │ + ····_foo();
3 3 │ }
4 4 │

const foo = () => {
foo();
};
code-block.js:1:7 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This variable foo is unused.

> 1 │ const foo = () => {
│ ^^^
2 │ foo();
3 │ };

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ Unsafe fix: If this is intentional, prepend foo with an underscore.

1 │ - const·foo·=·()·=>·{
2 │ - ····foo();
1 │ + const·_foo·=·()·=>·{
2 │ + ····_foo();
3 3 │ };
4 4 │

export function f<T>() {}
code-block.ts:1:19 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This type parameter T is unused.

> 1 │ export function f<T>() {}
│ ^
2 │

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ Unsafe fix: If this is intentional, prepend T with an underscore.

1 │ - export·function·f<T>()·{}
1 │ + export·function·f<_T>()·{}
2 2 │

const { brand } = car;
code-block.js:1:9 lint/correctness/noUnusedVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This variable brand is unused.

> 1 │ const { brand } = car;
│ ^^^^^
2 │

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

function foo(b) {
console.log(b)
};
foo();
export function foo(_unused) {}
function used_overloaded(): number;
function used_overloaded(s: string): string;
function used_overloaded(s?: string) {
return s;
}
used_overloaded();

By default, unused variables declared inside destructured objects are ignored if the destructuring pattern also contains a rest property. (See the rule options if you want to enable these checks).

const car = { brand: "Tesla", year: 2019, countryCode: "US" };
const { brand, ...rest } = car;
console.log(rest);

TypeScript namespaces that participate in declaration merging with an exported or referenced value of the same name are not flagged.

const MyComponent = () => {};
namespace MyComponent {
export type Props = { id: string };
}
export default MyComponent;

In Astro files, a top-level interface or a type alias named Props is always ignored as it’s implicitly read by the framework.

---
interface Props {
name: string;
greeting?: string;
}
---

Whether to ignore unused variables declared inside destructured objects containing rest properties (such as const { a, b, ...rest } = obj.

Default: true

If this option is set to false, unused rest siblings either have to be renamed or removed.

biome.json
{
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": {
"level": "on",
"options": {
"ignoreRestSiblings": false
}
}
}
}
}
}
const car = { brand: "Tesla", year: 2019, countryCode: "US" };
const { brand, ...other } = car;
console.log(other);
code-block.js:2:9 lint/correctness/noUnusedVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This variable brand is unused.

1 │ const car = { brand: "Tesla", year: 2019, countryCode: "US" };
> 2 │ const { brand, ...other } = car;
│ ^^^^^
3 │ console.log(other);
4 │

ℹ Unused variables are often the result of typos, incomplete refactors, or other sources of bugs.

ℹ You can enable the ignoreRestSiblings option to ignore unused variables inside destructured objects with rest properties.

const car = { brand: "Tesla", year: 2019, countryCode: "US" };
const { brand: _, ...other } = car;
console.log(other);

An object that allows excluding matching identifiers from this rule.

Each key may specify an array of identifiers to ignore which are case-sensitive matches.

The special string "*" can serve two purposes:

  • As a key it refers to every kind of identifier.
  • As a value it may be used to match all identifiers in the respective group, effectively disabling this rule for that group.

Allowed keys:

  • "*": Applies to all identifiers
  • "class": Applies to class names
  • "function": Applies to function names
  • "interface": Applies to interface names
  • "typeAlias": Applies to type aliases
  • "typeParameter": Applies to type parameters
  • "variable": Applies to variable names

Default: {} (no variables are excluded)

For example, you can exclude all unused identifiers named ignored regardless of their kind, all unused classes named IgnoredClass, and all unused functions with the following configuration.

A variable named unusedVariable is still flagged as unused, and so is a class named UnusedClass since they don’t fall under the exceptions.

biome.json
{
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": {
"level": "on",
"options": {
"ignore": {
"*": [
"ignored"
],
"class": [
"IgnoredClass"
],
"function": [
"*"
]
}
}
}
}
}
}
}
const ignored = 0;
class IgnoredClass {}
function ignoredFunction() {}
const unusedVariable = 0;
class UnusedClass {}