Reduce the size of node_modules

Measure dependency storage, omit development tools from runtime installs, and assess pruning, deduplication, shared stores, and bundling.

Best practices
Illustration of files, modules, and their dependencies

Start by identifying what occupies the space. A development checkout, a package-manager cache, and a deployed container image have different storage requirements; reducing one does not necessarily shrink the others.

Keep development tools out of runtime installs

After building the application in a stage that includes its build tools, create the runtime dependency tree with:

npm ci --omit=dev

This requires a valid lockfile consistent with the manifest. Do not omit a package that the running application actually needs. Test lifecycle scripts, native addons, generated files, and optional dependency behavior in the target environment.

Remove packages the dependency tree no longer needs

npm prune --dry-run
npm prune
npm dedupe --dry-run
npm dedupe

prune removes extraneous packages, not every package absent from the root manifest. Transitive dependencies are still required. A package installed and saved in package.json will remain until you remove that dependency intentionally.

dedupe can share compatible dependency versions at a higher level of the tree. It cannot combine incompatible requirements. Review lockfile changes and run tests after dependency changes.

Use filesystem tools to locate large directories, then npm ls package-name or npm explain package-name to identify why a package is present. Choose an inspection tool only after reviewing its source and execution behavior; running an unfamiliar command through npx can download and execute code.

Consider a shared package store

pnpm can share package content through its content-addressable store, using links or copies according to its configuration and filesystem capabilities. This can reduce storage across multiple projects. There is no universal savings percentage, and apparent directory sizes may count linked content in misleading ways.

Do not manually edit package files in a shared installation. Hard links are not an inherent read-only protection; use supported patching or dependency-update mechanisms. A migration also changes the lockfile and dependency resolution layout, so validate the project before replacing npm in CI.

Yarn Plug'n'Play can avoid a conventional node_modules tree, but dependencies still occupy cache storage and some tools require compatibility adjustments.

Reduce the dependency set or deployed artifact

Audit packages whose features are mostly unused. Smaller alternatives or native APIs may help, but compare locale support, timezone behavior, and other functionality before replacing a library. Importing a single function may shrink a browser bundle without reducing the installed package's disk footprint.

A server bundle can reduce deployed files, but native addons, dynamic loading, external packages, and runtime assets may still need separate packaging. Container layers and caches also affect image size. Removing npm's download cache can shrink an image layer when done in the same build step, but does not shrink node_modules itself; routine forced cache cleaning is unnecessary.

Commit the manifest and matching lockfile instead of node_modules. Use the matching package manager in CI: npm ci does not consume a pnpm or Yarn lockfile. Reinstalling the same dependency tree generally reproduces its size rather than solving the underlying problem.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting