Yarn 02 🧶 Installing and Upgrading Yarn
Installing Yarn used to mean a single global command. That era is over. Modern Yarn—versions 2, 3, and 4, collectively called “Berry”—is designed to be installed per-project, not globally. The tool that makes this possible is Corepack, a Node.js utility that intercepts yarn commands and routes them to the exact version declared in your project’s package.json. Understanding this shift is the difference between a clean, reproducible setup and a machine cluttered with conflicting global binaries.
Key point: Modern Yarn is not installed globally. It is activated per-project via Corepack, and the version is pinned in package.json so every developer and CI runner uses the same binary.
Why installation changed
The global binary problem. Yarn Classic (version 1.x) was installed globally via npm install -g yarn or a system package manager. Every project on your machine shared that single binary. If Project A required Yarn 1.22 and Project B required Yarn 3.2, you had a conflict. Upgrading Yarn for one project could break another. The global model worked when Yarn had one major version, but it collapsed once Yarn split into Classic and Berry .
The Corepack solution. Corepack ships with Node.js starting from version 16.10. It acts as a proxy: when you run yarn install, Corepack reads the packageManager field in your project’s package.json, downloads the specified Yarn version if necessary, and executes it. No global install. No version conflicts. The correct Yarn binary runs for every project, automatically .
The per-project version lock. The packageManager field is the contract. It looks like "packageManager": "yarn@4.5.0". Commit this to version control, and every developer who clones the repository gets the same Yarn version. CI runners get the same version. There is no ambiguity, no “works on my machine” Yarn drift .
The migration path. Yarn provides yarn set version to switch versions within an existing project. Running yarn set version stable downloads the latest Berry release and updates the project’s configuration. Running yarn set version classic reverts to Yarn 1.x. The command writes the version to .yarnrc.yml and the packageManager field, making the switch persistent .
The trade-off. Corepack requires Node.js 16.10 or later and one extra setup step (corepack enable). Yarn 1.x installations are simpler to explain but harder to maintain across multiple projects. The per-project model trades a one-time setup cost for long-term reproducibility.
a. Enabling Corepack and activating Yarn
Corepack is bundled with Node.js but disabled by default. Enabling it creates shim binaries for yarn, pnpm, and npm in your PATH. These shims are not the actual package managers—they are routers that read your project’s configuration and delegate to the correct version .
# Enable Corepack (run once per machine)
corepack enable
# Verify Corepack is active
corepack --version
# Output: 0.28.1 (or similar)
On Windows, you may need to run this command in an administrator PowerShell session. On macOS and Linux, a regular user session suffices. After enabling, restart your terminal or IDE for the shims to take effect .
Once Corepack is active, navigating to a project with a packageManager field and running yarn --version will automatically download and execute the specified version. If the project has no packageManager field, Corepack falls back to the latest stable Yarn release .
b. Initializing a new project with Yarn
For a new project, the workflow depends on whether you want Yarn Classic or Berry. Yarn 1.x (Classic) is the default when no version is specified. Berry requires an explicit version pin .
# Create a new directory and enter it
mkdir my-project && cd my-project
# Initialize with Yarn Classic (default)
yarn init -y
# Initialize with Yarn Berry (version 4)
corepack enable
yarn init -2
The -2 flag tells Yarn to initialize a Berry project. This generates a .yarnrc.yml file and sets the packageManager field in package.json to the installed Berry version. The yarnPath setting in .yarnrc.yml points to the local Yarn binary stored inside the project .
For existing projects migrating from Yarn 1.x, the command is yarn set version stable. This downloads the latest Berry release, updates the configuration, and converts the lockfile format automatically .
c. Upgrading Yarn within a project
Yarn provides the set version command to lock the project to a specific release. This is not a global upgrade—it modifies the project’s configuration so that future invocations use the new version .
# Upgrade to the latest stable Berry release
yarn set version stable
# Upgrade to a specific version
yarn set version 4.5.0
# Upgrade to the latest canary (release candidate)
yarn set version canary
# Downgrade to Yarn Classic (1.x)
yarn set version classic
After running set version, the project’s .yarnrc.yml is updated with the new yarnPath, and package.json receives the new packageManager value. Run yarn install to regenerate the lockfile and dependency tree with the new version .
If you encounter errors after upgrading, the most common cause is a stale cache or leftover PnP files from the previous version. Remove .yarn/cache, .pnp.cjs, and .pnp.loader.mjs, then run yarn install again .
Complete Example Session
# ============================================
# PART 1: ENABLING COREPACK
# ============================================
# Corepack ships with Node.js but is disabled by default.
# Enable it once per machine.
corepack enable
# Verify the shim is active.
corepack --version
# ============================================
# PART 2: CHECKING NODE.JS VERSION
# ============================================
# Corepack requires Node.js 16.10 or later.
# Modern Yarn (Berry) requires Node.js 18.12 or later.
node --version
# Output: v20.11.0 (or similar)
# ============================================
# PART 3: INITIALIZING A BERRY PROJECT
# ============================================
# The -2 flag initializes with Yarn Berry.
mkdir berry-project && cd berry-project
yarn init -2
# This creates .yarnrc.yml and sets packageManager.
cat .yarnrc.yml
# yarnPath: .yarn/releases/yarn-4.5.0.cjs
# ============================================
# PART 4: PINNING A VERSION
# ============================================
# The packageManager field locks the version.
cat package.json
# "packageManager": "yarn@4.5.0"
# Any developer who clones this repo gets Yarn 4.5.0.
yarn --version
# Output: 4.5.0
# ============================================
# PART 5: UPGRADING WITHIN THE PROJECT
# ============================================
# Upgrade to the latest stable Berry release.
yarn set version stable
# The .yarnrc.yml and package.json are updated.
yarn --version
# Output: 4.6.0 (or newer)
# ============================================
# PART 6: DOWNGRADING TO CLASSIC
# ============================================
# Revert to Yarn 1.x for compatibility testing.
yarn set version classic
# The project now uses Classic's node_modules layout.
yarn --version
# Output: 1.22.22
# ============================================
# PART 7: UPGRADING FROM CLASSIC TO BERRY
# ============================================
# Start from a Yarn 1.x project.
yarn --version
# Output: 1.22.22
# Upgrade to Berry.
yarn set version stable
# The lockfile is converted automatically.
yarn install
# ============================================
# PART 8: CLEANING UP AFTER UPGRADE
# ============================================
# If the upgrade fails, remove stale artifacts.
rm -rf .yarn/cache .pnp.cjs .pnp.loader.mjs
# Reinstall with the new version.
yarn install
# ============================================
# PART 9: CI CONFIGURATION
# ============================================
# CI runners must enable Corepack before installing.
# In GitHub Actions:
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: yarn install --immutable
The nine parts above cover the full lifecycle: enabling Corepack, verifying Node.js compatibility, initializing Berry, pinning versions, upgrading, downgrading, migrating from Classic, cleaning up, and configuring CI. Each step is a concrete action that produces a verifiable result.
Quick Reference
Installation Methods
| Method | Command | Scope |
|---|---|---|
| Corepack | corepack enable | Per-machine, per-project routing |
| npm global (Classic) | npm install -g yarn | Global, Yarn 1.x only |
| Homebrew (macOS) | brew install yarn | Global, Yarn 1.x |
| Yarn Switch | curl -sS https://repo.yarnpkg.com/install | bash | Per-project, experimental |
Version Commands
| Command | Effect |
|---|---|
yarn set version stable | Latest stable Berry (4.x) |
yarn set version 4.5.0 | Specific version |
yarn set version classic | Yarn 1.x |
yarn set version canary | Release candidate |
yarn set version self | Version currently running |
Files Modified by Version Changes
| File | Change |
|---|---|
package.json | packageManager field updated |
.yarnrc.yml | yarnPath updated |
yarn.lock | Regenerated on next install |
.pnp.cjs | Regenerated on next install |
Best Practices
✅ Do This:
corepack enable
<!-- Run once per machine, enables per-project routing --> # ✅
{
"packageManager": "yarn@4.5.0"
}
<!-- Pin exact version in package.json --> # ✅
yarn set version stable
<!-- Upgrade within the project, not globally --> # ✅
yarn install --immutable
<!-- CI uses immutable lockfile verification --> # ✅
rm -rf .yarn/cache .pnp.cjs
<!-- Clean stale artifacts after version change --> # ✅
❌ Don’t Do This:
npm install -g yarn
<!-- Global install bypasses Corepack --> # ❌
yarn --version
# Output: 1.22.22 (global Classic)
<!-- Project expects Berry, runs Classic --> # ❌
# Ignore packageManager field
<!-- Results in version drift across machines --> # ❌
# Skip corepack enable in CI
<!-- CI falls back to global or fails --> # ❌
# Upgrade globally and hope projects follow
<!-- Breaks reproducibility --> # ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
yarn --version shows 1.x in Berry project | Corepack not enabled | Run corepack enable |
| CI fails with “Yarn not found” | Corepack not enabled in workflow | Add corepack enable step |
| Upgrade breaks PnP resolution | Stale .pnp.cjs from previous version | Delete .pnp.cjs and .yarn/cache |
yarn set version fails | Network error or corrupted cache | Clear Corepack cache, retry |
| Multiple Yarn versions conflict | Global install coexists with Corepack | Uninstall global Yarn, use Corepack only |
| IDE cannot find Yarn | Terminal restarted, IDE not | Restart IDE after corepack enable |
Real-World Examples
1. Enabling Corepack
corepack enable
2. Verifying Installation
yarn --version
3. Initializing Berry Project
yarn init -2
4. Pinning Version in package.json
{
"packageManager": "yarn@4.5.0"
}
5. Upgrading to Latest Berry
yarn set version stable
6. Downgrading to Classic
yarn set version classic
7. Migrating from Classic
yarn set version stable
yarn install
8. Cleaning After Upgrade
rm -rf .yarn/cache .pnp.cjs .pnp.loader.mjs
9. CI Corepack Step
- name: Enable Corepack
run: corepack enable
10. Immutable Install in CI
yarn install --immutable
Visual
Corepack Routing
┌──────────────────────────────────────────────┐
│ Terminal: yarn install │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Corepack Shim (in PATH) │
│ │
│ 1. Read package.json │
│ 2. Find "packageManager": "yarn@4.5.0" │
│ 3. Download Yarn 4.5.0 if not cached │
│ 4. Execute yarn install with 4.5.0 │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Yarn 4.5.0 Executes │
│ │
│ Project A: yarn@4.5.0 → runs 4.5.0 │
│ Project B: yarn@4.6.0 → runs 4.6.0 │
│ No conflicts. No global state. │
└──────────────────────────────────────────────┘
Corepack decouples the binary from the global PATH. Each project declares its version, and Corepack enforces it.
Version Upgrade Flow
┌──────────────────────────────────────────────┐
│ Project uses Yarn 4.5.0 │
│ packageManager: "yarn@4.5.0" │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ yarn set version stable │
│ │
│ 1. Download latest Berry (4.6.0) │
│ 2. Update .yarnrc.yml yarnPath │
│ 3. Update package.json packageManager │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ yarn install │
│ │
│ 1. Regenerate yarn.lock │
│ 2. Rebuild .pnp.cjs │
│ 3. Project now runs 4.6.0 │
└──────────────────────────────────────────────┘
The upgrade is a project-level operation. It writes version information to configuration files and regenerates the dependency artifacts on the next install.
CI Setup Sequence
┌──────────────────────────────────────────────┐
│ CI Runner (fresh environment) │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ corepack enable │
│ │
│ Creates shims in CI PATH │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ yarn install --immutable │
│ │
│ 1. Corepack reads packageManager field │
│ 2. Downloads specified version │
│ 3. Executes install with immutable lockfile │
│ 4. Fails if lockfile would change │
└──────────────────────────────────────────────┘
The CI workflow must enable Corepack before invoking Yarn. Without this step, the runner may use a globally installed version or fail entirely .
Summary
| Item | Value |
|---|---|
| Corepack ships with | Node.js 16.10+ |
| Enable command | corepack enable |
| Version field | packageManager in package.json |
| Upgrade command | yarn set version stable |
| Downgrade command | yarn set version classic |
| Pin exact version | yarn set version 4.5.0 |
| CI requirement | corepack enable before install |
| Cleanup after upgrade | Remove .yarn/cache, .pnp.cjs |
| Global install | Not recommended for Berry |
| Yarn Berry Node.js minimum | 18.12 |
Key takeaways:
- Corepack replaces global installation. It routes
yarncommands to the version declared in each project, eliminating version conflicts across projects . - The
packageManagerfield is the contract. Committing it to version control ensures every developer and CI runner uses the same Yarn version . yarn set versionmodifies the project, not the machine. Upgrading or downgrading is a project-level operation that writes to.yarnrc.ymlandpackage.json.- CI must enable Corepack explicitly. Without it, the runner may use a global Yarn or fail to find the correct version .
- Clean stale artifacts after version changes. Leftover
.pnp.cjsor cache files from a previous version cause resolution errors . - Global Yarn installs are a legacy path.
npm install -g yarninstalls Classic and bypasses Corepack. For Berry projects, this is never the right approach. - Yarn Switch is the experimental future. Yarn 6 introduces Yarn Switch as a Corepack alternative, but it is not yet stable for general use .
Remember: Installing Yarn is no longer a one-time global action. It is a per-project configuration that travels with the repository. Enable Corepack once, pin the version in package.json, and let the tooling handle the rest. The version that runs on your machine is the version that runs in CI—because the project itself declares it.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!