Skip to content

Update React dependencies to v19#32473

Closed
teredasites wants to merge 1 commit into
jhipster:mainfrom
teredasites:feat/react-19-update
Closed

Update React dependencies to v19#32473
teredasites wants to merge 1 commit into
jhipster:mainfrom
teredasites:feat/react-19-update

Conversation

@teredasites

Copy link
Copy Markdown

Summary

Update React and related type packages to version 19, addressing all breaking changes in generated application code.

Closes #28130

Changes

Dependency Updates

  • react: 18.3.1 -> 19.1.0
  • react-dom: 18.3.1 -> 19.1.0
  • @types/react: 18.3.12 -> 19.1.6
  • @types/react-dom: 18.3.1 -> 19.1.6

Breaking Change Fixes

findDOMNode removed in React 19

  • Added react-dom-compat.ts polyfill that restores a basic findDOMNode implementation on the react-dom module. This is required because reactstrap depends on react-transition-group which calls ReactDOM.findDOMNode internally.
  • The polyfill is imported at the top of index.tsx (before any library code) and in setup-tests.ts (for test compatibility).

Global JSX namespace removed in @types/react 19

  • Replaced all bare JSX.Element references with React.JSX.Element in:
    • typings.d.ts.ejs (microfrontend module declarations)
    • error-boundary-routes.spec.tsx.ejs
    • private-route.spec.tsx.ejs
  • Added /// <reference types="react" /> triple-slash directive in typings.d.ts to ensure React types are available for React.JSX.Element in ambient declarations.

Stricter null types

  • Added non-null assertion (!) on document.getElementById('root') in index.tsx since createRoot() in React 19 is stricter about null arguments.

Peer dependency conflicts

  • Added overrides section in generated package.json for react-redux-loading-bar and react-jhipster which haven't updated their peer dependency ranges to include React 19 yet.

Files Changed

  • generators/react/resources/package.json - Version bumps
  • generators/react/files-react.ts - Register new polyfill template
  • generators/react/templates/src/main/webapp/app/config/react-dom-compat.ts.ejs - New findDOMNode polyfill
  • generators/react/templates/src/main/webapp/app/index.tsx.ejs - Import polyfill, null assertion fix
  • generators/react/templates/src/main/webapp/app/setup-tests.ts.ejs - Import polyfill for tests
  • generators/react/templates/src/main/webapp/app/typings.d.ts.ejs - React reference directive, JSX.Element fix
  • generators/react/templates/package.json.ejs - npm overrides for peer deps
  • generators/react/templates/src/main/webapp/app/shared/error/error-boundary-routes.spec.tsx.ejs - JSX.Element fix
  • generators/react/templates/src/main/webapp/app/shared/auth/private-route.spec.tsx.ejs - JSX.Element fix
  • generators/react/__snapshots__/generator.spec.ts.snap - Updated snapshots

Test plan

  • All 766 React generator tests pass (esmocha generators/react/generator.spec.ts)
  • Snapshots updated to include new react-dom-compat.ts file
  • CI should verify generated applications build and test successfully with React 19

- Bump react and react-dom from 18.3.1 to 19.1.0
- Bump @types/react from 18.3.12 to 19.1.6
- Bump @types/react-dom from 18.3.1 to 19.1.6
- Add findDOMNode polyfill (react-dom-compat.ts) for reactstrap/react-transition-group compatibility since findDOMNode was removed in React 19
- Import polyfill in index.tsx and setup-tests.ts before any library usage
- Replace bare JSX.Element with React.JSX.Element (global JSX namespace removed in @types/react 19)
- Add triple-slash reference directive in typings.d.ts for React types
- Add non-null assertion on getElementById('root') for stricter types
- Add npm overrides for react-redux-loading-bar and react-jhipster peer deps
- Update test snapshots

Closes jhipster#28130
@github-actions github-actions Bot added theme: react theme: dependencies Pull requests that update a dependency file labels Feb 27, 2026
@DanielFran

Copy link
Copy Markdown
Member

@teredasites Please update reacstrap version

@DanielFran DanielFran requested a review from Copilot February 27, 2026 23:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the React generator templates to React 19 (runtime + type packages) and applies template-level fixes for React 19 breaking changes (notably removal of findDOMNode and the global JSX namespace).

