Skip to content

fix: align react peerDependencies across react-components packages - #36551

Open
Martin Hochel (Hotell) wants to merge 2 commits into
microsoft:masterfrom
Hotell:fix/normalize-react-peer-dependencies
Open

fix: align react peerDependencies across react-components packages#36551
Martin Hochel (Hotell) wants to merge 2 commits into
microsoft:masterfrom
Hotell:fix/normalize-react-peer-dependencies

Conversation

@Hotell

Copy link
Copy Markdown
Contributor

Previous Behavior

Peer dependency ranges for react, react-dom, @types/react and @types/react-dom had drifted into 5 different signatures across publishable packages/react-components/** packages, 12 of which were internally incoherent:

Count react react-dom @types/react @types/react-dom
58 >=16.14.0 >=16.14.0 >=16.14.0 >=16.9.0 ✅ canonical
5 >=16.14.0 >=16.14.0 ✅ non-DOM packages
7 >=16.14.0 >=16.8.0 >=16.8.0 >=16.8.0
2 >=16.8.0 >=16.14.0 >=16.14.0 >=16.9.0
3 >=16.8.0 >=16.8.0 >=16.8.0 >=16.8.0 ❌ transitively unsatisfiable

Every v9 package depends on @fluentui/react-jsx-runtime, which does a hard module import of react/jsx-runtime:

// packages/react-components/react-jsx-runtime/src/utils/Runtime.ts
import * as ReactRuntime from 'react/jsx-runtime';

That entry point was only backported to the 16.x line in react@16.14.0 — verified by unpacking both tarballs:

react@16.13.1 -> 0 jsx-runtime files
react@16.14.0 -> package/jsx-runtime.js
                 package/cjs/react-jsx-runtime.development.js
                 package/cjs/react-jsx-runtime.production.min.js

So react >=16.14.0 is a hard floor. Any package advertising >=16.8.0 lets a consumer on React 16.8–16.13 install cleanly and then fail to resolve react/jsx-runtime at build/runtime.

How the skew happened

  1. 400cd5a243 — a bad release run wrote the package's own version into peers: "react": "^8.119.0", across ~97 package.json files.
  2. fix: revert incorectly set react versions in all packages #31937 (4edb54ea6e) reverted it — but restored only the react key, hand-assigning >=16.14.0 to 63 entries and >=16.8.0 to the rest. react-dom, @types/react and @types/react-dom were left untouched at whatever they had. This is the origin of the mismatch.
  3. chore: extend packages peer dependencies versions to support React 19 #35145 (eb7f6d51c2) added React 19 support via a mechanical <19.0.0<20.0.0 sweep. It preserved lower bounds verbatim, freezing the skew in place — and it never touched tools/, leaving the generator template stale.

New Behavior

All publishable packages/react-components/** packages collapse to one signature:

"@types/react":     ">=16.14.0 <20.0.0",
"@types/react-dom": ">=16.9.0 <20.0.0",
"react":            ">=16.14.0 <20.0.0",
"react-dom":        ">=16.14.0 <20.0.0"

@types/react-dom intentionally stays at >=16.9.0: no 16.14.x was ever published for it (16.x ends at 16.9.25), which is exactly what #30259 fixed. Every other package keeps >=16.14.0.

12 packages normalized: react-infolabel, react-list, react-message-bar, react-motion, react-rating, react-swatch-picker, react-teaching-popover, react-datepicker-compat, react-migration-v8-v9, react-calendar-compat, react-icons-compat, react-timepicker-compat

The 5 non-DOM packages (react-utilities, react-jsx-runtime, react-shared-contexts, react-portal-compat, react-portal-compat-context) correctly declare no react-dom peer and were already canonical — untouched.

Generator template fixed: tools/workspace-plugin/src/generators/react-library/files/package.json__tmpl__ still emitted <19.0.0, so every package scaffolded since #35145 started life with a stale upper bound.

This is metadata-only — no source, build output or runtime behavior changes. It narrows an advertised range that was never actually supported, so no consumer on a working configuration is affected.

Validation

  • beachball check → clean (12 patch change files, one per changed package)
  • nx run workspace-plugin:test --testPathPatterns=react-library → 3 tests, 10 snapshots passed
  • prettier --check → clean

Follow-up (not in this PR)

Nothing prevents this from drifting again — normalize-package-dependencies only validates internal workspace deps and deliberately skips external peers. A coherence check for the four react peers would make this regression-proof. Happy to add it here or in a separate PR.

Related Issue(s)

All v9 packages depend on `@fluentui/react-jsx-runtime`, which imports
`react/jsx-runtime` directly. That entry point was only backported to the
16.x line in react@16.14.0 (react@16.13.1 ships no jsx-runtime files), so
`react >=16.14.0` is a hard floor.

12 packages advertised a `>=16.8.0` lower bound on some subset of
react/react-dom/@types/react/@types/react-dom, which is unsatisfiable in
practice. The skew originated in microsoft#31937, which reverted a bad release that
wrote `"react": "^8.119.0"` into peerDependencies but only restored the
`react` key, leaving the other three behind. microsoft#35145 then swept
`<19.0.0` -> `<20.0.0` while preserving the existing lower bounds, freezing
the skew in place.

All publishable `packages/react-components/**` packages now use:

    "@types/react": ">=16.14.0 <20.0.0"
    "@types/react-dom": ">=16.9.0 <20.0.0"
    "react": ">=16.14.0 <20.0.0"
    "react-dom": ">=16.14.0 <20.0.0"

`@types/react-dom` stays at `>=16.9.0` because no 16.14.x was ever
published for it (16.x ends at 16.9.25) - see microsoft#30259.

Also updates the `react-library` generator template, which still emitted
`<19.0.0` because microsoft#35145 did not touch `tools/`, so every newly scaffolded
package started life with a stale upper bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yarn records workspace peerDependencies in the lockfile, so changing them
in package.json makes yarn.lock stale and `yarn install --immutable` fails
with YN0028 in CI.

Regenerated via `yarn install --mode=update-lockfile`. The diff is 35 lines,
all of them react/react-dom/@types peer ranges on the 12 realigned workspace
entries - no resolution, version or checksum changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

📊 Bundle size report

✅ No changes found

@github-actions

Copy link
Copy Markdown

Pull request demo site: URL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant