Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/element/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

## 8.3.0 (2026-07-14)

### Breaking Changes

- Move `react` and `react-dom` from `dependencies` to `peerDependencies`. Consumers must now provide `react` and `react-dom` themselves. `@types/react` and `@types/react-dom` become optional peer dependencies ([#80053](https://github.com/WordPress/gutenberg/pull/80053)).

## 8.2.0 (2026-07-01)

## 8.1.0 (2026-06-24)
Expand Down
20 changes: 15 additions & 5 deletions packages/element/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,29 @@
"types": "build-types",
"sideEffects": false,
"dependencies": {
"@types/react": "^18.3.27",
"@types/react-dom": "^18.3.1",
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/escape-html": "file:../escape-html",
"change-case": "^4.1.2",
"is-plain-object": "^5.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
Comment thread
SirLouen marked this conversation as resolved.
Resolved
"is-plain-object": "^5.0.0"
},
"devDependencies": {
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2"
},
"peerDependencies": {
"@types/react": "^18 || ^19",
"@types/react-dom": "^18 || ^19",
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
},
"publishConfig": {
"access": "public"
}
Expand Down
10 changes: 6 additions & 4 deletions packages/element/src/react-platform.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/**
* External dependencies
*/
import {
import * as ReactDOM from 'react-dom';
import { createRoot, hydrateRoot } from 'react-dom/client';

const {
createPortal,
findDOMNode,
flushSync,
/* eslint-disable react/no-deprecated */
findDOMNode,
render,
hydrate,
unmountComponentAtNode,
/* eslint-enable react/no-deprecated */
} from 'react-dom';
import { createRoot, hydrateRoot } from 'react-dom/client';
} = ReactDOM;

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.

Why do we need to reorganize this import?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's not a cosmetic reorganization.

React 19 removed findDOMNode, render, hydrate, and unmountComponentAtNode from react-dom.

With static named imports, those bindings must be resolvable at module link time. When a consumer loads @wordpress/element in a R19 app, the ESM loader tries to bind names that no longer exist on react-dom and throws for example:

SyntaxError: The requested module 'react-dom' does not provide an export named 'render'

Solution: A namespace import like this.

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.

Thanks, that makes sense. import { render } throws, but accessing a property of the namespace object (ReactDOM.render) just returns undefined.

Which ESM runtime does throw exactly this error? The native ESM resolver in Node, or in browsers? Or a bundler (esbuild or webpack) runtime?

SyntaxError: The requested module 'react-dom' does not provide an export named 'render'


/**
* Creates a portal into which a component can be rendered.
Expand Down
Loading