YARN vs NPM (vs pnpm) in 2019: comparison and verdict A comparative analysis of the most used package managers for JavaScript and Node.js and what to use in 2019

YARN vs NPM (vs pnpm) in 2019: comparison and verdict

In this article I’ll talk about Yarn and NPM, arguably the most popular JavaScript package managers available as of today, with the precise intent of compare their respective features and explain what I’m (mostly) using nowadays and why: needless to say, this post only depicts my personal opinion on the matter, even if I’ll try to back my statemets with objective arguments.

Introduction

In the unlikely case you don’t know what a package manager actually is, we strongly suggest to read this Wikipedia entry and then come back here! However, in a nutshell, a package manager is a tool that allow developers to automate a number of different tasks like installing, updating and configuring the various libraries, frameworks and packages that are commonly used to create complex projects. They play a major role in any decent DevOps-based approach as they allow to eliminate the need for manual installs, updates and removals of these packages – which can be painful when you’re dealing with hundreds of them.

As we previously said, the most two popular package managers in the ecosystem as of today are NPM, which is an acronym for Node Package Manager, and Yarn, a most recent alternative created by Facebook that aims to do the same stuff as NPM does but with an arguably better and more streamlined approach. We’ll be looking at these package managers side by side considering features such as performance, stability, security, ease of useness, support and the likes.

In the next two chapters we’ll briefly recap the NPM and Yarn history, going from their initial release to their latest improvements. Before reading them, it’s worth clarifying an important concept:  NPM is both an online repository (npmjs.com) and a command-line client to interact with it, while Yarn is just an alternative command-line client to handle the aforementioned online repository in a (arguably) better way: that said, in this post we’ll basically compare these two clients, and analyze how they’ll do against the common repository they’re designed to deal with.

NPM

In this post I’m writing NPM using uppercase letters, but the “official” name is npm since it follow the typical camelCase and/or kebab-case naming convention approach of the JavaScript ecosystem. Anyway, NPM is written entirely in JavaScript and was developed by Isaac Z. Schlueter as a result of having “seen module packaging done terribly” and with inspiration from other similar projects such as PEAR (PHP) and CPAN (Perl). It was initially released on January 12, 2010 and it was adopted almost instantly by Node.js, which came out in the same period (2009): the tremendous growth-rate of the Node.js community was the key to success of NPM, which was the most used package manager since then (and it still is).

In March 2016, NPM attracted press attention after a package called left-pad, which was a dependency of many popular JavaScript packages, was unpublished as the result of a naming dispute. Although the package was republished 3 hours later, it caused widespread disruption, leading npm to change its policies regarding unpublishing to prevent a similar event in the future. In February 2018, a major bug was discovered in version 5.7.0 of NPM, in which running sudo npm on Linux systems would result in changing the ownership of system files, permanently breaking the operating system. In July 2018 the NPM community had to face the first major security issue: the account of a maintainer of the popular eslint-scope package were compromised, thus resulting in a malicious release of eslint-scope (version 3.7.2): the malicious code was meant to copy the NPM credentials of the machine running eslint-scope and upload them to the attacker. Such technique is now called Module Highjacking and was replicated various ways since then, such as the flatmap-stream case in November 2018, where a malicious dependency called that way was added to NPM as a dependency of the popular package event-stream. The malicious package contained an encrypted payload that could steal bitcoins from certain applications: it was removed by the NPM administrators quickly, before being able to deal too much damage.

These relatively few – but still relevant – module hijacking cases were a inevitable cause of the NPM registry policy regarding package submissions: a no-vetting process that mostly relies on user reports to take down packages if they violate policies by being low quality, insecure or malicious. This optimistic, but (sadly) naive  approach was partially mitigated with the release of NPM version 6, with a new package audit feature specifically introduced to help developers identify and fix vulnerability and security issues in installed packages. The source of security issues were taken from reports found on the Node Security Platform (NSP), originally developed by ^Lift security, then acquired by NPM in April, 2018 and therefore integrated with the tool shortly thereafter.

NPM can manage packages that are local dependencies of a particular project, as well as globally-installed JavaScript tools. When used as a dependency manager for a local project, NPM can install, in one command, all the dependencies of a project through the package.json file, a “configuration file where each dependency can specify a range of valid versions using the semantic versioning scheme, allowing developers to auto-update their packages while at the same time avoiding unwanted breaking changes. NPM also provides version-bumping tools for developers to tag their packages with a particular version. Since version 5.0, NPM also provides the package-lock.json file, which has the entry of the exact version used by the project after evaluating semantic versioning in package.json.

Yarn

Yarn is a package manager for the JavaScript programming language developed and released by Facebook in October, 2016. Based on what Facebook wrote about it in their development blog, the project was meant to replace the existing workflow for the npm client or other package managers as an attempt to permanently fix some consistency, security, and performance issues the Facebook engineers were claiming to have experienced with npm as the size of their codebase and staff grew.  After trying to solve them with the npm client itself they set out to build a new solution to manage their dependencies: an alternative npm client which they called Yarn.

They were able to use the   npm package name, which was not available at the time, thanks to Sam Holmes, which donated it to the project in 2016.

