Nub's phantom detector scans published npm packages for undeclared dependencies. The results are available as a standalone package on npm, with the source, data and scan records on GitHub.

nub add -D @nubjs/extensions
import { packageExtensions } from '@nubjs/extensions';

Nub bundles a snapshot of this database for dependency resolution. There is no need to install the package to use it with Nub; the standalone export is for other tools and package managers.

Using the data

The export is an array of [selector, extension] pairs, using the same format as @yarnpkg/extensions. Each selector identifies a package and version range; its extension supplies missing dependency declarations or peer metadata.

import { packageExtensions } from '@nubjs/extensions';

const extensions = Object.fromEntries(packageExtensions);

For tools that read JSON directly, the package also exports @nubjs/extensions/package-extensions.json. The repository's JSON dataset includes rules, version-specific evidence and scan provenance. Weekly npm download estimates are available separately.

pnpm and Yarn

Installing the npm package alone does not enable its rules in pnpm or Yarn. Merge the generated configuration into the appropriate project file, then run the package manager's install command:

Package managerProject fileGenerated configuration
Yarn 2 and newer.yarnrc.ymlYarn configuration
pnpm 10 and newerpnpm-workspace.yamlpnpm workspace configuration
pnpm 9The pnpm field in package.jsonpnpm package configuration

For example, this entry supplies a dependency that @nrwl/devkit imports without declaring:

packageExtensions:
  "@nrwl/devkit@*":
    dependencies:
      tslib: "*"

The generated Yarn configuration includes a logFilters block to suppress warnings about rules for packages that are not installed. Keep that block when importing the full database.

See the pnpm and Yarn settings references for the configuration format.

Coverage and updates

The repository has a daily scan of the top 10,000 npm packages by downloads and publishes an npm update when extension rules change. It retains Yarn's package extensions and supports fixed rules for cases that static analysis cannot infer. Nub's bundled snapshot updates separately from the npm package.

A finding records the version examined, not every version of a package. Some references belong to optional integrations or published type declarations rather than unconditional runtime imports. Check the rule's version range and evidence when investigating a package.

Fixing a package

Declare the dependencies used by the published package, including its type declarations:

UsageManifest field
A library the package needs its own copy ofdependencies
A compatible host supplied by the applicationpeerDependencies
A consumer-selected integrationpeerDependencies with optional peer metadata
A dependency whose failed or omitted installation is handledoptionalDependencies
A tool used only for development or buildsdevDependencies

Optional integrations

For an optional React integration, declare the peer and mark it optional, using the versions the package supports:

package.json
{
  "peerDependencies": {
    "react": "^18.0.0 || ^19.0.0"
  },
  "peerDependenciesMeta": {
    "react": { "optional": true }
  }
}

The optional marker does not make an unconditional import safe when React is absent. Keep optional integrations out of the default entry point's eager import graph. Unlike an optional peer, an optionalDependencies entry requests installation unless optional dependencies are omitted; runtime code must handle its absence.

See npm's optional peer documentation.

Testing the fix

  1. Pack the package and install its tarball in a fresh consumer using Yarn Plug'n'Play without fallback, or pnpm with hoisting disabled.
  2. Exercise the public runtime, CLI and type entry points.
  3. Test optional integrations with their peers installed and absent. The base entry point should work in both cases.
  4. Report the corrected version so the database's affected range can be updated.

Contributing

Open an issue or pull request with the package name, version, import path and a reproduction. Corrections, missing entries and version-range updates are welcome.

Fixed rules belong in inputs/manual-extensions.json, not the generated output. They are merged into the database on every rebuild, including rules the detector cannot infer. See the repository instructions for the format and checks.