Duplicate packages

Detect dependencies that get bundled more than once and report them

Overview

When several of your dependencies depend on different versions of the same package — or the same version resolved from different locations (for example, distinct peer-dependency variants under pnpm) — that package ends up bundled more than once. This inflates bundle size and can cause subtle bugs when two copies of a library don't share state.

Packem ships a built-in detector that walks the final module graph after each build and reports any package that was bundled multiple times, along with the files that imported each copy.

It is enabled by default.

Example output

WARNING  packages ms is bundled multiple times!

  ms:
    - 2.0.0 imported by packages/pkg1/index.js
    - 2.1.3 imported by packages/pkg2/index.js

A runnable demo lives in examples/duplicated-packages.

Configuration

Configure (or disable) it through the rollup.detectDuplicated option:

import { defineConfig } from "@visulima/packem/config";

export default defineConfig({
  rollup: {
    detectDuplicated: {
      // Stop reporting specific packages/versions. Use "*" to ignore all versions.
      ignore: {
        axios: ["0.27.2"],
        lodash: ["*"],
      },

      // Only report duplicates imported directly by your own source,
      // ignoring those pulled in transitively by another dependency.
      // @default true
      deep: true,

      // Fail the build (non-zero exit) when duplicates are found.
      // @default false
      throwErrorWhenDuplicated: false,

      // Build a custom report from the collected data instead of the default one.
      // customErrorMessage: (packagesInfo) => `...`,
    },
  },
});

Disable it

import { defineConfig } from "@visulima/packem/config";

export default defineConfig({
  rollup: {
    detectDuplicated: false,
  },
});

Options

OptionTypeDefaultDescription
deepbooleantrueWhen false, only duplicates imported directly by your own source are reported (transitive ones are ignored).
ignoreRecord<string, string[]>{}Packages/versions to skip. Pass "*" as a version to ignore every version of that package.
throwErrorWhenDuplicatedbooleanfalseFail the build when duplicates are detected instead of only warning.
customErrorMessage(packagesInfo: PackagesInfo) => stringReplace the default report with your own message, built from the collected duplicate map.

Notes

  • The detector inspects the bundled module graph, so dependencies that are externalized (not bundled) are never flagged.
  • Detection runs at buildEnd, which means it works correctly with Packem's build cache and watch mode — there is no extra module resolution cost.
  • Set detectDuplicated: false if you don't want the check (for example, in a project that intentionally bundles multiple versions).

Tests

See packages/packem/__tests__/intigration/detect-duplicated.test.ts.

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues