little cubes

How to install corepack

For deterministic dependency installation

Corepack is a package manager, manager.

  • The purpose of a package manager is to ensure that everyone installs exactly the same version of a projects dependencies.
    • But that is not guaranteed if different people are using different versions of the same package manager.
  • A package manager manager then ensures that everyone installs exactly the same version of that package manager, ensuring that your project installs are always deterministic.
  • Different versions of a package manager can result in different versions of dependencies getting installed and cause lock file versioning issues

Similar to how nvm/fnm lets you have multiple versions of node installed simultaneously, Corepack lets you have multiple versions of npm/pnpm/yarn installed.

Install Corepack on your machine

Section titled: Install Corepack on your machine

First uninstall existing package managers

Section titled: First uninstall existing package managers

First uninstall your global yarn and pnpm binaries (just leave npm).

How you do this will differ depending on how you installed them in the first place. These two commands are a good place to start:

Terminal window
npm uninstall -g yarn pnpm
brew uninstall yarn

Now check if there are still other versions installed:

Terminal window
which pnpm # we want: "pnpm not found"
which yarn # we want: "yarn not found"

If which outputs “not found”, then you’re good to go. If it outputs a file path, then that’s where the binary that you still have to remove lives.

If you don’t know how to uninstall it based on the path, then you can always just rm -rf the directory that which output.

Now install the latest version of Corepack

Section titled: Now install the latest version of Corepack
Terminal window
npm i -g corepack@latest
corepack enable

Now go into any project and try to use the appropriate package manager, you’ll see something like the following:

Terminal window
pnpm -v
! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-9.15.2.tgz
? Do you want to continue? [Y/n]

Hit y or enter Corepack will automatically download and start using the specified version of that package manager. If the project doesn’t specify a package manager version (boo 👎) then it will default to a known good version; but continue reading the next section to see how to fix that.

To specify a particular package manager version in your project, you’ll want to run the corepack use command:

Terminal window
corepack use pnpm
corepack use yarn@1
corepack use npm@latest

This will add a packageManager field at the bottom of the package.json:

"packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b"

This accomplishes two things for all other developers with Corepack enabled:

  1. Running pnpm install will automatically download and use pnpm version 10.15.0, ensuring deterministic project installs
  2. Trying to use any other package manager to install dependencies will result in an error:
    This project is configured to use pnpm because /my-project/package.json has a "packageManager" field
Terminal window
corepack install
Type Error: URL.canParse is not a function

Node 16 comes preinstalled with one of corepack 0.10, 0.11, or 0.12. All three of those versions of corepack predate the corepack use command, so they operate significantly different than the modern version.

But using the latest of Corepack version relies on the URL.canParse() method which was introduced in Node.js version 19.9.0 and backported 18.17.0.

This creates a catch-22 where you can’t use the Node 16 (no corepack use) or the Node 24 (url parse error) version of Corepack to get a packageManager field added to your package.json.

I’ve found two solutions to this problem:

  1. Manually specify the packageManager field, without the optional hash.
    "packageManager": "yarn@1.22.22"
  2. Use corepack v0.20.0; npm i -g corepack@0.20.0. I’ve found that this version specifically straddles the line where it doesn’t use URL.canParse() but does have the corepack use command.