Unused code
Three rules find code that nothing uses. The design follows Knip.
The rules are in the nursery category, so they are off by default.
| Rule | What it reports |
|---|---|
unused-exports | Exports that no module imports, members of enums and namespaces that no code reads, and bindings that a module exports under two names. |
unused-packages | Packages that a package.json declares and that none of its modules imports. |
unused-modules | Source modules that no path from an entry point reaches. |
Enable the rules
{
"rules": {
"unused-exports": "warn",
"unused-packages": "error",
"unused-modules": "error"
}
}This is the output for a small project:
error[unused-packages]: `unused-dep` is in `dependencies` but no module imports it
--> package.json:6:5
|
6 | "unused-dep": "1.0.0",
| ^
error[unused-modules]: this module cannot be reached from any entry point
--> src/orphan.ts
warn[unused-exports]: unused export `renamed`
--> src/api.ts:5:20
|
5 | export { helper as renamed };
| ^
warn[unused-exports]: unused member `Color.Green`
--> src/util.ts:8:3
|
8 | Green,
| ^Entry points
An entry point is a module whose exports are public. The unused-exports rule does not report the exports of an entry point.
The unused-modules rule starts at the entry points and reports the modules that no path from them reaches.
Oxcruise finds entry points from these sources:
- The files that each
package.jsonpublishes:main,module,types,binandexports. Oxcruise maps build output back to source with theoutDirandrootDirof the tsconfig. index,mainandclifiles, only at the package root or in itssrcfolder.- Files that the tools in
package.jsonload by convention, such as tests, routes and configuration files. - The
entriesoption of the rules and theentriesof plugins. - Modules that have the
// oxcruise-ignore-filecomment.
The unused-exports rule has one more source of entry points: the modules that no other module imports.
The unused-modules rule does not use this source, because then it would report no module that nothing imports.
Conventions
A convention is a small entry in a table. It says which files a tool loads and which packages it uses.
A convention is active in a package.json that declares one of its packages.
The conventions table lists all of them.
Use the conventions option of a rule to switch conventions off or to select some.
Production mode
Run npx oxcruise --production or set production: true in the options of the rules.
In production mode, tests are not entry points and do not count as users of an export.
The unused-packages rule also skips devDependencies.
An export that only a test uses is then a violation.
Exports and symbols
unused-exports needs the exports of each module and the names that each import uses.
Oxcruise calls these symbols. It extracts them in the same pass as the dependencies, but only when something needs them:
- a rule that needs them is on, such as
unused-exports - a plugin declares
needs: ["symbols"] - you use
--symbols, thesymbolsconfig key orcruise({ symbols: true })
Without symbols, nothing changes in speed or output.
With symbols, the json format lists the exports of each module and the names of each dependency.
Limits
- A module that you import in a way that Oxcruise cannot follow counts as a user of all its exports. Examples are
require, a dynamicimport()and a namespace that code passes as a value. - Single-file components (Vue, Svelte and Astro) are never narrowed. Their templates use bindings that the script block does not mention.
- Oxcruise does not check class members, catalogs, binaries or JSDoc visibility tags.
- A violation of
unused-packagesis in apackage.json. A comment cannot suppress it. Use theignoreoption.
To suppress one export, put // oxcruise-ignore-next-line unused-exports above it.
Use --fix to repair some violations automatically.

