Yarn: the improved Node Package Manager

2 minute read

I was surprised when Facebook introduced Yarn on October 11. I didn’t expect anything to be wrong with Node Package Manager (NPM) itself, apart from the well-known left-pad issue. But when I started reading the introduction page and the first blog by Facebook about it, it became clear which issues they try to address.

What Yarn tries to do better

Caching packages locally

It creates a local cache of all the packages that you ever installed. Because of that local cache, installing and restoring packages becomes a lot faster. This also enables you to work offline if needed.

A developer can also decide to include these packages as tarballs into the source repository. This way your build server has no direct dependency on the NPM registry. You can do that by adding a setting to the .npmrc file:

yarn-offline-mirror=./any-directory

Lockfile for reliability

It also adds a yarn.lock file to your repository. This includes all the packages including their version, tarball name and file hash. Because of that file, Yarn ensures that an install that worked on one device, also works on another device. Make sure to commit this file to your source control repository.

This is also possible with NPM by using npm shrinkwrap, but it is a lesser known feature to a lot of developers. Yarn does that automatically for you.

Parallel downloads

NPM does all of the work per package and sequentially. Yarn on the other hand downloads as many packages as it can in parallel, thereby increasing installation times. I haven’t done exact benchmarks yet, but it ranges from about 1.2x to up to 10x faster installations. Yarn is consistently faster than NPM.

Switching to Yarn is easy

Since Yarn is built on top of NPM, you can still use the NPM commands and configuration you already know. But if you want to harness the real power of it there are a few commands you should be aware of:

Installing all packages in the package.json file:

npm install
//becomes
yarn

Installing a new package and including it as a dependency to the package.json file:

npm install packagename --save
//becomes
yarn add packagename

As you can see there is no need to explicitly save your package to the package.json file with Yarn. This prevents you from having local installs of packages, that are not available when another developer or the build server picks up your repository, causing the build to break.

Is yarn here to stay?

Well, this is a rather hard question to answer. We’ve all seen what happened with the Node.js and io.js fork. In the end Node.js was improved because of the changes that io.js made in their fork. NPM might go down the same path and learn from Facebook’s implementation. They might resolve some (or all) of the shortcomings that Facebook addresses, therefore making Yarn obsolete again. But I guess that won’t happen anytime soon.

Since Yarn is very easy to pick up, a lot of developers are able to give Yarn a try in a project in less than 5 minutes. You’ll be amazed of the differences in installation speed and clean output.

There is also a big difference when doing CI builds with Yarn or NPM. In some cases having faster builds results in lower costs. I will add a post soon that makes it clear how you can use Yarn in Visual Studio Team Services builds. In short it comes down to installing Yarn from NPM, and after that executing the yarn command:

npm i yarn && yarn

Leave a comment