Skip to content

[BREAKINGCHANGE] Add support for React 19+ - #390

Merged
Gladorme merged 5 commits into
perses:mainfrom
Gladorme:agents/react-compiler-support-18-19
Oct 28, 2026
Merged

Gladorme merged 5 commits into
perses:mainfrom
Gladorme:agents/react-compiler-support-18-19

Conversation

@Gladorme

@Gladorme Gladorme commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Description

Starting to add support for React 19+, while still keeping React 18 as base.
Related to perses/perses#4578

Done by IA (Opus 5.5)

Breaking change

  • In order to support React 19+, use-resize-observer must be upgrade to v10 in plugin (if used).

  • Added @mui/system peer dependency of @perses-dev/components.

  • Remote plugins must consume both react and react/jsx-runtime as shared singletons from the host. Rebuild plugins with react/jsx-runtime in their Module Federation shared configuration before using them on a React 19 host: a bundled React 18 JSX runtime cannot run against the host's React 19 instance.

Screenshots

Checklist

  • Pull request has a descriptive title and context useful to a reviewer.
  • Pull request title follows the [<catalog_entry>] <commit message> naming convention using one of the
    following catalog_entry values: FEATURE, ENHANCEMENT, BUGFIX, BREAKINGCHANGE, DOC,IGNORE.
  • All commits have DCO signoffs.

UI Changes

  • Changes that impact the UI include screenshots and/or screencasts of the relevant changes.
  • Code follows the UI guidelines.
  • E2E tests are stable and unlikely to be flaky.
    See e2e docs for more details. Common issues include:
    • Is the data inconsistent? You need to mock API requests.
    • Does the time change? You need to use consistent time values or mock time utilities.
    • Does it have loading states? You need to wait for loading to complete.

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
@Gladorme
Gladorme requested a review from a team as a code owner October 22, 2026 12:20
@Gladorme
Gladorme marked this pull request as draft October 22, 2026 12:20
Comment thread plugin-system/src/remote/PluginRuntime.tsx Outdated
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
@Gladorme Gladorme changed the title [ENHANCEMENT] Add support for React 19+ [BREAKINGCHANGE] Add support for React 19+ Oct 22, 2026
@Gladorme
Gladorme marked this pull request as ready for review October 22, 2026 14:50

@Nexucis Nexucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI looks good, and the React 19 job really does run against React 19: the --no-save install changes 6 packages, and Turbo reports 0 cached tasks.

Read together with perses/plugins#889, the use-resize-observer v10 move is fine as a coordinated breaking change. Both PRs should be released together, and Perses should update its bundled plugins in the same release. Plugins built against v9 use the default import, so they get undefined from the shared v10 singleton.

Main point: plugins built with React 18 can't run on a React 19 host yet. After perses/plugins#889, plugins are still built with React 18.3.1. Each one bundles its own react/jsx-runtime, which resolves react to the host's shared singleton. React 18's runtime reads React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner as soon as it loads, and React 19 doesn't have it. I reproduced this in Node with React 18.3.1's production jsx-runtime against React 19:

Cannot read properties of undefined (reading 'ReactCurrentOwner')

