Three Reasons to Use Yarn in 2020 (and Beyond)

When Yarn was first released, it was a huge step forward for the JavaScript and NPM community. At the time, NPM did not support deterministic sub-dependency resolution. And Yarn was considerably faster, primarily due to the introduction of an offline cache.

These days, however, the gap between Yarn and NPM is much closer. NPM 5 introduced a package-lock, which allows for deterministic dependency installation. Additionally, recent versions of NPM now cache installed dependencies, which speeds up installation but still lags behind Yarn (in my non-scientific testing).

Yet, even with improvements to NPM, Yarn still provides compelling reasons to choose it. Here are three Yarn features I’ve found extremely useful over the past few years.

1. Pinned Version Resolutions

Have you ever used a library, discovered an issue with it, and determined that the problem was with one of their dependencies? One of the most frustrating things to happen in that situation is discovering that the sub-dependency had released a fix in newer versions. Even more frustrating than that, though, is if your dependency is no longer maintained or not frequently updated.

Enter Yarn dependency resolution. In your package.json, add a property “resolutions.” Yarn will resolve the versions listed in this field. This looks like:

 
{
  ....
  "resolutions": {
    "mini-css-extract-plugin": "^0.9.0",
    "less-loader": "^5.0.0"
  }
}

In your Yarn .lock, this would look like:

 
[email protected], less-loader@^5.0.0:
  version "5.0.0"
  resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-5.0.0.tgz#498dde3a6c6c4f887458ee9ed3f086a12ad1b466"
  integrity sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==
  dependencies:
    clone "^2.1.1"
    loader-utils "^1.1.0"
    pify "^4.0.1"

Notice how [email protected] and less-loader@^5.0.0 resolve to 5.0.0. Typically, Yarn will resolve major versions separately. However, with the version resolution set to ^5.0.0, it resolves all versions of less-loader to that.

This is a good way to ensure that all dependencies are using the same version of a specific package. However, this could lead to unintended behaviors, so use this sparingly.

2. Autoclean

Autoclean lets you automatically remove any dependencies in the .yarnclean file after installing or adding dependencies. In the Yarn docs, they recommend it for pruning unnecessary files that take up extra space, such as docs, tests, examples, assets, etc. These files aren’t necessary to run the modules, and it can help reduce the node_modules size.

One of the benefits that I’ve found with autoclean is that dependencies can be removed completely. This certainly isn’t a common case, but there have been a few times where I’ve found that the cleanest solution is to remove dependencies altogether.

For example, in the past, I’ve used libraries that have dependencies on both React and React Native. This leads to some incorrect imports, namespace collision, and occasional bugs. The easiest thing to do in that case is to add rules in the .yarnclean file to simply remove the bad dependencies. If I’m working on a web application, I don’t want React Native modules in my application dependencies, especially not my compiled code.

3. Yarn 2 – aka “Berry”

Yarn 2 has been announced and is under active development. This is a major overhaul, and it will provide many new features in addition to various bug fixes. In the Yarn roadmap, it was stated that the intention is to shift Yarn from a Node-specific CLI package manager to a platform and API for multiple languages. Yarn 2 is available now for usage in Node projects.

I’m personally very excited about the workspaces for full-stack projects and the portable shell for cross-platform Windows/Mac developers.

Yarn v2 provides the most compelling reason to continue using Yarn in 2020. Yarn reshaped the Node ecosystem in 2016, and I believe they can do it again in 2020.