Yarn is an alternative npm client with some distinctive aspects, including:

  • multiple registries: it reads and installs packages from both npmjs.com and Bower, thus ensuring a CI business continuity for developers if one of them goes down.
  • selective version resolutions: it lets the developer define custom package versions inside the various dependencies through the resolutions field in the package.json file.
  • automatic retries: Network requests are retried upon failure, reducing “red builds” due to single request fails or temporary network issues.
  • parallel downloads: Yarn uses parallel workers to download packages, thus maximizing resource utilization and reducing the time builds take to run.
  • caching: Yarn caches every package it downloads, so it never needs to download it again.
  • lock file: A dedicated lock file (  ) that keeps dependencies locked to specific versions, similar to Ruby’s Gemfile.lock.

Most of these features were added to overcome the limitations found on npm at the time of Yarn’s initial release: however, some of them would be mitigated few months since then with the introduction of npm version 5.0 (26 May 2017) and a lot of new features, such as the lockfile (  ), an improved npm cache and more.

Comparison

In the next paragraphs I’ll do my personal comparison about Yarn and NPM.

Performance

In those 8 months passed from the release of Yarn (October 2016) and the release of NPM 5.0.0, Yarn was the clear winner in terms of performances: the parallel download alone had an tremendous impact there, especially for big projects with 100+ JS packages on the   file.

The gap closed almost completely within the next 2 years, with NPM punching back with every release. In July 2019 I tried to do a quick benchmarks using Powershell’s Measure-Command feature to measure the time it takes to execute the given command using NPM v6.10.1 vs Yarn v1.17.3. I was then able to compare the whole install phases for a big project:

The results I got clearly demonstrated that Yarn is still the clear winner in 2019, even if the difference (a bunch of seconds for clean install, a bit more for cached install) wasn’t nearly as big as before NPM5.

Stability

NPM and Yarn are both solid, well-tested and proven products: in terms of stability I don’t see a clear winner nowadays, since they are used by millions of users and backed by a great community which ensure continuous testing, issue-reporting and so on. Both of them seem very viable nowadays for  Windows, Linux and MacOS environments.

Security

One of the main reason Facebook developed Yarn was to address NPM’s security issues in a better way. NPM allowed packages to run code on installation automatically and on-the-fly, even from their dependencies automatically and on the fly. While this feature has its conveniences, it raised a few security concerns – especially considering the no-vetting registry policy on package submissions which we talked about early on. Conversely, Yarn only installs from your yarn.lock or package.json files. More specifically, yarn.lock ensures that the same package is installed throughout all devices, thus drastically reducing the chance of bugs from having different versions installed.

Since these concerns are still in force at the time of writing, I think that Yarn is preferable in terms of security.

Usage

Here’s the download comparison of npm vs Yarn packages in the last 24 months according to npmtrends.com:

YARN vs NPM (vs pnpm) in 2019: comparison and verdict
source: npmtrends.org

As we can see NPM still seems to be the clear winner here: however, the stats below the chart tell a whole different story:

stars 🌟 forks 🍽 issues ⚠️ updated 🛠 created 🐣 size 🏋️‍♀️
npm 1934 432 22 Jul 14, 2019 Jul 6, 2018 Minified + gzip package size for npm in KB
yarn 36282 2229 1884 Jul 13, 2019 Jan 19, 2016 Minified + gzip package size for yarn in KB

It definitely seems that Yarn, with almost 20 times the stars and 5 times the forks, might be currently holding the lead.

Introducing PNPM

… you know what they say? Between two parties, the third gains! A couple months ago I started to try a new kid on the block, called pnpm: a fast, disk-efficient package manager that uses hard links and symlinks to save one version of a module only ever once on a disk.

Hey, wait a minute: what does it mean? I’ll try to explain the concept in few words. When using npm or Yarn , if you have 30 projects which are using the same version of a module, how many copies of that module would you have on your HDD? Well, the answer is… 30. With pnpm, each package is saved in a single place on the disk and a hard link will put it into the node_modules where it should be installed. This neat implementation not only improves performance (a lot of less required downloads), but it will help you save tons of space on your development drive(s). If you’re more curious about that, the whole concept is well-explained in this Medium post by Zoltan Kochan, part of the pnpm developers team.

I still don’t know much about pnpm myself, therefore I wouldn’t recommend it yet for those wanting something stable and widely proven… but hey, in terms of performance and design, it’s definitely a clear winner, at least at the time of writing (July 2019), as  it has all the features of npm and yarn and it just outperforms them in many aspects. On top of that, it comes with the same API as npm, meaning that you can just use the   command instead of   and you’ll be good to go.

Verdict

As a matter of fact, if I had to choose between NPM and Yarn, I would most likely go for Yarn: in fact, I’m actually doing that for almost any collaborative project I’m currently working with, mostly because Yarn currently is, at least in my own, humble opinion, the “safest” option out there.

As for those projects I’m developing alone… well, I’m definitely using pnpm, which I think is the best – and most promising –  JavaScript package manager in 2019.

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

2 Comments on “YARN vs NPM (vs pnpm) in 2019: comparison and verdict A comparative analysis of the most used package managers for JavaScript and Node.js and what to use in 2019

  1. You forgot to add NPM stars before moving. It has additional 17,181 stars in https://github.com/npm/npm

    Comparing Yarn stars to NPM stars doesn’t tell the whole story. It takes consideration to install Yarn so most people installing it will visit its github page and while being there add a star. NPM is built in by default and there’s no need to visit its page.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.