React 18 hosts aren't affected, so this isn't a regression. But for remote plugins, React 19 support only covers type-checks and tests until the host shares react/jsx-runtime (see inline comment) and plugins consume it (perses/plugins#889).

react-compiler-runtime works on React 19; I checked that too.

Comment thread plugin-system/src/remote/PluginRuntime.tsx
Comment thread plugin-system/src/remote/PluginRuntime.tsx
Comment thread components/src/Dialog/Dialog.tsx
Comment thread explore/package.json Outdated
- Share the host's react/jsx-runtime with plugins, so plugins built with React 18 can run on a React 19 host.
- Type Dialog.Form with @mui/material types instead of the undeclared @mui/system.
- Remove the unused use-resize-observer dependency from explore.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
Comment thread components/src/Dialog/Dialog.tsx Outdated
Signed-off-by: Guillaume LADORME <gladorme@users.noreply.github.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 27, 2026
Perses 0.55 still requires React 18; its React 19 support is
perses/shared#390, open as of 2026-10-27. router.ts and docs/connect.md
say the router setting goes once that ships and the console moves.

Signed-off-by: Juntao Wang <juntwang@redhat.com>

@Nexucis Nexucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at ecaeb32d. Thanks for the updates!

Addressed

  • react/jsx-runtime is now shared from the host, with a test. The README also documents the plugin migration.
  • Declaring @mui/system fixes a real mismatch, not just a nit. On main, the hoisted @mui/system was 7.3.11 while @mui/material used 6.5.0, so import type { MUIStyledCommonProps } from '@mui/system' resolved to the v7 types. It now dedupes to 6.5.0. Note that this adds a new peer dependency to @perses-dev/components. It's harmless with npm, because @mui/material already depends on it, but it's worth mentioning in the breaking-change notes.
  • explore no longer has the unused use-resize-observer dependency.

React 19 checks

  • The React 19 CI job passes 1,418 tests with no React deprecation warnings.
  • No removed or legacy APIs remain in the source: no global JSX namespace, no argument-less useRef(), no element.ref, no findDOMNode, react-dom/test-utils, propTypes, legacy context, or defaultProps on function components. forwardRef is still used, which is fine while React 18 is the minimum.
  • Re-render check: v10 memoizes its ref callback and its return value, and keeps onResize in a ref, so it adds no re-renders compared to v9. The test helpers and mocks are defined at module level, and Panel's contentDimensions memo uses primitive dependencies.

One behavior change to handle (inline comment): v10 reports a measured 0 as 0, while v9 reported undefined. This leaks into the public PanelProps.contentDimensions contract.

Cross-PR: perses/plugins#889 doesn't declare react/jsx-runtime as shared yet. React 18 hosts are fine, but React 19 hosts still need it, as the new README says.

Comment thread dashboards/src/components/Panel/Panel.tsx
use-resize-observer v10 reports a measured 0 instead of undefined, which
made Panel pass {width: 0, height: 0} contentDimensions to plugins. Keep
the v9 contract by mapping falsy sizes to undefined.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

@Nexucis Nexucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM at 93244a6a. The zero-size fix keeps the PanelProps.contentDimensions contract, and the new test checks it: with the old guard, the 0×0 and 120×0 cases fail, and with the fix all 17 Panel tests pass. CI is green, including the React 19 job.

Non-blocking follow-ups:

  • Please also mention the new @mui/system peer dependency of @perses-dev/components in the PR's Breaking change section, plus the requirement for plugins to share react/jsx-runtime (already documented in the README).
  • perses/plugins#889 still needs 'react/jsx-runtime' in each plugin's Module Federation shared config before plugins can run on a React 19 host. Please release it together with this PR.

@Gladorme
Gladorme merged commit 2911b40 into perses:main Oct 28, 2026
14 checks passed
Gladorme added a commit to Gladorme/plugins that referenced this pull request Oct 28, 2026
Bump @perses-dev/{client,components,dashboards,explore,plugin-system} to
^0.56.0-beta.0 and apply the breaking changes from perses/shared#390 and
perses/shared#391:

- Share react/jsx-runtime as a singleton in every plugin's Module
  Federation config so plugins use the host's JSX runtime on React 19.
- Upgrade @tanstack/react-table to ^9.2.8 in the table and flamechart
  plugins to match @perses-dev/components, and use concrete row types
  instead of `unknown` for TableColumnConfig.
- Use CellContext<TableFeatures, ...> in the piechart legend test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
Gladorme added a commit to Gladorme/perses that referenced this pull request Oct 28, 2026
Bump @perses-dev shared packages to 0.56.0-beta.0 and the default plugins to
their 0.56.0-beta.0-based releases, and move the UI to React 19.

- Adapt to perses/shared#390: use-resize-observer v10 (drop the polyfilled
  alias), add the @mui/system peer dependency, and replace the removed global
  JSX namespace with ReactElement.
- Switch the React Compiler target to 19 and drop react-compiler-runtime.
- Upgrade react-social-login-buttons to v4 (React 19 support).
- Share react/jsx-runtime in the generated plugin template.
- Pin the embedded examples to the 0.56.0-beta.0 packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
perses/shared#390 and perses/plugins#889 merged on 2026-10-28 and ship in
0.56.0-beta.0, so the router setting's exit is React 19 with Perses 0.56 or
later. The notes said the support was still open.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
The console declares the peers its Perses packages require (echarts,
immer, lodash, date-fns, @hookform/resolvers and so on) rather than leaving
them to pnpm's autoInstallPeers. Three were still implicit:

