DEV Community

Cover image for Package manager wars. The real picture
Wojciech Maj
Wojciech Maj

Posted on • Updated on

Package manager wars. The real picture

"pnpm has surpassed Yarn!" I've read on Twitter the other day. "In what exactly?" - I thought to myself. The answer to this question turned out to be: "In npm downloads". However, this doesn't mean anything at all!

In this article, we'll explore why it's a horrible way of comparing different package managers popularity, and we'll find out the real answer to the question: "Which package managers are the most popular?".

Why npm downloads can't be counted?

The most obvious problem with counting npm downloads is that npm ships with Node.js. This means that, in theory, everyone can use npm in Node.js project with no additional downloads. You don't download npm from npm to obtain it, only to update it.

Why Yarn downloads can't be counted?

First, I need you to know that Yarn Classic (v1) and Yarn Modern (also known as Yarn Berry; v2+) are completely different things.

Let's look at Yarn Classic first.

Yarn Classic was indeed shipped as an npm package called yarn. The recommended way of installing it was by running npm install -g yarn. However, it is not the only way of downloading Yarn Classic. Among many others you could use brew, config of which unveils that, unsurprisingly, it downloads Yarn binary from yarnpkg.com rather than npm.

For Yarn Modern, things got complicated.

Before Corepack (I'll cover it later) became a thing, Yarn 2 installation was weeeird. To install Yarn 2, you had to install Yarn 1 first. Then, in every repository, you had to run yarn set version berry, which installed Yarn 2 in this repository, specifically in .yarn/releases. While doing so, you could see the console output:



Resolving berry to a url...
Downloading https://github.com/yarnpkg/berry/raw/master/packages/berry-cli/bin/berry.js...
Saving it into /private/tmp/my-app/.yarn/releases/yarn-berry.js...
Updating /private/tmp/my-app/.yarnrc...
Done!


Enter fullscreen mode Exit fullscreen mode

So, again, not npm. In fact, you cannot download Modern Yarn from npm at all!

Corepack

Nowadays, the recommended way of installing Yarn is through Corepack, a tool shipped (although not enabled - yet) by default with Node.js.

Slight off-topic: I highly recommend you to familiarize yourself with Corepack, regardless of your package manager of choice. Once enabled, it transparently downloads a binary for a package manager a given project requires, as specified in packageManager in package.json. You don't need to install Yarn or pnpm manually at all!

Back to the topic. Where does Corepack downloads Yarn from? Corepack's config makes it clear: it's yarnpkg.com, so again, not npm.

Why pnpm downloads can't be counted?

pnpm's 1st (and thus preferred) installation method installation instructions is "Using standalone script". Looking at script source, we quickly learn it downloads its binaries from GitHub. So… not npm.

Unlike Yarn, pnpm can actually be downloaded from npm. Corepack takes advantage of that, and uses npm under the hood to download pnpm binaries.

What do we know so far?

  • npm is underreported on npm downloads stats. You don't need to download it to use it.
  • Yarn Classic is underreported. You can download it from other sources.
  • Yarn Modern is not reported at all. You can't download it from npm.
  • pnpm is underreported. You can download it from other sources.
  • And perhaps the most importantly, more npm downloads != more popularity. It just means… There is more downloads. If package manager A is updated weekly, and package manager B is updated once per year, A will get more downloads than B, even if B is technically more popular.

So what can we measure?

Here's my plan.

  • Get as many most starred GitHub JavaScript and TypeScript repositories as I can.
  • Figure out package manager each repo is using.
    • Check if packageManager is present in package.json. If present, count as whatever is specified.
    • Check for package-lock.json or npm-shrinkwrap.json. If present, count as npm.
    • Check for yarn.lock, and…
    • Check for .yarnrc.yml. If present, count as Yarn Modern.
    • If not, count as Yarn Classic.
    • Check for pnpm-lock.yaml. If present, count as pnpm.
    • Check for bun.lockb. If present, count as Bun.
    • If all else fails, check documentation for commands that would hint on package manager used.

And so, the script was born.

Without further ado, here are the results:

Pie chart

Package manager Total
npm 978 (53%)
Yarn Classic 471 (26%)
Yarn Modern 75 (4%)
pnpm 105 (6%)
Bun 4 (0%)
unknown 203 (11%)
Stat Total
Projects examined 2040
Projects with package.json 1836
Projects using Corepack 179
Projects not using Corepack, but with a lockfile 1657

So there you have it. The real picture of package manager wars.

pnpm does, indeed, appear to have surpassed Yarn Modern (v2 and v3). But it is nowhere near to Yarn Classic's (v1) popularity, which, in turn, is not nearly as popular as npm.

npm is the absolute king with whopping 53% of the "market". In reality, it's likely even more than that. 11% of the projects examined did not have lockfile committed. My suspicion is that the vast majority of maintainers of these projects are in fact using npm, as there is no (machine-readable) indication that something other than the "default" is being used.

Final words

If you'd like to see how the script was done, or would like to improve it, please visit:

https://github.com/wojtekmaj/package-manager-stats

Top comments (7)

Collapse
 
artxe2 profile image
Yeom suyun

It will be difficult to come up with a completely accurate method, but targeting newly launched projects that have grown rapidly in the past year may be more accurate.

Collapse
 
wojtekmaj profile image
Wojciech Maj • Edited

Ah, that's an excellent idea! Here are all the repos that are <= 1 year old, and have >1000 stars.

Pie chart

Package manager Total
npm 150 (63%)
Yarn Classic 33 (14%)
Yarn Modern 5 (2%)
pnpm 38 (16%)
Bun 3 (1%)
unknown 10 (4%)
Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix

Where are no wars to speak of - pnpm won (state of today).
Bun - will replace every other choice next (future state).
Looking at usage stats - is just looking backwards in time -> it does not give you a meaningful picture of future direction (just like driving in a car looking in the back mirror - is a very bad way to drive)

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix
  • just use bun, no reason to complicate things
  • pnpm would be second choice (if bun is to new/experimental for you), used by everyone (who know about it)
  • npm is for people who do not know about pnpm
  • yarn 1 is deprecated
  • yarn 2 is completely unusable (because they choose to to create a new plug-and-play method, which no one else supports)
Collapse
 
wojtekmaj profile image
Wojciech Maj

just use bun, no reason to complicate things

It's indeed fantastic, but has its own quirks. I would refrain from using it in serious projects for a little while (although I'm evaluating it on a separate branch)

pnpm would be second choice (if bun is to new/experimental for you), used by everyone (who know about it)

I know about pnpm and use Yarn 4. Both are fine.

npm is for people who do not know about pnpm

For some, out-of-the-box tools suffice.

yarn 1 is deprecated

💯 no idea why it's still used by so many. Literally any other modern package manager (including modern Yarn itself) is a better choice.

yarn 2 is completely unusable (because they choose to to create a new plug-and-play method, which no one else supports)

We're on Yarn 4, node_modules is the default again (when migrating old projects), PnP is supported by far more tools than it used to be. The "PnP problems" were in fact "ecosystem problems" that others chose to ignore. "PnP compatibility fixes" made improved the ecosystem for everyone. But that's a topic for another day.

Collapse
 
glensc profile image
Elan Ruusamäe

Just to add more to install source info. docker node images contain yarn 1 and npm. so they come pre-installed. that can be reason why yarn 1 is still a thing and also not counted as download. you get download +1 when docker.io image is built. not every time someone downloads node docker image with package manager, you get the idea.

Collapse
 
tausifcreates profile image
Tausif

you shouldn't use corepack to install npm/yarn (whatever) If you use nvm and switch between versions. If you do, you have to install yarn/npm for every version of node that is installed on system.