"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!
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 inpackage.json
. If present, count as whatever is specified. - Check for
package-lock.json
ornpm-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.
- Check if
And so, the script was born.
Without further ado, here are the results:
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:
Top comments (7)
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.
Ah, that's an excellent idea! Here are all the repos that are <= 1 year old, and have >1000 stars.
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)
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)
I know about pnpm and use Yarn 4. Both are fine.
For some, out-of-the-box tools suffice.
💯 no idea why it's still used by so many. Literally any other modern package manager (including modern Yarn itself) is a better choice.
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.
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.
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.