- @mui/system 6.5.0, a new peer of @perses-dev/components 0.56
  (perses/shared#390), at @mui/material's exact version;
- @perses-dev/explore 0.56.0-beta.0, a peer of the Prometheus and Loki
  plugins (already in the minimum-release-age exclusions);
- @tanstack/react-table 9.3.1, a peer of the table plugin.

Each is pinned to the version pnpm already resolved, so the lockfile
resolution doesn't change; pnpm still reports no peer issues.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
… support

Perses supports React 19 from 0.56 (perses/shared#390 and
perses/plugins#889, merged 2026-10-28); 0.56.0-beta.0 and a beta of each
plugin the console bundles are the first releases with it. They are
pinned exactly: @perses-dev/client, components, dashboards and
plugin-system 0.56.0-beta.0, gauge 0.15.0-beta.0, loki 0.8.0-beta.0,
markdown 0.14.0-beta.0, pie 0.16.0-beta.0, prometheus 0.60.0-beta.0,
stat 0.16.0-beta.0, table 0.15.0-beta.0 and timeseries 0.15.0-beta.0.
They are newer than pnpm's minimum release age, so pnpm-workspace.yaml
excludes them from it until 0.56.0 is released.

The peers only Perses needs move with it: @hookform/resolvers 3.9.1 ->
5.9.2 (the plugins want ^5.9.1), use-resize-observer 9.1.0 -> 10.0.0
(9 declares React up to 18) and @perses-dev/spec 0.2.0 -> 0.3.0. pnpm now
reports no peer dependency issues. Perses's own zod is now zod 4, the
console's copy.

- The pie chart patch goes: 0.16.0-beta.0 imports `format` from
  'echarts/core' itself (perses/plugins#893). The Dockerfile no longer
  copies the patches folder.
- buildProxyUrl takes Perses's BuildDatasourceProxyUrlParams, whose name
  is optional in 0.56: without one, Perses asks for its unsaved-datasource
  proxy (testing a datasource before saving it), which the relay doesn't
  serve, so it throws like a dashboard's own datasource does.
- Vitest inlines @perses-dev/*: 0.56 is "type": "module" and imports
  mdi-material-ui/<Icon> without an extension, which Node's ES module
  resolver refuses.
- The dev server aliases those imports to mdi-material-ui/esm/<Icon>.
  The icons are CommonJS files and mdi-material-ui has no "exports" map;
  esbuild's dependency pre-bundling follows Node's rules for an ES module
  importing CommonJS, so the default import is the whole module.exports
  and the Monitoring page fails to render ("Element type is invalid").
  The production build (Rollup) honours __esModule and doesn't need it.

Perses 0.56 still declares Query v4, so the override stays, and so do the
v4 names docs/connect.md lists. The Monitoring chunk grows from about
1,024 kB to 1,178 kB gzipped; a later commit looks into why.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
The console declares the peers its Perses packages require (echarts,
immer, lodash, date-fns, @hookform/resolvers and so on) rather than leaving
them to pnpm's autoInstallPeers. Three were still implicit:

- @mui/system 6.5.0, a new peer of @perses-dev/components 0.56
  (perses/shared#390), at @mui/material's exact version;
- @perses-dev/explore 0.56.0-beta.0, a peer of the Prometheus and Loki
  plugins (already in the minimum-release-age exclusions);
- @tanstack/react-table 9.3.1, a peer of the table plugin.

Each is pinned to the version pnpm already resolved, so the lockfile
resolution doesn't change; pnpm still reports no peer issues.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
… support

Perses supports React 19 from 0.56 (perses/shared#390 and
perses/plugins#889, merged 2026-10-28); 0.56.0-beta.0 and a beta of each
plugin the console bundles are the first releases with it. They are
pinned exactly: @perses-dev/client, components, dashboards and
plugin-system 0.56.0-beta.0, gauge 0.15.0-beta.0, loki 0.8.0-beta.0,
markdown 0.14.0-beta.0, pie 0.16.0-beta.0, prometheus 0.60.0-beta.0,
stat 0.16.0-beta.0, table 0.15.0-beta.0 and timeseries 0.15.0-beta.0.
They are newer than pnpm's minimum release age, so pnpm-workspace.yaml
excludes them from it until 0.56.0 is released.

The peers only Perses needs move with it: @hookform/resolvers 3.9.1 ->
5.9.2 (the plugins want ^5.9.1), use-resize-observer 9.1.0 -> 10.0.0
(9 declares React up to 18) and @perses-dev/spec 0.2.0 -> 0.3.0. pnpm now
reports no peer dependency issues. Perses's own zod is now zod 4, the
console's copy.

- The pie chart patch goes: 0.16.0-beta.0 imports `format` from
  'echarts/core' itself (perses/plugins#893). The Dockerfile no longer
  copies the patches folder.
- buildProxyUrl takes Perses's BuildDatasourceProxyUrlParams, whose name
  is optional in 0.56: without one, Perses asks for its unsaved-datasource
  proxy (testing a datasource before saving it), which the relay doesn't
  serve, so it throws like a dashboard's own datasource does.
- Vitest inlines @perses-dev/*: 0.56 is "type": "module" and imports
  mdi-material-ui/<Icon> without an extension, which Node's ES module
  resolver refuses.
- The dev server aliases those imports to mdi-material-ui/esm/<Icon>.
  The icons are CommonJS files and mdi-material-ui has no "exports" map;
  esbuild's dependency pre-bundling follows Node's rules for an ES module
  importing CommonJS, so the default import is the whole module.exports
  and the Monitoring page fails to render ("Element type is invalid").
  The production build (Rollup) honours __esModule and doesn't need it.

Perses 0.56 still declares Query v4, so the override stays, and so do the
v4 names docs/connect.md lists. The Monitoring chunk grows from about
1,024 kB to 1,178 kB gzipped; a later commit looks into why.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
DaoDaoNoCode added a commit to DaoDaoNoCode/ai-grid-provider-console that referenced this pull request Oct 28, 2026
The console declares the peers its Perses packages require (echarts,
immer, lodash, date-fns, @hookform/resolvers and so on) rather than leaving
them to pnpm's autoInstallPeers. Three were still implicit:

- @mui/system 6.5.0, a new peer of @perses-dev/components 0.56
  (perses/shared#390), at @mui/material's exact version;
- @perses-dev/explore 0.56.0-beta.0, a peer of the Prometheus and Loki
  plugins (already in the minimum-release-age exclusions);
- @tanstack/react-table 9.3.1, a peer of the table plugin.

Each is pinned to the version pnpm already resolved, so the lockfile
resolution doesn't change; pnpm still reports no peer issues.

Signed-off-by: Juntao Wang <juntwang@redhat.com>
piotaixr pushed a commit to piotaixr/perses that referenced this pull request Oct 28, 2026
…perses#4630)

* [ENHANCEMENT] Add support for React 19+

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Update doc

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [ENHANCEMENT] Run the Perses UI on React 19

Bump @perses-dev shared packages to 0.56.0-beta.0 and the default plugins to
their 0.56.0-beta.0-based releases, and move the UI to React 19.

- Adapt to perses/shared#390: use-resize-observer v10 (drop the polyfilled
  alias), add the @mui/system peer dependency, and replace the removed global
  JSX namespace with ReactElement.
- Switch the React Compiler target to 19 and drop react-compiler-runtime.
- Upgrade react-social-login-buttons to v4 (React 19 support).
- Share react/jsx-runtime in the generated plugin template.
- Pin the embedded examples to the 0.56.0-beta.0 packages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [ENHANCEMENT] Address React 19 review feedback

- Compile JSX with the production runtime in the plugin template dev mode, so
  `percli plugin start` uses the host's shared `react/jsx-runtime` instead of
  bundling React 18's `jsx-dev-runtime`, and document it in the upgrade guide.
- Pin the beta Perses packages in the embedding documentation install command.
- Add a release step to replace prerelease dependency pins before v0.56.0.
- Run the examples in a dedicated workflow, only when they change and weekly.
- Use the built-in `GitlabLoginButton` of react-social-login-buttons v4.
- Add `@mui/system` to the embedded examples.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [ENHANCEMENT] Run the examples when a package.json changes

Run the examples on every `package.json` change to check that dependency
upgrades keep React 18 and React 19 compatibility, and drop the weekly run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [ENHANCEMENT] Move the examples back to the react workflow

Always run the examples with the other React checks, so dependency upgrades
are checked against React 18 and React 19 on every pull request.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [IGNORE] Remove trailing blank line in react workflow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* [ENHANCEMENT] Bump @perses-dev/spec to ^0.3.0 in the plugin template

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

---------

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gladorme added a commit to Gladorme/plugins that referenced this pull request Oct 28, 2026
* [ENHANCEMENT] Add support for React 19+

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Remove use-resize-observer v9

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Upgrade perses shared libs to v0.56.0-beta.0

Bump @perses-dev/{client,components,dashboards,explore,plugin-system} to
^0.56.0-beta.0 and apply the breaking changes from perses/shared#390 and
perses/shared#391:

- Share react/jsx-runtime as a singleton in every plugin's Module
  Federation config so plugins use the host's JSX runtime on React 19.
- Upgrade @tanstack/react-table to ^9.2.8 in the table and flamechart
  plugins to match @perses-dev/components, and use concrete row types
  instead of `unknown` for TableColumnConfig.
- Use CellContext<TableFeatures, ...> in the piechart legend test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Apply Nexucis review comments

- Compile plugin JSX with the production `react/jsx-runtime` even in dev
  mode, so dev builds consume the host's shared JSX runtime instead of
  bundling React 18's `react/jsx-dev-runtime` (broken on a React 19 host).
- Align the json plugin's README and react/react-dom peer range with the
  other plugins (React 18 or 19).
- Assert the React 19 CI job actually installed React 19.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Use React 18 as default in plugin READMEs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Require React 18.3+ in Module Federation shared config

Align the react, react/jsx-runtime and react-dom requiredVersion ranges with the ^18.3.0 || ^19.0.0 peer dependency range.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

* Update versions in README snapshot example

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>

---------

Signed-off-by: Guillaume LADORME <Gladorme@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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