This article's content
Yarn 3

Yarn is a package manager similar to npm (node package manager). It improves user experience by

  • offline caching: packages can be installed without internet connection once they were downloaded before. Additionally you can make yarn point to an offline mirror (gzipped files), so that continuous integration systems don’t need to access the internet to acquire packages
  • deterministic deployment: packages are always installed the same way across multiple machines
  • consistency by using lock-files
  • security by using checksums to test the integrity of packages.
  • network performance and resilience: requests are queued and if one request fails it does not cancel the whole installation process
  • flat node modules prevent creating duplicate packages
  • workspaces are a concept to break projects down into smaller parts and abstract out shared packages: yarn looks for packages that subpackages have in common and moves them up to the highest point in the package hierarchy (hoisting).

Yarn was initially released in October 2016 by Facebook and allows you to use and share code with other developers from around the world via packages. A package is describe by the package.json manifest file.

Installing / Upgrading from Yarn 1.x

As of the date of this article there is version 1.x (https://classic.yarnpkg.com) and 2.x (https://yarnpkg.com). Installing Yarn 2.x globally is discouraged, instead you should install it per-project. Do not uninstall Yarn 1.x, the creators want you to keep it installed. Instead run this in your project root folder:

yarn --version

yarn policies set-version berry # below v1.22
yarn set version berry          # on v1.22+

yarn set version from sources

Displaying help and initializing projects

Run yarn help for a list of all commands. To start a new project run yarn init.

Installing existing dependencies

If you already have an existing project with a package.json run yarn install or simply yarn to install all the dependencies.

Adding dependencies

You can add packages via yarn add my-package or more specific yarn add my-package@2.3.1 or yarn add my-package@my-tag. Add --dev to that command to install the package as a dev dependency or --peer for a non-dev dependency.

Removing dependencies

yarn remove my-package deletes a package.

Updating/Upgrading dependencies

Check if package is outdated:

yarn outdated @storybook/react

Upgrade to the latest dependency range of a single dependency as specified in package.json

yarn up @storybook/react

Upgrade to latest package disregarding what is specified in package.json:

yarn up @storybook/react --latest

Upgrading all dependencies across all workspaces to the latest version:

yarn up

Interactive upgrade

One time installation of plugin

yarn plugin import interactive-tools

From then on you can run

yarn upgrade-interactive

Wondering why your package.json is not updating after running yarn up

There seems to be a common misconception that the version in package.json always reflects the currently installed versions, but that is not true. package.json deals with the specification of version ranges, not with the exact version that IS installed – that is what yarn.lock does. So for example, it is possible to have this in your package.json

"@popperjs/core": "~2.11.2",

but actually have 2.11.6 installed in your node_modules folder, as yarn.lock confirms:

"@popperjs/core@npm:~2.11.2":
  version: 2.11.6
  resolution: "@popperjs/core@npm:2.11.6"
  checksum: 47fb328cec1924559d759b48235c78574f2d71a8a6c4c03edb6de5d7074078371633b91e39bbf3f901b32aa8af9b9d8f82834856d2f5737a23475036b16817f0
  languageName: node
  linkType: hard

Updating yarn itself

yarn set version stable

To upgrade yarn itself enter yarn set version latest and then yarn set version from sources.

Manifest file (package.json)

It contains all the info about your project, such as name, version, license. All available options can be found on the yarnpkg website.

Entry points

The package can be access by its name. To make this work you have to define which file shall be used as the main entry file using the main field and/or the module property if you use an ES6-compatible environment.

Scripts (yarn run)

The scripts field is used to list small shell scripts that will be executed when running yarn run. For example:

"scripts": {
  "test": "jest",
  "build": "webpack-cli --config ./webpack.config.js",
  "count-words": "echo \"$@\" | wc -w",
}

Dependencies (yarn add)

Every time you add packages via yarn add [package] the package definition is added to dependencies field or devDependencies respectively if you added packages with --dev.

peerDependencies lists all those dependencies that the consumer of your package must provide.

Monorepos

A monorepository is a repository that contains multiple packages. For example, Babel and Jest

Offline caching

Each time a package is downloaded from a remote location, for example via yarn install on first use, a copy will be stored within the cache. The next time this same package will need to be installed, Yarn will leverage the version stored within cache instead of downloading its original source. The cache cannot be disabled but you can clean it running yarn cache clean.

Starting from Yarn v2, Yarn will by default configure the cache to be local to your project. If that does not make sense in your project and you rather would like to instruct Yarn to use a special path that will be shared by all projects that list the same configuration, then add the following to yarnrc.yml:

enableGlobalCache: true

Workspaces

Workspaces allow multiple of your projects to live together in the same repository AND to cross-reference each other. Yarn terminology:

  • A project is the whole directory tree making up your workspaces (often the repository itself).
  • A workspace is a specific named package stored anywhere within the project.
  • A worktree is the name given to private packages that list their own child workspaces

Worktrees are defined through the traditional package.json files.

About Author

Mathias Bothe To my job profile

I am Mathias, born 40 years ago in Heidelberg, Germany. Today I am living in Munich and Stockholm. I am a passionate IT freelancer with more than 16 years experience in programming, especially in developing web based applications for companies that range from small startups to the big players out there. I am founder of bosy.com, creator of the security service platform BosyProtect© and initiator of several other software projects.