| |

Yarn 02 🧶 Installing and Upgrading Yarn

⏱️ Estimated read: 10 min | |

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

MethodCommandScope
Corepackcorepack enablePer-machine, per-project routing
npm global (Classic)npm install -g yarnGlobal, Yarn 1.x only
Homebrew (macOS)brew install yarnGlobal, Yarn 1.x
Yarn Switchcurl -sS https://repo.yarnpkg.com/install | bashPer-project, experimental

Version Commands

CommandEffect
yarn set version stableLatest stable Berry (4.x)
yarn set version 4.5.0Specific version
yarn set version classicYarn 1.x
yarn set version canaryRelease candidate
yarn set version selfVersion currently running

Files Modified by Version Changes

FileChange
package.jsonpackageManager field updated
.yarnrc.ymlyarnPath updated
yarn.lockRegenerated on next install
.pnp.cjsRegenerated 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

PitfallWhy It HappensFix
yarn --version shows 1.x in Berry projectCorepack not enabledRun corepack enable
CI fails with “Yarn not found”Corepack not enabled in workflowAdd corepack enable step
Upgrade breaks PnP resolutionStale .pnp.cjs from previous versionDelete .pnp.cjs and .yarn/cache
yarn set version failsNetwork error or corrupted cacheClear Corepack cache, retry
Multiple Yarn versions conflictGlobal install coexists with CorepackUninstall global Yarn, use Corepack only
IDE cannot find YarnTerminal restarted, IDE notRestart 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

ItemValue
Corepack ships withNode.js 16.10+
Enable commandcorepack enable
Version fieldpackageManager in package.json
Upgrade commandyarn set version stable
Downgrade commandyarn set version classic
Pin exact versionyarn set version 4.5.0
CI requirementcorepack enable before install
Cleanup after upgradeRemove .yarn/cache, .pnp.cjs
Global installNot recommended for Berry
Yarn Berry Node.js minimum18.12

Key takeaways:

  • Corepack replaces global installation. It routes yarn commands to the version declared in each project, eliminating version conflicts across projects .
  • The packageManager field is the contract. Committing it to version control ensures every developer and CI runner uses the same Yarn version .
  • yarn set version modifies the project, not the machine. Upgrading or downgrading is a project-level operation that writes to .yarnrc.yml and package.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.cjs or cache files from a previous version cause resolution errors .
  • Global Yarn installs are a legacy path. npm install -g yarn installs 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.

Was this helpful?


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!