Changes:

  • Bumped react, react-dom, and related @types/* packages to React 19.
  • Added a react-dom compatibility shim to restore findDOMNode for legacy dependencies.
  • Updated template type annotations from JSX.Element to React.JSX.Element and added an ambient React types reference.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
generators/react/templates/src/main/webapp/app/typings.d.ts.ejs Adds React types reference and updates microfrontend typings to React.JSX.Element.
generators/react/templates/src/main/webapp/app/shared/error/error-boundary-routes.spec.tsx.ejs Updates test component return types to React.JSX.Element.
generators/react/templates/src/main/webapp/app/shared/auth/private-route.spec.tsx.ejs Updates wrapper parameter type to React.JSX.Element.
generators/react/templates/src/main/webapp/app/setup-tests.ts.ejs Imports the findDOMNode compatibility shim in test setup.
generators/react/templates/src/main/webapp/app/index.tsx.ejs Imports the shim before other imports and adds a non-null assertion for the root element.
generators/react/templates/src/main/webapp/app/config/react-dom-compat.ts.ejs New shim that polyfills ReactDOM.findDOMNode.
generators/react/templates/package.json.ejs Adds npm overrides to work around peer dependency ranges not yet updated to React 19.
generators/react/resources/package.json Updates React and type dependency versions to React 19.
generators/react/files-react.ts Registers the new shim template file for generation.
generators/react/snapshots/generator.spec.ts.snap Snapshot updates to include the newly generated shim file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +31
let node = fiber;
while (node) {
if (node.stateNode instanceof Element || node.stateNode instanceof Text) {
return node.stateNode;
}
node = node.child;

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

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

The fiber traversal only follows child pointers and never explores sibling (or walks back up via return), so it can incorrectly return null even when a host DOM/Text node exists elsewhere in the subtree. Consider switching to a small DFS traversal (child → sibling → return) so the shim can find the first stateNode that is an Element/Text in more real-world component trees.

Suggested change
let node = fiber;
while (node) {
if (node.stateNode instanceof Element || node.stateNode instanceof Text) {
return node.stateNode;
}
node = node.child;
const stack: any[] = [fiber];
while (stack.length > 0) {
const node = stack.pop();
if (!node) {
continue;
}
if (node.stateNode instanceof Element || node.stateNode instanceof Text) {
return node.stateNode;
}
if (node.sibling) {
stack.push(node.sibling);
}
if (node.child) {
stack.push(node.child);
}

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +20
if ((componentOrElement as Element).nodeType != null) {
return componentOrElement as Element;

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

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

This branch treats any nodeType as an Element, but callers may pass a Text node (and your function signature includes Text). Returning componentOrElement as Element is type-incorrect and can mislead downstream code. Use a Node-compatible type (or Element | Text) for the cast/return in this branch to match the runtime behavior.

Suggested change
if ((componentOrElement as Element).nodeType != null) {
return componentOrElement as Element;
if ((componentOrElement as Node).nodeType != null) {
return componentOrElement as Element | Text;

Copilot uses AI. Check for mistakes.
import ErrorBoundaryRoutes from './error-boundary-routes';

const ErrorComp = (): JSX.Element => {
const ErrorComp = (): React.JSX.Element => {

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

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

These templates now reference the React namespace for types but do not explicitly import React types. In TypeScript setups that restrict compilerOptions.types, this can fail with Cannot find namespace 'React'. A more robust pattern is to add an explicit type-only import (e.g. import type * as React from 'react';) or import JSX from react and use JSX.Element from that import.

Copilot uses AI. Check for mistakes.
};

const NoErrorComp = (): JSX.Element => {
const NoErrorComp = (): React.JSX.Element => {

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

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

These templates now reference the React namespace for types but do not explicitly import React types. In TypeScript setups that restrict compilerOptions.types, this can fail with Cannot find namespace 'React'. A more robust pattern is to add an explicit type-only import (e.g. import type * as React from 'react';) or import JSX from react and use JSX.Element from that import.

Copilot uses AI. Check for mistakes.
<%_ } _%>

const wrapper = (Elem: JSX.Element, authentication) => {
const wrapper = (Elem: React.JSX.Element, authentication) => {

Copilot AI Feb 27, 2026

Copy link

Choose a reason for hiding this comment

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

Similar to the other spec template, this introduces a dependency on the global React namespace for typing without an explicit type-only import. To avoid Cannot find namespace 'React' in projects that restrict compilerOptions.types, prefer an explicit type-only import (or import JSX from react and use JSX.Element).

Copilot uses AI. Check for mistakes.
@mshima

mshima commented Mar 5, 2026

Copy link
Copy Markdown
Member

Fixed in #32495 by moving to react-bootstrap.
Thanks anyway.

@mshima mshima closed this Mar 5, 2026
@mraible mraible added this to the 9.0.0 milestone Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

theme: dependencies Pull requests that update a dependency file theme: react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update to React 19

5 participants