Skip to content

Latest commit

 

History

199 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

find-unused-exports

A Node.js CLI and equivalent JS API to find unused ECMAScript module exports in a project.

To achieve this the whole project is analyzed at once, something ESLint can’t do as it lints files in isolation.

  • The npx find-unused-exports script is handy for finding redundant code to remove in legacy projects.
  • Use the CLI command find-unused-exports in package test scripts, so that CI can prevent the addition of redundant code.

Installation

To install find-unused-exports with npm, run:

npm install find-unused-exports --save-dev

If the project has Babel configured, ensure the modules to analyze are not Babel ignored because this tool uses the Babel parser to scan module code for imports and exports.

Then, either use the CLI command find-unused-exports or import and use the function findUnusedExports.

Excluding modules

Exclude third party modules and build artifacts from analysis via an exclude glob. This is specified for the CLI command find-unused-exports via the argument --exclude-glob (relative to the current working directory), and for the function findUnusedExports via the option excludeGlob (relative to the current working directory specified by the option cwd, defaulting to process.cwd()).

By default TypeScript declaration files and node_modules directories are recursively excluded:

{**/{,*,.*}.d.{mts,cts,ts},**/node_modules/**}

When specifying a custom exclude glob, include what the default does. E.g. to also exclude a directory dist at the project root:

{**/{,*,.*}.d.{mts,cts,ts},**/node_modules/**,dist/**}

Don’t exclude modules you author as a way to ignore validly unused exports:

  • Accidental unused exports in the excluded modules won’t be detected.
  • The imports won’t be analyzed, potentially causing exports elsewhere in the project to be falsely considered unused.

See below for how to properly ignore specific exports in specific modules.

Ignoring unused exports

Ignore exports that are unused in a project for valid reasons:

  • If the project is a package intended to be used by other projects, the package exports may be unused.
  • If the project has configuration modules for tools, the exports are unused. E.g. the ESLint config file eslint.config.mjs has an unused default export.
  • If the project uses a framework that by convention consumes certain certain exports from project modules, they may be unused. E.g. in a Next.js project the directory pages modules have unused default exports.

Ignore exports map

A map of module file globs and export names to ignore as unused. The export name default ignores the default export, and * ignores all exports (usually a bad idea). This is specified for the CLI command find-unused-exports via the argument --ignore (relative to the current working directory), and for the function findUnusedExports via the option ignore (relative to the current working directory specified by the option cwd, defaulting to process.cwd()).

Examples

For a Next.js and ESLint project, a contrived ignore-unused-exports.json:

{
  "eslint.config.js": ["default"],
  "next.config.js": ["default"],
  "pages/**/*.js": [
    "default",
    "getServerSideProps",
    "getStaticPaths",
    "getStaticProps"
  ]
}

Then, using npx:

npx find-unused-exports --ignore "$(cat ignore-unused-exports.json)"

For a published package, to ignore all the unused exports in a package main index module, the ignore exports map may contain:

{
  "index.mjs": ["*"]
}

Please don’t publish a package main index module though, for optimal JavaScript module design.

It’s usually a bad idea to ignore every export with *; instead ignore specific export names to be able to detect other accidental unused exports.

Ignore comments

Ignore comments can be used anywhere in a module to ignore all or specific unused exports. They are line or block comments, with the format:

  1. Optional whitespace.
  2. ignore unused exports (case insensitive).
  3. Optional to only ignore specific exports:
    1. Optional spaces.
    2. The names of exports to ignore, separated by a , and optional spaces.
  4. Optional whitespace.

Examples

How to ignore all unused exports (usually a bad idea):

// ignore unused exports
export const a = true;
export default true;

How to ignore specific unused exports:

// ignore unused exports b, default
export const a = true;
export const b = true;
export default true;

Multiple comments can be used:

// ignore unused exports a
export const a = true;

// ignore unused exports b
export const b = true;

Comments are case-insensitive, except for the export names:

// iGnOrE UnUsEd eXpOrTs default

Line or block comments can be used:

/* ignore unused exports */

Requirements

Supported runtime environments:

  • Node.js versions ^22.22.2 || ^24.15.0 || >=26.0.0.

Projects must configure TypeScript to use types from the ECMAScript modules that have a // @ts-check comment:

CLI

Command find-unused-exports

Finds unused ECMAScript module exports in a project. If some are found, it reports them to stderr and exits with a 1 error status.

It implements the function findUnusedExports.

Arguments

Argument Default Description
--exclude-glob "{**/{,*,.*}.d.{mts,cts,ts},**/node_modules/**}" File glob pattern to exclude files from the --module-glob results, relative to the current working directory.
--ignore "{}" JSON ignore exports map of module file globs (relative to the current working directory) and export names to ignore as unused. The export name default ignores the default export, and * ignores all exports (usually a bad idea).
--import-map "{}" JSON import map, relative to the current working directory.
--module-glob "**/{,*,.*}.{mts,cts,ts,tsx,mjs,cjs,js,jsx}" Module file glob pattern, relative to the current working directory.
--resolve-file-extensions File extensions (without the leading ., multiple separated with , in preference order) to automatically resolve in extensionless import specifiers. Import specifier file extensions are mandatory in Node.js; if your project resolves extensionless imports at build time (e.g. Next.js, via webpack) mjs,js might be appropriate.
--resolve-index-files Should directory index files be automatically resolved in extensionless import specifiers. Node.js doesn’t do this by default; if your project resolves extensionless imports at build time (e.g. Next.js, via webpack) this argument might be appropriate. This argument only works if the argument --resolve-file-extensions is used.

Examples

Using npx in a standard Node.js project:

npx find-unused-exports

Using npx in a legacy webpack project that has ESM in .js files, extensionless import specifiers, and index.js files:

npx find-unused-exports --module-glob "**/*.js" --resolve-file-extensions js --resolve-index-files

Using npx in a project with an import map in a file import-map.json:

npx find-unused-exports --import-map "$(cat import-map.json)"

package.json scripts for a project that also uses eslint and prettier:

{
  "scripts": {
    "prettier": "prettier -c .",
    "eslint": "eslint",
    "find-unused-exports": "find-unused-exports",
    "test": "node --run prettier && node --run eslint && node --run find-unused-exports",
    "prepublishOnly": "node --run test"
  }
}

Exports

The npm package find-unused-exports features optimal JavaScript module design. It doesn’t have a main index module, so use deep imports from the ECMAScript modules that are exported via the package.json field exports:

About

A Node.js CLI and equivalent JS API to find unused ECMAScript module exports in a project.

Topics

Resources

Stars

58 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages