Skip to content

Upgrade React 18 to 19#145

Open
fwextensions wants to merge 2 commits into
devfrom
claude/react-19-wjrm30
Open

Upgrade React 18 to 19#145
fwextensions wants to merge 2 commits into
devfrom
claude/react-19-wjrm30

Conversation

@fwextensions

Copy link
Copy Markdown
Owner

Summary

Stacked on #144 so the two can be tested independently. Single commit: react/react-dom 18.3 → 19.2.7.

The codebase was already clean for 19 (by design — the react-virtualized replacement in #144 removed the last findDOMNode dependency):

  • rendering already uses createRoot/hydrateRoot
  • the only defaultProps are static on class components, which is still supported (only the function-component form was removed in 19)
  • react-router 7 and @tanstack/react-virtual both support React 19

Two accompanying changes:

  • JSX transform switched from classic to automatic in build/scripts/babel-jsx.mjs — compiles JSX to jsx() from react/jsx-runtime instead of React.createElement(), since React 19 warns the classic transform is outdated.
  • Pre-rendered markup regenerated: React 19's renderToString serializes spellCheck in camelCase, so src/popup.html gets a one-attribute cosmetic diff (HTML attributes are case-insensitive) to keep hydration clean.

Verification

Loaded the build into Chromium via Playwright: popup search with results, virtualized list scrolling and PageUp/PageDown paging across 25 tabs, options pages including the goober-styled animated demos and router navigation — no console, page, or hydration errors. Demo geometry was also measured pixel-identical to the pre-migration webpack build.

Merge note

If #144 is squash-merged, this branch will need a rebase onto dev before merging; with a regular merge, GitHub will retarget it automatically.

🤖 Generated with Claude Code

https://claude.ai/code/session_017DTY8KLAPgLRcooVuTUMKi


Generated by Claude Code

@fwextensions fwextensions force-pushed the claude/deps-vite-migration-wjrm30 branch from 6cfa3d7 to 039e55b Compare July 11, 2026 21:51
The code was already clean for 19: rendering uses createRoot/hydrateRoot,
the only defaultProps are static on class components (still supported;
only function-component defaultProps was removed), and the last
findDOMNode dependency left with react-virtualized.

The JSX transform switches from the classic runtime to automatic, which
compiles JSX to jsx() from react/jsx-runtime instead of
React.createElement(); React 19 warns that the classic transform is
outdated.

React 19's renderToString serializes the spellCheck attribute in camel
case, so the pre-rendered markup in src/popup.html is regenerated (the
attribute is case-insensitive in HTML, so this is cosmetic).

Verified in Chromium: popup search, virtualized list scrolling and
paging, options pages including the goober-styled animated demos, with
no console or hydration errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DTY8KLAPgLRcooVuTUMKi
@fwextensions fwextensions force-pushed the claude/react-19-wjrm30 branch from 4de6ee3 to e203ede Compare July 11, 2026 22:01
@fwextensions fwextensions changed the base branch from claude/deps-vite-migration-wjrm30 to dev July 11, 2026 22:02
babel-plugin-transform-goober prepends /*#__PURE__*/ to the styled()
calls it rewrites, but the annotation is invalid on a tagged template
expression, so rolldown ignores it and warns on every build. The plugin
has a pure option to turn it off; since the annotation was already
having no effect, nothing is lost.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DTY8KLAPgLRcooVuTUMKi
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