I know what you're thinking, "Yet another new tooling in the JS ecosystem?", and "Weren't we just done deprecating bower?".1
What exactly does "deterministic" mean in this context, and why should you care? According to definition a "deterministic algorithm" would, given a particular input, always produce the same output.
Sometimes npm might introduce a sneaky bug in this regard. It does not always, given the same
package.json (input), install the same versions of your dependencies (output). This is because of how npm resolves dependencies.
Say you depend on
"foo-module": "^2.6.0" in your
package.json. Here the caret (
^) in front of the version number means that when you run
npm install, it will install the newest
2.x.x version of
foo-module. But it will only do this if your
node_modules folder does not already contain a
2.x.x version of this module.
What if a new
2.x.x version has been released in the interim between you installing the dependencies on your machine, and another colleague on their machine? This fact may lead to you, and your colleagues, and your build servers having completely different versions of packages installed.
Imagine there's a bug in the newest version of
foo-module. It works on certain machines, but not others. In this scenario you may have a difficult time discovering where the bug is. Worse if it happens at the end of a deploy pipeline.
Even if you don't use version number ranges in your
package.json, the deps of your deps2 might.
Yarn fixes this with the help of a file called
yarn.lock. This file is generated by default, and it will lock down the specific versions to be installed. Of course this file must be checked in along with the rest of your code, so your colleagues and build servers can use it.
Lockfiles aren't anything new, several other package managers use them (with good reason). Even npm has
shrinkwrap for this purpose. But the difference is that with Yarn the lockfile is updated automatically, whilst with npm you will have to remember to manually run
Much faster installs
Another benefit of having a lockfile is that Yarn knows exactly which dependencies to fetch. Even if your
2.x.x), your lockfile will nail it down to a very specific version, say
2.6.2. This fact means that Yarn doesn't have to do anything fancy before it starts to fetch packages. In fact it can start right away, parallelize requests, and effectively utilize your bandwidth.
Yarn also keeps a global offline cache of the packages, which means that it will only hit the network when it truly needs to. Both of these improvements mean a huge speed-up in terms of install time.
Even if you don't care about anything else regarding Yarn, you will definitely notice the difference in install time. The global package cache is also a benefit to developers who have to work offline, or in low-bandwidth environments.
Of course, there's one potential downside; you will no longer have an excuse to go get coffee because of
Yarn supports both the npm and bower registries, which means you will not have to "migrate" your
It supports most of the commands that npm does, with certain things renamed. For example
npm install --save foo-module has become
yarn add foo-module. While
npm install is just
Yarn is open source, more secure, and with several big industry players behind it. Even the npm folks have been pretty nice about the announcement.