---
url: /docs/guide/usage/linter/rules/eslint/no-unused-vars.md
---

### What it does

Disallows variable declarations, imports, or type declarations that are
not used in code.

### Why is this bad?

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.

```ts
// `b` is unused; this indicates a bug.
function add(a: number, b: number) {
  return a;
}
console.log(add(1, 2));
```

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 (`var bar = foo`)
* It is passed into a function or constructor as an argument (`doSomething(foo)`)
* It is read inside of a function that is passed to another function
  (`doSomething(function() { foo(); })`)
* It is exported (`export const foo = 42`)
* It is used as an operand to TypeScript's `typeof` operator (`const bar:
  typeof foo = 4`)

A variable is *not* considered to be used if it is only ever declared
(`var foo = 5`) or assigned to (`foo = 7`).

#### Types

This rule has full support for TypeScript types, interfaces, enums, and
namespaces.

A type or interface `Foo` is considered to be used if it is used in any
of the following ways:

* It is used in the definition of another type or interface.
* It is used as a type annotation or as part of a function signature.
* It is used in a cast or `satisfies` expression.

A type or interface is *not* considered to be used if it is only ever
used in its own definition, e.g. `type Foo = Array<Foo>`.

Enums and namespaces are treated the same as variables, classes,
functions, etc.

#### Ignored Files

This rule ignores `.d.ts`, `.astro`, `.svelte` and `.vue` files entirely. Variables,
classes, interfaces, and types declared in `.d.ts` files are generally
used by other files, which are not checked by Oxlint. Since Oxlint does
not support parsing template syntax, this rule cannot tell if a variable
is used or unused in a Vue / Svelte / Astro file.

#### Exported

The original ESLint rule recognizes `/* exported variableName */`
comments as a way to indicate that a variable is used in another script
and should not be considered unused. Since ES modules are now a TC39
standard, Oxlint does not support this feature.

### Examples

Examples of **incorrect** code for this rule:

```javascript
/* no-unused-vars: "error" */
/* if you have `some_unused_var` defined as a global in .oxlintrc.json */

// It checks variables you have defined as global
some_unused_var = 42;

var x;

// Write-only variables are not considered as used.
var y = 10;
y = 5;

// A read for a modification of itself is not considered as used.
var 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;
}
```

```ts
type A = Array<A>;

enum Color {
  Red,
  Green,
  Blue,
}
```

Examples of **correct** code for this rule:

```js
/* no-unused-vars: "error" */

var 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;
}
```

```ts
export const x = 1;
const y = 1;
export { y };

type A = Record<string, unknown>;
type B<T> = T extends Record<infer K, any> ? K : never;
const x = "foo" as B<A>;
console.log(x);
```

Examples of **incorrect** code for `/* exported variableName */` operation:

```js
/* exported global_var */

// Not respected, use ES modules instead.
var global_var = 42;
```

## Configuration

### args

type: `"after-used" | "all" | "none"`

Controls how unused arguments are checked.

#### `"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

### argsIgnorePattern

type: `string`

Specifies exceptions to this rule for unused arguments. Arguments whose
names match this pattern will be ignored.

By default, names starting with `_` are ignored, except for the bare `_`
parameter. If options are configured with an object, this will default
to \[`None`]. Note that this behavior deviates from both ESLint and
TypeScript-ESLint, which never provide a default pattern.

#### Example

Examples of **correct** code for this option when the pattern is `^_`:

```javascript
function foo(_a, b) {
  console.log(b);
}
foo(1, 2);
```

### caughtErrors

type: `"all" | "none"`

Used for `catch` block validation.

#### `"all"`

All named arguments must be used.

#### `"none"`

Do not check error objects.

### caughtErrorsIgnorePattern

type: `string`

Specifies exceptions to this rule for errors caught within a `catch` block.
Variables declared within a `catch` block whose names match this pattern
will be ignored.

#### Example

Examples of **correct** code when the pattern is `^ignore`:

```javascript
try {
  // ...
} catch (ignoreErr) {
  console.error("Error caught in catch block");
}
```

### destructuredArrayIgnorePattern

type: `string`

This option specifies exceptions within destructuring patterns that will
not be checked for usage. Variables declared within array destructuring
whose names match this pattern will be ignored.

By default this pattern is unset.

#### Example

Examples of **correct** code for this option, when the pattern is `^_`:

```javascript
const [a, _b, c] = ["a", "b", "c"];
console.log(a + c);

const {
  x: [_a, foo],
} = bar;
console.log(foo);

let _m, n;
foo.forEach((item) => {
  [_m, n] = item;
  console.log(n);
});
```

### fix

type: `object`

