Release: Yarn 4.0 🪄⚗️
Today is the day! After more than a year of work, our team is excited to finally put a fancy "stable" sticker on the first release from the 4.x release line! To celebrate, let's make together a tour of the major changes; should you look for a more itemized list, take a look at the changelog .
Breaking Changes
Here's what you need to know when upgrading from 3.x projects:
yarn
init
won't enable
Zero-Install
by default anymore.
yarn
init
will use
Corepack
rather than
yarnPath
.
typescript
,
interactive-tools
, ...) are now included by default.
yarn
workspaces
foreach
command has a slightly altered syntax.
Installing Yarn
Ever since the 2.0 our recommendation has been to install Yarn on a per-project basis using the
yarnPath
setting (automatically set either of
yarn
init
-
2
and
yarn
set
version
). We intentionally don't release modern releases on the npm
yarn
package,
so as not to break older projects which didn't migrate yet
.
To that end we used to recommend using the
yarnPath
setting pointing to a checked-in binary, but this pattern increased friction more than we liked - many people didn't like the idea of adding a binary to their repository, however small. We listened, and worked conjointely with Node.js on a project called
Corepack
. Corepack is a tool shipped with Node.js 16+ that will automatically select the right package manager version to run depending on the project you're working on.
Now that Corepack is shipped with both Node 18 and 20 we no longer need to rely on
yarnPath
, and as a result we updated our
installation guide
to reflect that. The
yarn
init
-
2
and
yarn
set
version
commands have been updated to favor updating the
packageManager
field when possible.
Corepack knows which package manager version to use thanks to the standard
packageManager
field in your
package.json
. This field will typically be set via one of
yarn
init
-
2
,
yarn
set
version
x.y.z
, or the more generic
corepack use [email protected]
.
Hardened Mode
Yarn attempts to protect you from common attacks, and this is pushed even further by the introduction of the Hardened Mode. When operating under this mode, Yarn will perform two extra validations:
Together, those checks will prevent any attacker from surreptitiously modifying your lockfiles when making PRs to your project using Yarn ( https://snyk.io/blog/why-npm-lockfiles-can-be-a-security-blindspot-for-injecting-malicious-modules/ ).
The Hardened Mode is enabled by toggling on
enableHardenedMode
, but it's also automatically enabled when Yarn detects that it runs within a GitHub pull request on a public repository. This can be disabled by explicitly toggling off
enableHardenedMode
in your yarnrc file.
Installs operating under Hardened Mode constraints are significantly slower than usual as they need to perform many network requests that would be skipped otherwise. We don't recommend enabling it by default - if you need it in a specific CI job, toggle it on via an environment variable:
export YARN_ENABLE_HARDENED_MODE=1
JavaScript Constraints
Yarn is the only package manager to implement a constraints engine . If you don't know it, this feature lets you define a set of rules that your project must satisfy. For instance, the Yarn repository enforces that no two workspaces depend on different versions of any given dependencies, unless explicitly allowed.
Our constraints engine used to be powered by Tau-Prolog, a JavaScript Prolog implementation. Unlike imperative languages like JavaScript, Prolog uses a different model called logic programming - you define that something exists if a rule is true. It's a very interesting pattern that integrates well with the concept of rule-based linting. Unfortunately, Prolog proved very complex to use, increasing the learning curve of constraints past the threshold we were comfortable with.
As a result, Prolog constraints are deprecated starting from Yarn 4, and they have been superseded by a shiny new JavaScript-based engine, with optional TypeScript support! We have been writing our own rules at Datadog with this framework for a couple of months now, with great success. You can also check the public Yarn repository for a practical example of the kind of rules you can enforce at the repository level, and the newly revamped documentation is there to help you quickly get up to speed.
The new optional
enableConstraintsChecks
setting will make Yarn run your constraints as part of
yarn
install
. It's a handy way to surface errors before having to wait for the remote CI to raise them, and since the new engine is so fast, it has almost no impact on your install time 🚀
TypeScript Integration, Interactive Tools, ...
Various features in Yarn used to be shipped as sideloaded plugins that needed to be managed separately from the main bundle. While this helped us build a plugin ecosystem, it also proved challenging to manage for our users. We implemented some features to make that easier (auto-upgrade plugins when you auto-update Yarn), but in the end the few KiBs we gained by not shipping all the features by default weren't worth the confusion and friction they caused.
As a result, while Yarn still supports third-party plugins (and will continue to in the future),
all the features and commands we build are now available as part of the main distribution
. You can now use
yarn
upgrade-interactive
and
yarn
stage
without plugins and, if you have TypeScript configured in your project, Yarn will now auto-add and remove
@types
packages as needed whenever you update your dependencies with
yarn
add
and
yarn
remove
.
Improved User Interface
Various pieces of the UI got revamped to better convey information. For example,
yarn
install
now tells you the packages you added, and their total weight. You will also notice it doesn't print as much warnings around peer dependencies, as we now try to only print warnings for actionable situations:
➤ YN0000: · Yarn 4.0.0➤ YN0000: ┌ Resolution step➤ YN0085: │ + next@npm:13.5.4, react-dom@npm:18.2.0, and 24 more.➤ YN0000: └ Completed in 0s 280ms➤ YN0000: ┌ Fetch step➤ YN0013: │ 22 packages were added to the project (+ 177.72 MiB).➤ YN0000: └ Completed in 3s 723ms➤ YN0000: ┌ Link step➤ YN0000: └ Completed➤ YN0000: · Done with warnings in 4s 123ms
Another example is the
yarn
config
command, which sports a new tree display and now also accepts an arbitrary number of settings as positional arguments, letting you select what you wish to see:
├─ cacheFolder│ ├─ Description: Folder where the cache files must be written│ ├─ Source: │ └─ Value: '/Users/global/.yarn/berry/cache'│└─ enableHardenedMode ├─ Description: If true, automatically enable --check-resolutions --refresh-lockfile on installs ├─ Source: └─ Value: null
Performances
The 4.0 isn't lagging behind in performance improvements, and shows to be significantly faster at installs than the 3.6. For instance, here's the difference in time to install Gatsby and its ~350MiB dependency tree from a cold cache. The 3x improved performances are due to a new package metadata cache which significantly improves performances of repeated installs:
hyperfine -L v stable,canary --prepare 'rm -rf ~/.yarn/berry/cache' 'cd $(mktemp -d) && yarn init -2 && yarn set version {v} && yarn && yarn add gatsby --mode=skip-build'
Benchmark 1: 3.6.0
Time (mean ± σ): 65.599 s ± 2.214 s [User: 82.952 s, System: 8.638 s]
Range (min … max): 62.167 s … 68.277 s 10 runs
Benchmark 2: 4.0.0
Time (mean ± σ): 16.724 s ± 0.928 s [User: 14.622 s, System: 5.743 s]
Range (min … max): 15.318 s … 18.110 s 10 runs
Summary
4.0.0 ran 3.92 ± 0.25 times faster than 3.6.0
These changes make Yarn as fast as pnpm in most scenarios , although competition is still fierce 🔥
Fancy Website
As you probably noticed, our website received a major overhaul, both style and content! We worked on this new iteration for more than a year now, and we hope it'll help you find better information, faster than before.
Some particular improvements:
yarn
install
)
yarn
--
immutable-cache
)
Our expertise lies in tooling more than building websites, so I'm sure various hanging fruits remain - especially around loading time. If you're interested to help us, check the sources and please feel free to send PRs our way!