Skip to content

[all components] Drop React 17 support - #24084

Draft
LukasTy wants to merge 3 commits into
mui:masterfrom
LukasTy:drop-react-17
Draft

LukasTy wants to merge 3 commits into
mui:masterfrom
LukasTy:drop-react-17

Conversation

@LukasTy

@LukasTy LukasTy commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Drop React 17 support in v10. React 18 is the new minimum. This PR is for discussion: master still ships v9, so it stays a draft until v10 starts. v9 stays the line for React 17 users.

Closes #17637. Follow-up to #24038, which fixed six React 17 crashes in v9.17.0.

Why

  • CI tests only React 18 and 19. The unit suite cannot run on React 17: all test files fail at import.
  • React 17 is about 1.6% of the weekly react downloads.
  • All axis charts crashed on React 17 from v9.6.0 for 4 months. Nobody reported it.

Wins

  • Diff: 121 files changed, 272 insertions, 433 deletions (net -161 lines). Without pnpm-lock.yaml and whitespace: 208 insertions, 325 deletions.
  • Dependencies: use-sync-external-store removed from 4 packages (x-charts, x-chat-headless, x-data-grid, x-scheduler-internals). @types/use-sync-external-store removed from 7 packages. 2 catalog entries removed. The lockfile loses 46 lines.
  • Shim: 5 use-sync-external-store/shim imports (4 imports and 1 re-export from @mui/x-data-grid/internals) and 6 hook calls now use React.useSyncExternalStore.
  • useId: 98 calls in 71 files now use React.useId() instead of the @mui/utils/useId and @base-ui/utils/useId wrappers. 71 wrapper imports removed. The IDs do not change: on React 18+, both wrappers return React.useId() as is.
  • React 17 first-render guards: 24 removed. That is 2 runtime guards (ScatterPlot progressive plan, GridActionsCell menu button), 8 string | undefined types, 13 ! assertions and 1 ?? '' fallback.
  • PropTypes: 2 props of GridHeaderFilterMenu are required again (revert of [DataGridPro] Avoid proptypes warnings with header filters in React 17 #17482).
  • ESLint: the React 17 guard from [charts][chat][DataGridPremium][scheduler] Fix React 17 crashes #24038 (12 restricted React.* properties) becomes a React 18 guard (6 properties: use, useActionState, useOptimistic, useEffectEvent, Activity, cache).
  • Tests: 3 reactMajor < 18 skips, 3 dynamic import('react-dom/client') calls and their comments removed from the SSR tests.
  • Comments: 4 React 17 comments removed.
  • CI: no React 17 job exists, so there is nothing to remove.
  • Bundle size (CI report, gzip): 12 of 14 bundles get smaller, by 6 B to 109 B. The largest relative gain is @mui/x-tree-view (-73 B, -0.33%). @mui/x-date-pickers grows by 3 B and @mui/x-license does not change. The gain is small because the shim stays in the bundles: @base-ui/utils/store (useStore) imports it.

What stays

  • @base-ui/utils and @base-ui/react keep their React 17 fallbacks (for example useGlobalId in useId and SafeReact) and their use-sync-external-store dependency, because Base UI 1.x supports React 17. 17 MUI X packages depend on @base-ui/utils, so the shim stays in the install tree and in the bundles.
  • 3 useId(idProp) calls keep the wrapper because it merges the id prop (PickersTextField, CalendarGridRoot, EventTimelinePremiumEvent).
  • The React 18 fallbacks for React 19 APIs stay: isReactVersionAtLeast(19) (5 places), the SafeReact read of the React internals in useDisposable, and the reactMajor < 19 and 'Activity' in React test branches.
  • The @mui/material and @mui/system peer ranges do not change in this PR.

Changelog

Breaking changes

  • The minimum supported version of React is now 18. Upgrade react and react-dom to v18 or v19 before you upgrade to MUI X v10. React 17 users can stay on MUI X v9.

Generated with Claude Code

LukasTy and others added 3 commits November 2, 2026 15:47
- Remove `^17.0.0` from the `react` and `react-dom` peer ranges.
- Use `React.useSyncExternalStore` and remove the `use-sync-external-store` dependency.
- Replace the React 17 ESLint guard with a smaller React 18 guard.
- Remove the React 17 skips and dynamic imports from the SSR tests.
- Update the peer ranges in the quickstart docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… React 17" (mui#17482)

This reverts commit 124bfdd.
`useId()` returns a string on the first render in React 18 and later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Replace the no-argument `@mui/utils/useId` and `@base-ui/utils/useId` calls with `React.useId()`.
- Remove the `| undefined` types, `!` assertions and guards that only exist for the React 17 first render.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LukasTy LukasTy added breaking change Introduces changes that are not backward compatible. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. scope: all components Widespread work has an impact on almost all components. integration: react About improving React support. labels Nov 2, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid ▼-17B(0.00%) ▼-70B(-0.05%)
@mui/x-data-grid-pro ▼-17B(0.00%) ▼-109B(-0.06%)
@mui/x-data-grid-premium 🔺+118B(+0.02%) ▼-72B(-0.03%)
@mui/x-charts ▼-171B(-0.04%) ▼-63B(-0.05%)
@mui/x-charts-pro ▼-149B(-0.03%) ▼-64B(-0.04%)
@mui/x-charts-premium ▼-133B(-0.02%) ▼-91B(-0.05%)
@mui/x-date-pickers 🔺+11B(+0.01%) 🔺+3B(+0.01%)
@mui/x-date-pickers-pro 🔺+5B(0.00%) ▼-6B(-0.01%)
@mui/x-tree-view ▼-191B(-0.25%) ▼-73B(-0.33%)
@mui/x-tree-view-pro ▼-200B(-0.14%) ▼-95B(-0.22%)
@mui/x-scheduler ▼-177B(-0.04%) ▼-109B(-0.09%)
@mui/x-scheduler-premium ▼-172B(-0.03%) ▼-100B(-0.06%)
@mui/x-chat ▼-204B(-0.06%) ▼-84B(-0.09%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

Total duration: 1,674.05 ms +210.82 ms(+14.4%) | Renders: 63 (+0) | Paint: 2,328.73 ms +314.24 ms(+15.6%)

Test Duration Renders
SparkLineChart grid of 100 instances 228.24 ms 🔺+127.37 ms(+126.3%) 1 (+0)
BarChart stacked with multiple series 82.97 ms 🔺+17.70 ms(+27.1%) 2 (+0)
BarChartPro with big data amount 42.82 ms 🔺+12.01 ms(+39.0%) 2 (+0)
RadialLineChart with big data amount 52.40 ms 🔺+9.65 ms(+22.6%) 2 (+0)
HeatmapPremium: 100x100 grid (webgl renderer) 27.27 ms 🔺+5.41 ms(+24.7%) 5 (+0)

…and 9 more (+12 within noise) — details

Metric alarms

Test Metric Change
SparkLineChart grid of 100 instances bench:paint 🔺 +198.23 ms
BarChart stacked with multiple series bench:paint 🔺 +22.32 ms
HeatmapPremium: 100x100 grid (webgl renderer) bench:paint 🔺 +5.81 ms
PieChart with big data amount bench:paint 🔺 +3.88 ms
ScatterChartPro with big data amount and zoomed in (batch renderer) bench:paint 🔺 +2.93 ms

…and 3 more metric alarms — details


Check out the code infra dashboard for more information about this PR.

This branch has not been deployed

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

Labels

breaking change Introduces changes that are not backward compatible. integration: react About improving React support. scope: all components Widespread work has an impact on almost all components. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. v10.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[all components] Drop React 17 support

1 participant