Controls which `no-unused-vars` auto-fixes are emitted.

When omitted, both `imports` and `variables` default to `"suggestion"`,
preserving the current behavior.

NOTE: This option is experimental and may change based on feedback.

Fine-grained auto-fix controls for `no-unused-vars`.

#### fix.imports

type: `"off" | "suggestion" | "fix" | "safe-fix"`

Controls auto-fixes for unused imports.

##### `"off"`

Disable auto-fixes for this symbol kind.

##### `"suggestion"`

Emit suggestion-style fixes (current behavior).

##### `"fix"`

Emit fix-style fixes.

##### `"safe-fix"`

Like `Fix`, but does not mark them as dangerous.
Only applicable for imports, unavailable for variables.

#### fix.variables

type: `"off" | "suggestion" | "fix" | "safe-fix"`

Controls auto-fixes for unused variables (including catch bindings).

##### `"off"`

Disable auto-fixes for this symbol kind.

##### `"suggestion"`

Emit suggestion-style fixes (current behavior).

##### `"fix"`

Emit fix-style fixes.

##### `"safe-fix"`

Like `Fix`, but does not mark them as dangerous.
Only applicable for imports, unavailable for variables.

### ignoreClassWithStaticInitBlock

type: `boolean`

default: `false`

The `ignoreClassWithStaticInitBlock` option is a boolean. 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.

#### Example

Examples of **incorrect** code for the `{ "ignoreClassWithStaticInitBlock": true }` option

```javascript
/* 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

```javascript
/* no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/

class Foo {
  static {
    let bar = "some string";

    console.log(bar);
  }
}
```

### ignoreRestSiblings

type: `boolean`

default: `false`

Using a Rest property 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.

#### Example

Examples of **correct** code when this option is set to `true`:

```js
// 'foo' and 'bar' were ignored because they have a rest property sibling.
var { foo, ...coords } = data;

var bar;
({ bar, ...coords } = data);
```

### ignoreUsingDeclarations

type: `boolean`

default: `false`

When set to `true`, the rule will ignore variables declared with
`using` or `await using` declarations, even if they are unused.

This is useful when working with resources that need to be disposed
via the explicit resource management proposal, where the primary
purpose is the disposal side effect rather than using the resource.

#### Example

Examples of **correct** code for the `{ "ignoreUsingDeclarations": true }` option:

```javascript
/* no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/

using resource = getResource();
await using anotherResource = getAnotherResource();
```

### reportUsedIgnorePattern

type: `boolean`

default: `false`

The `reportUsedIgnorePattern` option is a boolean.
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.

#### Example

Examples of **incorrect** code for the `{ "reportUsedIgnorePattern": true }` option:

```javascript
/* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/

var firstVarIgnored = 1;
var secondVar = 2;
console.log(firstVarIgnored, secondVar);
```

Examples of **correct** code for the `{ "reportUsedIgnorePattern": true }` option:

```javascript
/* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/

var firstVar = 1;
var secondVar = 2;
console.log(firstVar, secondVar);
```

### reportVarsOnlyUsedAsTypes

type: `boolean`

default: `false`

The `reportVarsOnlyUsedAsTypes` option is a boolean.

If `true`, the rule will also report variables that are only used as types.

#### Examples

Examples of **incorrect** code for the `{ "reportVarsOnlyUsedAsTypes": true }` option:

```javascript
/*  no-unused-vars: ["error", { "reportVarsOnlyUsedAsTypes": true }] */

const myNumber: number = 4;
export type MyNumber = typeof myNumber
```

Examples of **correct** code for the `{ "reportVarsOnlyUsedAsTypes": true }` option:

```javascript
export type MyNumber = number;
```

Note: even with `{ "reportVarsOnlyUsedAsTypes": false }`, cases where the value is
only used a type within itself will still be reported:

```javascript
function foo(): typeof foo {}
```

### vars

type: `"all" | "local"`

Controls how usage of a variable in the global scope is checked.

#### `"all"`

All variables are checked for usage, including those in the global scope.

#### `"local"`

Checks only that locally-declared variables are used but will allow
global variables to be unused.

### varsIgnorePattern

type: `string`

Specifies exceptions to this rule for unused variables. Variables whose
names match this pattern will be ignored.

By default, this pattern is `^_` unless options are configured with an
object. In this case it will default to \[`None`]. Note that this
behavior deviates from both ESLint and TypeScript-ESLint, which never
provide a default pattern.

#### Example

Examples of **correct** code for this option when the pattern is `^_`:

```javascript
var _a = 10;
var b = 10;
console.log(b);
```

## How to use

## Version

This rule was added in v0.7.0.

## References
