Tiny Packages, Big Challenges in NPM

Opinion / Post


The world of Node.js and its package manager, NPM, has revolutionised how we think about and manage dependencies in software development. However, this ecosystem is not without its challenges. One such challenge is the proliferation of micropackages, which, while seemingly innocuous, can cumulatively create a significant burden for developers and organisations alike. In this blog post, we will explore the nature of this issue, its underlying causes, potential solutions, and examine a real-world example to illustrate the sheer insanity of the problem. :whatthefuck:

The Plague

The term “micropackage” refers to small, often single-function packages in the NPM ecosystem. These packages typically accomplish very specific, sometimes trivial, tasks. On the surface, this approach seems to promote modularity and reusability, hallmarks of efficient software development. However, in practice, it leads to a phenomenon I refer to as the “micropackage plague”.

A Worked Example

To truly grasp the absurdity of the micropackage problem, let’s consider the case of developer Jon Schlinkert, known for creating an extensive array of such packages. Schlinkert’s repositories include a series of packages for ANSI colors, each dedicated to a single color: ansi-red, ansi-green, ansi-blue, and so on. This approach not only fragments what could be a single, manageable package into several smaller ones but also bloats the dependency tree unnecessarily.

1In the case you’re reading this Jon, sorry, it’s nothing personal.

Furthermore, Schlinkert’s portfolio includes packages like is-odd and is-even, which offer simple functionality to check if a number is odd or even. While these functions are elementary and could be easily integrated into larger projects, they exist as standalone packages. The is-even package takes ludicrousness to another level by depending on is-odd to determine if a number is even.

And it doesn’t stop there. Here is everything npm install is-even actually pulls in:

Everything is-even installs Installing is-even 1.0.0 pulls in is-odd 0.1.2, which needs is-number 3.0.0, which needs kind-of 3.2.2, which needs is-buffer 1.1.6: five packages and 4,213 bytes of code to compute n % 2 === 0. Weekly downloads run from 443 thousand for is-even to 225 million for is-number. is-even@1.0.0254 bytes of code442.6kdownloads a week depends on is-odd@0.1.2434 bytes of code971.8kdownloads a week depends on is-number@3.0.0420 bytes of code225.2Mdownloads a week depends on kind-of@3.2.22,407 bytes of code135.3Mdownloads a week depends on is-buffer@1.1.6698 bytes of code67.9Mdownloads a week what it all works outfor is-even(n) n % 2 === 0 5 packages4,213 bytes of index.js4 levels of dependencies4 of the 5 by one author npm, week of 2 to 8 November 2026;downloads count every version

Through all these micropackages, he seems to have achieved something. If you’re a web developer you probably have some of his code on your computer. If you go to your node_modules and do a little grep -r jonschlinkert it’s pretty likely he’ll show up. Through creating hundreds of packages that depend on each other, you end up with ansi-red being downloaded 6.5M times a week, when nobody is going and including ansi-red themselves. We have entered a weird fractal of CV-boosting where NPM metrics are gamified, to make you look like a more impactful developer than you maybe are.

These examples highlight the core issues of the micropackage plague:

  1. Dependency Bloat and Redundancy: Instead of a single package to handle ANSI colors, there are multiple packages, one for each color. This leads to a bloated node_modules directory and an inflated dependency tree.
  2. Unnecessary Complexity: For something as straightforward as checking if a number is even, relying on another package (is-odd) adds unnecessary complexity and dependency.
  3. Maintenance Overhead: Each of these packages, no matter how small, requires ongoing maintenance for updates, security, and compatibility. This only gets more difficult as the number of packages in active use increases.

This level of fragmentation and redundancy in package management illustrates just how far the micropackage issue can go, impacting the efficiency and manageability of JS development in general.

The Cause

The root of the micropackage problem lies in a combination of cultural and technical factors within the Node.js and NPM community. The culture of open-source contribution in the Node.js ecosystem encourages the sharing of any and all code, no matter how small. This philosophy, while commendable for promoting collaboration, sometimes leads to an excessive focus on quantity over quality.

While the technical simplicity of creating and publishing packages to NPM commendably lowers the barrier to entry, it also presents a double-edged sword. This accessibility encourages many developers to contribute small, often superfluous packages for tasks that could be efficiently integrated into larger applications or libraries.

Furthermore, there’s a tendency to prioritise individual developer metrics, such as the number of packages created or download counts, over the practical utility of the package. This can lead to developers creating multiple small packages to inflate these metrics, rather than focusing on contributing to more substantial, robust projects. As mentioned earlier, NPM metrics are also quite gamified, which means micropackages are commonly used to abuse the metrics’ flaws to make the author’s profile look better.

The Solution

I don’t have a silver bullet, but a few things would nudge it the right way.

Stop treating download counts as a measure of impact. Transitive downloads in particular tell you nothing about whether anyone actually chose your package. If ansi-red gets 6.5M downloads a week and nobody asked for it, that number is noise. As long as it looks good on a CV, people will keep farming it.

Tooling could help too. I’d love a dependency tree viewer that makes it painfully obvious when half your node_modules is one-liners, and audit tools that flag a project for dragging in a silly number of tiny or unmaintained packages.

Prefer bigger, well-maintained libraries over one package per function. Nobody needs a package per colour. If you care about bundle size, make the library modular, don’t split it into fifty packages.

And honestly, if it’s one line, just write the line. You don’t need a dependency to check if a number is even.

How much this blog post will do to combat it? Unfortunately, likely nothing at all.

What next?

I had a discussion about this with my friend Daniel, and he suggested I try to map the space to find the most prolific micropackage authors. I like the idea of taking this a step further and trying to apply the principles of epidemiology to this micropackage plague. Expect another post sometime soon with follow up results to this.

This post is signed by me

Cross-check this clearsigned file with my public key to verify the authenticity of this post.

Public key: key.pub
Raw Markdown: npm-micropackages.md
Signature: npm-micropackages.sig
File hashes: assets.sig