Skip to content

react-dom's exact pin outlived its reason — revert it to a caret now that the Dependabot group exists #238

Description

@os-zhuang

Filed by the repo:objectos seat (objectstack#9831) at the ACCEPT of PR #236 (#159), from a measurement that PR's dev took and correctly declined to act on. Graded pm:queue here — first touch by this seat, per the single-lane self-service rule.

The state on origin/main @ 58126d4

apps/docs/package.json declares the two halves of a peer-coupled pair in different shapes:

"react":     "^19.2.7",   // floats
"react-dom": "19.2.7",    // pinned exact

The pin was introduced by #158 as a deliberate, bounded workaround: react-dom@X peer-requires react@^X, react was out of that card's scope, and a caret on react-dom resolved upward to 19.2.8 and broke the peer check. Pinning was the right call for that card.

PR #236 removed the reason it exists. .github/dependabot.yml now groups react and react-dom, so they arrive as one PR and move together — which is what the pin was standing in for.

Why it is worth closing rather than leaving

The asymmetry has a failure mode that is silent at install time, described on #159 and still live:

a future non-frozen install can float react upward while react-dom stays put. The peer range ^19.2.7 permits that, so no tool complains — while React itself expects the two to be the same version.

Both resolve to 19.2.7 today, so nothing is broken now. The hazard is that the mismatch reads as intentional, and the thing that would catch it does not fire.

Leaving both the group and the pin is belt-and-braces: not wrong, but it hides which mechanism is load-bearing, and the next person to touch this pair has to re-derive that.

The change, already measured — do not re-derive it

PR #236's dev ran the experiment and restored the tree afterwards (verified byte-identical by sha256). The result:

$ sed -i 's/"react-dom": "19.2.7"/"react-dom": "^19.2.7"/' apps/docs/package.json
$ pnpm install --lockfile-only
$ diff pnpm-lock.yaml.before pnpm-lock.yaml
39c39
<         specifier: 19.2.7
---
>         specifier: ^19.2.7

The resolved version: does not move — it stays 19.2.7(react@19.2.7). Only the specifier: field changes. So this is a two-line change: one in apps/docs/package.json, one in pnpm-lock.yaml.

⚠️ Why it was not folded into PR #236, and what that means for whoever takes this

deploy-docs.yml fires a production deploy on every pnpm-lock.yaml push to main. That is the whole reason this is a separate card: a change that reads as cosmetic would have shipped a production docs deploy riding on a Dependabot-config PR, where no reviewer would be looking for one.

That blast radius does not go away here — it is just made visible and deliberate. Whoever takes this should say plainly in the PR body that merging it triggers a production deploy, so the person merging knows. That is the cost, and it is acceptable as a stated cost, not as a surprise.

Alternative, if someone disagrees

Keep the pin and treat the group as the mechanism, accepting the asymmetric declaration as documented-by-this-card rather than corrected. If that is chosen, close this card with the reasoning rather than leaving it open — a permanently-open hygiene card is worse than a ruled one.

Re-check

git show origin/main:apps/docs/package.json | grep -E '"react(-dom)?"'
git show origin/main:.github/dependabot.yml | grep -A3 'react:'

Related: #159 (the grouping card), #158 / PR #158 (where the pin came from), PR #236 (where this was measured).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions