I was never really concerned about the size of node_modules — my thinking was that you should not care too much about the tools you need to do the job. If you need a 20 kg hammer to drive a nail, you just take it. The same story with the node_modules , it may weight a few kilobytes or a few megabytes because our imaginary hammer comes with a set of heavy nails, right? Well, maybe, in theory.

Let’s drop that fancy analogy and look at real-world examples. I will examine some @angular/cli dependencies — but only because it’s quite a big library. I don’t want to make it look bad — it’s just a good representation of an average package. I installed it in the empty directory using npm@5.5.1. Npm reported “added 976 packages in 107.13s” after installation (that’s 141 megabytes on disk).

Okay so cli package it’s quite a robust library and its list of dependencies is a bit too long but perhaps all of them are needed. Let’s focus at the first selected package common-tags . Quick look at its documentation and you can say that it’s some kind of utils library with a number of common methods to work with the text. So far so good — general methods, easy to reuse.

Just one little flaw — in deps of common-tags we see babel-runtime . A bit surprising, we just need some common text functions but — hey — it’s 2017 JS for you. Oh wait, it turns out that it wants core-js and regenerator-runtime . Fortunately it ends here and — what’s more — core-js is also utils library, quite a big one honestly! It has so many functions inside I bet a lot of other packages will be using it!

Not really. Only babel-runtime has it in its deps. Oopsie.

And returning to the starting point, cli uses only 3 (trivial) methods from common-tags — stripIndents , stripIndent , oneLine . Oopsie daisy.

In order to use these 3 methods node_modules needs 1826 files. And that’s just 4 of mentioned 976 installed packages.

This is your dream about lightweight package collapsing

The next dependency is core-object — it downloaded in total of 8 packages and 45 files — so not so bad. And other packages use these files too, mostly chalk .

The real bummer is 6 of these 8 are dependencies of chalk and chalk is used only once in core-object to paint yellow deprecation message.

Other random findings:

few packages to tackle the topic of “querystring”

some attempts for assert methods varying in complexity from minimalistic-assert to assert-plus

to dozens of various is-* packages

packages a lot of packages to “prettifyfifafiying-whatever” errors and console prints

of packages to “prettifyfifafiying-whatever” errors and console prints hundreds of polyfills/shims or reimplementation of native methods

of course previous asserts sit in node_modules next to full lodash

next to full … and some partial methods from lodash as separate deps

And, by random, I mean just picking some packages and brief searching for similar ones which was often really easy because the packages had similar names.