no-unused-vars
Disallow variables, functions, imports, and parameters that are never used
A name that's declared and never read is clutter at best. Often it points to a bug. Maybe you computed a value and then used a different name, or a refactor left an import behind.
"Used" means read. A variable that's only assigned to or incremented isn't used, and neither is a function that only calls itself. Anything you export is used.
--fix-suggestions removes the declaration, but only if that can't change what the program does: an unused import, function or class, or a variable set to a plain value. const sent = sendEmail(user); stays, because removing it would also remove the call. So do parameters, names in a destructuring pattern, and the top level of a script that's neither an ES module nor CommonJS, which a web page can use. With an ESLint config file the suggestions are ESLint's.
An unused import always goes. import { setup } from "./polyfills"; is removed as a whole, so the module is no longer loaded. import setup from "./polyfills"; becomes import "./polyfills";, which is how you load a module only for its side effects.
To keep a name that you don't use, start it with _.
This rule is on by default in JavaScript files. In TypeScript files, @typescript-eslint/no-unused-vars is on instead.
Configure#
On by default as a warning. To turn it off:
[lint.rules]
"no-unused-vars" = "off" # or "error"Every option, set to its default:
[lint.rules]
"no-unused-vars" = ["warn", {
vars = "all", # "all" or "local"
varsIgnorePattern = "^_",
args = "after-used", # "all", "after-used" or "none"
argsIgnorePattern = "^_",
caughtErrors = "all", # "all" or "none"
caughtErrorsIgnorePattern = "^_",
destructuredArrayIgnorePattern = "^_",
ignoreRestSiblings = true,
ignoreClassWithStaticInitBlock = false,
ignoreUsingDeclarations = false,
reportUsedIgnorePattern = false,
}]Examples#
import { readFilereadFile is defined but never used., writeFile } from "node:fs/promises";
let savedsaved is assigned a value but never used. = 0;
async function savesave is defined but never used.(path, data, optionsoptions is defined but never used.) {
await writeFile(path, data);
saved++;
}import { writeFile } from "node:fs/promises";
let saved = 0;
export async function save(path, data) {
await writeFile(path, data);
saved++;
return saved;
}An unused parameter is only reported if it comes after the last one that's used, because you can't remove the others:
export const doubled = items.map((item, index) => index * 2);A name that starts with _ is unused on purpose:
export function onMessage(_event) {}
const [_first, second] = items;
send(second);A component that only appears in JSX is used:
import Button from "./button";
export const App = () => <Button />;Options#
[lint.rules]
no-unused-vars = ["error", { args = "all" }]An option you don't set keeps its default. With an ESLint config the defaults are ESLint's: no patterns, and ignoreRestSiblings is false.
| Option | Default | What it does |
|---|---|---|
vars | "all" | "local" skips globals: the names in /* global */ comments and the top-level variables of a classic script. The top level of a module or a CommonJS file is still checked. |
varsIgnorePattern | "^_" | Regular expression for variable names that may be unused. |
args | "after-used" | "all" reports every unused parameter, "none" reports none. |
argsIgnorePattern | "^_" | Like varsIgnorePattern, for parameters. |
caughtErrors | "all" | "none" allows an unused error in catch (error). |
caughtErrorsIgnorePattern | "^_" | Like varsIgnorePattern, for the catch parameter. |
destructuredArrayIgnorePattern | "^_" | Like varsIgnorePattern, for names in const [a, b] = list. |
ignoreRestSiblings | true | Allow unused names next to a ...rest in object destructuring. |
ignoreClassWithStaticInitBlock | false | Allow an unused class that has a static {} block, which runs anyway. |
ignoreUsingDeclarations | false | Allow unused using and await using variables, which are disposed of anyway. |
reportUsedIgnorePattern | false | Report a name that matches one of the patterns and is used. |
You can pass a string instead of the object, "all" or "local", to set vars.
With { "args": "all" }, an unused parameter before a used one is reported too:
{ "args": "all" }1 problemexport const doubled = items.map((itemitem is defined but never used., index) => index * 2);The "^_" patterns still apply, so _item isn't:
{ "args": "all" }No problemsexport const doubled = items.map((_item, index) => index * 2);ignoreRestSiblings is for taking properties out of an object:
const { password, ...publicUser } = user;
send(publicUser);{ "ignoreRestSiblings": false }1 problemconst { passwordpassword is assigned a value but never used., ...publicUser } = user;
send(publicUser);{ "varsIgnorePattern": "^_", "reportUsedIgnorePattern": true }1 problemconst _timeout_timeout is marked as ignored but is used. Used vars must not match /^_/u. = 500;
wait(_timeout);By default, a name in a /* global */ comment that the file never uses is reported too:
/* global analyticsanalytics is defined but never used. */
console.log("ready");"local"No problems/* global analytics */
console.log("ready");