Node.js, part 18: Corepack — pinning the package manager instead of documenting it
Part 18from the Node.js series · 24 parts in all
"We use pnpm 8" lives in a wiki, in CI config, in a README, and in someone's global install — four places that drift. Corepack, shipped with Node from 16.9 and on-by-default in some releases, moves that fact into the repository where the other reproducibility facts live.
The declaration
{
"name": "maplecart",
"packageManager": "[email protected]+sha512.0f…",
"scripts": { "test": "pnpm -r test" }
}
corepack enable # shims for npm, yarn, pnpm on PATH
corepack prepare [email protected] --activate # explicit, if you do not trust the field
With packageManager set, running pnpm install in the repo uses
that pnpm — downloaded and cached on demand, not the one on your machine. The
+sha512… suffix pins the exact build, so the field is both a version and an
integrity check.
What this actually fixes
- The "works on my machine" class of bug that is nobody's code. A lockfile written by pnpm 7 read by pnpm 9 is a real source of phantom diffs.
- Onboarding is one command. No "which Node version manager do you use" — the answer is in the file, and Corepack is the only thing that needs installing.
- CI stops having a special install step. The same declaration that guides a laptop guides the runner.
The caveats worth knowing
Corepack was shipped on-by-default and has since moved toward opt-in, precisely because
silently downloading a binary from the internet is a supply-chain decision, not a formatting
one. In a locked-down environment, pre-install the manager and use
COREPACK_ENABLE_DOWNLOAD_PROMPT=0 deliberately rather than by default. And
Corepack does not replace a Node version file — .nvmrc or the
engines field still says which runtime, which is a separate question. Next: the
capability model that arrived in Node 20.