Should I migrate to Yarn?

May 18, 2017 in technology

Yarn is an alternative package manager for Node.js and Javascript. Acclaimed for being much faster, reliable and secure compared to Npm. But does it really justify a change?

In my current project at IsApp we’ve been considering a migration due to a lot of frustrating some problems dealing with npm-shrinkwrap to lock package versions.

Well, let’s talk about that for start…

WTF is npm-shrinkwrap?

npm-shrinkwrap is a feature of NPM to lock down package versions. It’s a command that generates a file named npm-shrinkwrap.json (wth it’s not just npm.lock) with quite the same concept behind Gemfile.lock (for Ruby Bundler) or composer.lock (for PHP Composer). It writes down the current version of every installed package in the working tree.

Once generated, any attempt to npm install will respect this file in two ways:

  • For a project installation, it installs the exact same versions of the packages listed on npm-shrinkwrap.json. So we can guarantee that the same environment runs on development, test and production.
  • For new package installations, it updates npm-shrinkwrap.json with the new installed versions.

The problem is that it’s not so reliable as it should. It changes thousands of lines to npm-shrinkwrap.json after any simple install and insists in adding development dependencies to it without being requested, so we had to manually update the file from time to time. In short, it sux.

Yarn to the rescue

I’ve been using Yarn for some weeks only, but despite my initial reluctance in using anything beyond the node default tools, I’m quite satisfied.

Yarn always uses a yarn.lock (now this name makes sense) file. Which means that either you don’t have to worry about generating/updating it nor you can ignore it.

The yarn.lock is a simple text file instead of a json one and, in my tests, it remains very consistent between new package installs. But it has even more benefits.

Cache and faster install

Npm seems to completely ignore local cache, as it always take a lot of time to install packages, even if you have already installed them before in other projects. Yarn, on the other hand, can be very fast once it has a cache.

I’ve collected some benchmarks comparing Npm and Yarn using the GNU time command and the express.js repository as example.

The results are bellow (full comparisons on gist):

  npm install yarn install
clean install (no cache)19.70s6.93s
cached and lockfile present13.90s2.10s
cached and node_modules present1.49s4.18s
cached, lockfile and node_modules present1.63s0.67s

Just to summarize…

In a clean install Yarn can be 3 times faster than Npm. Reducing to almost 5 times faster when the packages are cached. With the lockfile present it took less than one second on the example project.

It’s f****** fast!

Yarn for the win

I would not suggest migrating to Yarn on small or new projects. In other words, if Npm can handle your project well, just keep with it.

But if you work on a huge project with lots of dependencies that takes a lot of time to install or if having a lockfile is mandatory, Yarn can help a lot, so consider using it.

Nevertheless, Yarn still uses package.json and so it’s fully compatible with Npm (despite the lockfile). So you can still install and run any Yarn project using Npm.