Yarn Berry Migration Guide
Overview
This guide explains how to migrate a Party Bus project from Yarn Classic (v1.22.22) to Yarn Berry (Yarn 4.x). It covers:
- Preparing your development environment
- Testing Yarn Berry without affecting production pipelines
- Updating your project configuration
- Resolving common migration issues
- Completing the migration
Use this document to understand the basics of the upgrade, Party Bus-specific requirements, and recommended best practices for migrating from Yarn Classic to Yarn Berry. With this update comes several changes to commands, project structure, and tool design that you will need to be aware of.
Deprecation Notice: Yarn Classic pipelines
WARNING
Yarn Classic (v1.22.22) support is being deprecated and will be removed in a future Party Bus release. Customers should begin migrating to Yarn Berry (Yarn 4.x) before the retirement date is announced.
Yarn Berry provides improved dependency management, faster and more reliable installations, stricter dependency resolution through PnP, immutable installs, and ongoing support from the Yarn project.
To help customers migrate with minimal disruption, Party Bus provides a migration window during which you can test Yarn Berry alongside your existing Yarn Classic pipelines. During this period, you can validate your project, resolve compatibility issues, and complete the migration when you are ready.
The migration timeline and final retirement date for Yarn Classic will be announced separately.
Yarn Berry template
To help customers with this migration, Yarn Berry will be available for testing in customer projects alongside existing Yarn Classic pipelines.
To accomplish this, we have created a separate template for Yarn Berry that is enabled by doing one of the following:
- Create a branch that starts with
pbmdo-yarn-update - Set
USE_YARN_BERRYtotrue
INFO
To clarify, using the pbmdo-yarn-update branch prefix is for testing Yarn Berry alongside Yarn Classic, and the USE_YARN_BERRY environment variable is used to complete the migration to Yarn Berry.
This will allow customers to test how Yarn Berry works and move to it fully before the migration deadline, once they are ready.
Pipeline differences
Once this migration window is live, all Yarn Classic jobs will be labeled yarn-install-old, while the new Yarn Berry jobs will now show as the standard yarn-install.
From the user's perspective, these jobs accomplish the same goal, but under the hood, they function very differently. This applies to the unit-test and lint jobs.
TIP
Yarn versions are printed in the yarn-install job output as well.
There will also be two new jobs in your pipelines: yarn-install-prod and yarn-run-ci.
yarn-install-prod
In Yarn Modern pipelines, the build-image job will now inherit its dependencies from yarn-install-prod instead of yarn-install.
The yarn-install-prod job installs only production dependencies. This prevents development dependencies from being included in the final image deployed to production. As a result, production images will be smaller and may have fewer exploitable vulnerabilities.
The lint and unit-test jobs will continue to inherit their dependencies from yarn-install. This ensures that they have access to both production and development dependencies.
:::note As indicated above, the dependencies available in .yarn/cache in the build-image job will only include production dependencies. Please see the section below for customers who have complications with that change. :::
yarn-run-ci
You may need to perform additional build operations after yarn-install installs the dependencies, but before packaging the application with build-image.
Previously, these steps could be performed in the build-image job. However, because build-image will no longer have access to development dependencies, some customers will not be able to perform these build operations in build-image.
To support this use case, we have added the yarn-run-ci job. This job inherits the production and development dependencies from yarn-install.
TIP
Please Note: The yarn-run-ci job looks for a script named pb:ci in the application's package.json file. If the script exists, the job runs it. Customers can define the pb:ci script to perform additional build operations that require development dependencies.
Migration overview
Prerequisites
Before you begin, ensure that you have:
- Node.js 22 or later
- Git access to your repository
- Permission to modify project CI/CD variables
- A protected branch available for testing
Process overview
To migrate to Yarn Berry, you will navigate the following process:
Install Yarn Berry in your development environment.
Create a new branch with the
pbmdo-yarn-updateprefix and ensure the branch is protected.Delete your existing Yarn configuration file (
.yarnrc).Create a new Yarn configuration file (
.yarnrc.yml) and modify your.gitignoreto align with Party Bus requirements.Run
yarn installto update your lockfile, then commit and push changes.Check the running pipeline and resolve any issues that arise.
When you are ready to complete the migration, merge changes to the default branch and set
USE_YARN_BERRYto true in your project's CI/CD vars.
Key differences between Yarn Classic and Yarn Berry
Enforced Plug'n'Play and removal of node_modules
PnP is currently the only supported nodeLinker in MDO Party Bus pipelines. When using PnP, you will notice your node_modules folder disappears. Dependencies are instead stored as archives inside the .yarn/cache folder and mapped directly into Node using the .pnp.cjs mapping file.
This dependency resolution model improves installation performance and provides stricter dependency boundaries by preventing undeclared dependencies from being resolved. This is also the default nodeLinker for Yarn Berry and is the recommended dependency resolution mode for Party Bus Yarn Berry pipelines.
With this change, some legacy scripts and dependencies will no longer be supported. However, most modern tooling supports PnP. For the time being, customers who require node_modules or dependencies that are not compatible with PnP must use npm pipelines.
Enforced immutable installs in CI/CD
Similar to how Yarn Classic ran with the --frozen-lockfile flag in the yarn-install job, installs for Yarn Berry will be run with the --immutable flag to ensure that the pipeline fails immediately if the install would modify the lockfile:
yarn install --immutableEnforced disablement of lifecycle scripts
Party Bus disables Yarn lifecycle scripts during pipeline execution to reduce supply-chain risk. Projects should ensure enableScripts remains disabled locally to match pipeline behavior.
yarnPath is disabled in pipelines
While Yarn Berry does allow you to specify a path to a specific yarn berry binary, we disable this feature and enforce the use of the yarn4 binary included in Iron Bank Node.js images. This also means that any scripts defined in your package.json or Yarn commands run in your Dockerfile must be updated to use yarn4 instead of yarn.
Since yarnPath is disabled, it is recommended not to commit anything under .yarn/releases.
This also means that any scripts defined in your package.json or Yarn commands you run in your Dockerfile will need to be updated to use yarn4 instead of Yarn for all Yarn commands.
Switching node images
Moving forward, Yarn pipelines will no longer utilize NPM_CI_IMAGE and instead use NODEJS_YARN_IMAGE to specify the image used in the yarn-install, lint, and unit-test jobs.
To specify a particular version, we also made the following vars available for use in Yarn Berry pipelines: NODEJS_YARN_IMAGE_22, NODEJS_YARN_IMAGE_24, NODEJS_YARN_IMAGE_26
WARNING
If you override the image to use a value beyond these predefined versions, you will need to ensure you utilize an Iron Bank Node.js with -yarn4 added to the tag.
WARNING
Whenever switching Node versions for your pipeline image, please ensure you clear the runner cache between pipeline runs.
TIP
It is recommended to use the same image for testing Yarn Classic and Yarn Berry (Iron Bank packages both in their Node.js images) to avoid issues.
The build-image job inherits only production dependencies
In the Yarn Berry template, the yarn-install job installs both production and development dependencies by running:
yarn install --immutableThe Yarn Berry template now also includes the yarn-install-prod job. This job installs only production dependencies by running:
yarn workspaces focus --all --productionThe installed dependencies are stored as artifacts in the .yarn/cache directory so that subsequent jobs can reuse them.
Installing only production dependencies in yarn-install-prod provides two key benefits:
- The
build-imagejob and other jobs that require only production dependencies can inherit fromyarn-install-prod. This avoids including unnecessary development dependencies and reduces the dependency footprint. - The
lint,unit-test, andyarn-run-cijobs can continue to use development dependencies by inheriting fromyarn-install.
The following Yarn PnP files and directories are also preserved as artifacts in both yarn-install and yarn-install-prod:
.pnp.cjs.pnp.loader.mjs.yarn/install-state.gz.yarn/unplugged/
Preserving these files allows Yarn to reuse its existing installation state, reducing the time required to install development dependencies in downstream jobs.
Prepare your development environment
Before migrating your project, ensure your development environment is ready to use Yarn Berry.
Use a container (optional)
While you can use your existing development environment, some customers may find it easier to perform the migration in a container.
For example, using podman:
podman run -it --rm \
--entrypoint /bin/bash \
--workdir /home/node \
--user root \
-v ~/Documents/repos/my-cool-yarn-project:/home/node:Z \
registry1.dso.mil/ironbank/opensource/nodejs/debian/nodejs:24-npm11-yarn4Replace ~/Documents/repos/my-cool-yarn-project with the path to your local repository and update the image tag if your project uses a different Node.js version.
Once the container is running, you can complete the remaining steps in this guide from within the container.
Install Corepack
Yarn Berry is managed through Corepack, which is included with supported Node.js versions.
If Corepack is unavailable or disabled in your Node.js installation, install it globally:
npm install -g corepackWARNING
You may experience issues installing corepack if you have pnpm installed.
Enable Corepack
Enable Corepack on your machine by running:
corepack enableSet the Yarn version
From the root of your project, run:
yarn set version stableThis command:
- Updates
package.jsonwith a"packageManager": "yarn@4.x.x"field. - Creates
.yarnrc.ymlif it does not already exist. - Downloads the Yarn release to
.yarn/releases/.
These changes ensure that everyone working on the project uses the same version of Yarn. This produces:
.yarn/.yarn/releases/yarn-4.x.cjs.yarnrc.yml(if not present)
Configure your project
This section prepares your project to use Yarn Berry and the Party Bus Yarn Berry pipeline.
Create a migration branch
To test your project with the Yarn Berry pipeline, create a branch named pbmdo-yarn-update or one that begins with the pbmdo-yarn-update prefix. Party Bus uses this branch naming convention to select the Yarn Berry pipeline template.
To create this new branch and switch to it, run:
git checkout -b pbmdo-yarn-updateTIP
To run pipelines for this branch, you may want to add a protected branch pattern for pbmdo-yarn-update to your project.
Configure Yarn Berry
Yarn Berry uses a YAML-based configuration file (.yarnrc.yml) instead of the legacy .yarnrc or .npmrc. file.
Delete the existing
.yarnrcfile from your project, if present.Create a new
.yarnrc.ymlfile in the root of your repository.Add the following recommended configuration:
yamlenableScripts: false npmMinimalAgeGate: 1 approvedGitRepositories: [] nodeLinker: pnp
This configuration aligns with the Party Bus Yarn Berry pipeline requirements and recommended security settings.
The following sections explain each configuration option and when you may need to customize it.
Configure Plug'n'Play
Party Bus Yarn Berry pipelines support PnP as the only supported nodeLinker. Unlike Yarn Classic, PnP does not install dependencies into a node_modules directory. Dependencies are stored as archives in .yarn/cache and resolved at runtime through the .pnp.cjs manifest generated by Yarn.
By default, Yarn Berry uses pnp as the nodeLinker. However, you should verify that your project has not been configured to use node-modules.
You can validate or update this setting by editing .yarnrc.yml or by running the following commands from the root of your repository:
yarn config get nodeLinker
yarn config set nodeLinker pnpWARNING
node-modules is not supported by Party Bus Yarn Berry pipelines. Projects that require node_modules or depend on packages that are not compatible with PnP must continue using the npm pipelines.
Disable lifecycle scripts
Yarn Berry has the .yarnrc.yml setting enableScripts that, when set to false, blocks all post-install scripts during installs. Make sure enableScripts is disabled.
Behavior:
- As of 4.14.0, this is disabled by default.
- Running
yarn installcompletes successfully, but Yarn reports dependencies with lifecycle scripts and indicates that those scripts were disabled. - Exceptions can be configured using dependenciesMeta in
package.json. - Is the planned default for 4.14 according to the docs.
You can validate/change this by editing your .yarnrc.yml or by running the following commands from the root of your repo:
yarn config get enableScripts
yarn config set enableScripts falseConfigure npmMinimalAgeGate
Yarn 4.10.0+ includes the .yarnrc.yml setting npmMinimalAgeGate, which requires package versions to be at least N days old before Yarn installs them.
Behavior:
- If no release candidate can be found that meets the age requirement,
yarn installwill exit with a non-zero status and error message. - You can add exceptions for this by adding a package to npmPreapprovedPackages in the
.yarnrc.yml.
We recommend setting npmMinimalAgeGate to a value between 1 and 3 (in days) to mitigate the risk of supply-chain attacks. Set this by running the following command from the root of your repository:
yarn config set npmMinimalAgeGate 1Configure approvedGitRepositories (optional)
Yarn 4.14.0+ has the .yarnrc.yml setting approvedGitRepositories, which can be used to prevent installation of git‑based dependencies when set to [].
Behavior:
- If dependency is not in
approvedGitRepositoriesthen yarn install exits with a non-zero status and error. - Exceptions to the no Git repository dependency rule are done via
approvedGitRepositoriesitself (dependencies are added as inclusions to that list).
Configure Git for your project
Update .gitignore
To ensure your project's configuration works well with MDO pipelines, please add the following to your .gitignore:
# Ignore everything under .yarn/ except patches and plugins
.yarn/*
!.yarn/patches
!.yarn/plugins
# Ignore PnP dependency maps. These output files are regenerated during installation
.pnp.*- Plugins modify how Yarn operates; committing them guarantees identical behavior across machines and CI.
- Patch files represent corrected third‑party code; committing ensures fixes are preserved and reproducible across all installs.
(Optional) Update .gitattributes
To prevent Git from showing massive text diffs if you update Yarn or plugins, you can add a .gitattributes file to your root as well:
/.yarn/plugins/** binaryUpdate project dependencies
After configuring your project for Yarn Berry, update your dependencies and lockfile by running the install command from the root of your repository:
yarn installThis command will:
- Create
.yarn/cache(zip archives for dependencies) - Create
.pnp.cjs(if using PnP) - Rewrite
yarn.lockin the Yarn Berry format
Review the generated changes before committing them to your branch.
Commit the following files (they form the source of truth and are required to reproduce installs):
package.jsonyarn.lock.yarnrc.yml.yarn/plugins/.yarn/patches/
Do not commit generated install output files, such as:
.yarn/cache/.yarn/unplugged/*.yarn/install-state.gz.pnp.cjs.pnp.loader.mjs
These files are regenerated during installation and are managed through GitLab CI caching.
Validate the migration
Push your pbmdo-yarn-update branch to trigger the Yarn Berry pipeline. Party Bus will detect the branch prefix and use the Yarn Berry pipeline template.
Verify that:
- The install job is labeled
yarn-install. - The Yarn version displayed in the job output is Yarn 4.x.
- The
yarn-install,lint, andunit-testjobs complete successfully.
If any jobs fail, resolve the reported issues before completing the migration. Common migration issues include:
- Dependencies that are not compatible with PnP.
- Lockfile changes that were not committed.
- Dependencies that rely on lifecycle scripts.
Complete the migration
Once your Yarn Berry pipeline is running successfully, you can complete the migration.
- Merge the validated changes into your default branch.
- Set the
USE_YARN_BERRYCI/CD variable to true in your project configuration.
After this variable is enabled, Party Bus will use the Yarn Berry pipeline template for subsequent pipelines.
Your project is now migrated from Yarn Classic to Yarn Berry.
Troubleshooting
| Issue | Resolution |
|---|---|
| Dependency incompatible with PnP | Use a supported package or migrate to npm pipeline |
| Lifecycle script failure | Review package dependency scripts and approved exceptions |
| Lockfile changes unexpectedly | Run yarn install locally and commit changes |
| Package does not support PnP | Check package documentation for PnP support or migrate to npm pipelines |