chore(ci): CI runs Node 20 while production runs 24 — and pnpm 11 (#89) cannot run on 20 at all
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 2
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 18
Description
## What happens
`chore(deps): update pnpm to v11` (#89) fails CI, and it is not a code defect. The `web · type-check
+ tests` job dies before running anything:
```
Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:sqlite
at ../store/index/lib/index.js (.../pnpm@11.5.3/node_modules/pnpm/dist/pnpm.mjs:54998:25)
Node.js v20.20.2
```
`node:sqlite` is the symptom. The cause is a declared engine constraint:
```
$ npm view pnpm@11.5.3 engines
{ node: '>=22.13' }
```
CI runs Node 20. **pnpm 11 cannot run there at all**, so #89 can never go green as configured, no
matter how many times its lockfile is regenerated.
## Root cause
`.github/workflows/ci.yml` on `main` pins `node-version: '20'`. There is no `.nvmrc` on `main` today;
#248 adds one, also set to `20`, and pm-kit's detection step prefers `.nvmrc` over the workflow input
— so after #248 lands, `.nvmrc` becomes the single source of truth for the CI Node version.
## The bigger issue underneath
**CI runs Node 20 while production runs Node 24.** #248 states this in its own commit
(`fix(ci): say that CI runs Node 20 while production runs 24, and ignore build output`) and in
`ci.yml`'s comments — it documented the gap rather than closing it, which was the right scope call
for that PR.
The consequence is the one worth naming: **the Node version that serves players is not the version
the suite runs against.** A Node-24-only behaviour difference — or a Node-20-only one — is invisible
to CI in both directions. pnpm 11 is simply the first dependency to force the question.
Node 20 is also now deprecated on GitHub Actions runners; every run already logs:
> Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on
> Node.js 24: actions/checkout@v4, actions/setup-node@v4, pnpm/action-setup@v4
## Suggested fix
Move CI to **Node 24**, matching production, rather than to the 22.13 minimum pnpm 11 happens to
need. Aligning with what actually serves players is the reason to do it; satisfying pnpm is a
side effect.
Concretely: `.nvmrc` → `24`, and the `node-version` fallback in `.github/workflows/ci.yml` to match
(#248 adds both and deliberately keeps them in sync — keep that property).
**Sequencing.** This has to land **after** #248 (which introduces `.nvmrc`) and **before or with**
#89. Doing it inside #89 would bundle a CI policy change into a dependency bump, which is why it is
filed separately.
**What this does NOT fix:** it does not make pnpm 11 desirable on its own merits — #89 also re-resolves
the whole lockfile (vitest 4.1.0 → 4.1.10, jsdom 29.0.0 → 29.1.1, vite 8.1.5 → 8.2.1 all move with it),
and that is a separate thing to review on its own.
## Non-goals
Not changing the Vercel build's Node version — it is already 24. Not bumping pnpm here; that stays
#89's job.
## Depends on / blocks
- **Depends on #248** (introduces `.nvmrc`).
- **Blocks #89** — that PR cannot go green until this lands.
## Open question
Whether to go to 24 (matches production, closes the gap) or to 22 (smallest step that unblocks pnpm
11). Recommending 24, because a CI/production version gap is the actual defect here and 22 leaves it
open while feeling like progress. Left explicit so whoever picks it up makes the call deliberately.
## Acceptance criteria
- [ ] `.nvmrc` and the `ci.yml` fallback both name the same version, and it matches production
- [ ] CI demonstrably runs on that version — read it out of a run log, not out of the config
- [ ] #89 goes green on a rebase with no further changes, proving the diagnosis
- [ ] The Node 20 deprecation warnings stop appearing in run logs
- [ ] If 22 is chosen over 24, the remaining CI/production gap is written down and owned
## How we'd know it's fixed
A run log shows the intended Node version, the deprecation warning is gone, and #89 turns green
without touching its own contents. Verified at `cfa135f`.
Contributor guide
Assessment
This issue has not been assessed yet.