Skip to content

chore: pin npm via corepack to stop package-lock drift - #264

Merged
raymondk merged 1 commit into
mainfrom
chore/pin-node-npm-version
Aug 4, 2026
Merged

chore: pin npm via corepack to stop package-lock drift#264
raymondk merged 1 commit into
mainfrom
chore/pin-node-npm-version

Conversation

@marc0olo

@marc0olo marc0olo commented Aug 4, 2026

Copy link
Copy Markdown
Member

Problem

npm i kept rewriting package-lock.json with no dependency change. The cause is npm-version skew between contributors and CI — and it turned out to bite at the patch level:

  • CI pinned node-version: 22 → npm 10; local Node 24 → npm 11. npm 11 serializes the lockfile differently (peer flags, optional-peer handling), and since npm ci never rewrites the lockfile, the format ping-ponged between anyone who ran npm i.
  • Worse, even within npm 11 the behavior differs by patch: npm 11.6.2 (a local Node 24 build) prunes the optional-peer @emnapi/core / @emnapi/runtime entries, while CI's npm 11.16.0 npm ci requires them. A lockfile written by 11.6.2 therefore fails CI with npm ci can only install ... when package.json and package-lock.json are in sync.

So a version floor alone is not enough — the fix has to make everyone use one exact npm.

Fix

Pin the exact npm with corepack, for contributors and both CI jobs:

Change Purpose
package.json"packageManager": "npm@11.16.0" corepack resolves this exact npm locally + in CI, regardless of what Node bundles
corepack enable step in both workflows CI uses the pinned npm instead of Node's (drifting) bundled npm
engines: node >=22, npm >=11.16.0 + .npmrc engine-strict=true A pre-11.16.0 npm fails fast instead of silently rewriting the lockfile
.nvmrc24; both workflows node-version: 22node-version-file: .nvmrc Single Node pin; CI + nvm use stay aligned
package-lock.json regenerated with npm 11.16.0 Canonical, complete tree (keeps the optional-peer entries CI needs)

The lockfile diff is a 12-line normalization: adds the engines block and lets npm 11.16.0 tidy peer flags. No dependency version or integrity changes; 0 vulnerabilities.

Contributor note (one-time)

corepack ships with Node. Enable the npm shim once:

corepack enable npm

After that, npm in this repo automatically resolves to the pinned 11.16.0. If you're on an older npm without corepack enabled, engine-strict will refuse to install until you do.

Verification

corepack-resolved npm ci + build + stability
$ npm -v
11.16.0                      # via corepack, from packageManager pin

$ npm install --package-lock-only   # settled lockfile
LOCKFILE UNCHANGED           # stable — no churn across runs

$ npm ci
found 0 vulnerabilities

$ npm run build
[build] 30 page(s) built
[build] Complete!

@marc0olo
marc0olo requested review from a team and JoshDFN as code owners August 4, 2026 13:16
`npm i` kept rewriting package-lock.json with no dependency change. Root
cause is npm-version skew across contributors and CI:

- CI pinned Node 22 → npm 10; local Node 24 → npm 11. npm 11 serializes
  the lockfile differently (peer flags, optional-peer handling), and
  `npm ci` never rewrites it, so the format ping-ponged.
- Worse, the skew is patch-level: npm 11.6.2 prunes the optional-peer
  @emnapi/* entries while CI's npm 11.16.0 `npm ci` requires them — so a
  lockfile written by 11.6.2 fails CI outright.

Fix: make everyone — contributors and both CI jobs — use one exact npm.

- package.json `packageManager: npm@11.16.0`; corepack resolves that exact
  npm locally and in CI (`corepack enable` step in both workflows).
- engines floor node >=22, npm >=11.16.0 + .npmrc engine-strict=true so a
  pre-11.16.0 npm fails fast instead of silently rewriting the lockfile.
- .nvmrc → 24; both workflows switch node-version 22 → node-version-file.
- Regenerate package-lock.json with npm 11.16.0 (canonical, complete tree).
@marc0olo
marc0olo force-pushed the chore/pin-node-npm-version branch from 12b2813 to 8ee812b Compare August 4, 2026 13:33
@marc0olo marc0olo changed the title chore: pin Node/npm to stop package-lock format drift chore: pin npm via corepack to stop package-lock drift Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Skill Validation Report

No skill files were changed in this PR — validation skipped.

@raymondk
raymondk merged commit ec170c6 into main Aug 4, 2026
6 checks passed
@raymondk
raymondk deleted the chore/pin-node-npm-version branch August 4, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants