feat(desktop): React Compiler on the renderer, plus Vite 8 / plugin-react 6 / electron-vite 6 / Lingui 6.12

Merged
SA
3d ago
+240-321

What

  1. React Compiler (babel-plugin-react-compiler@1.0.0) on the whole desktop renderer, in two commits: chat transcript + chat-ui first, then everything.
  2. Toolchain upgrade: Vite 7.3.7 → 8.3.6, @vitejs/plugin-react 5.2.0 → 6.2.1, electron-vite 4.0.1 → 6.0.0, Lingui 6.8.0 → 6.12.0 (repo-wide). All versions are older than the 3-day minimumReleaseAge.

Lingui + compiler order

The Lingui macro must run before the compiler; compiler-first makes the macro throw on useLingui in 5 files and emit different ids in 3 more. plugin-react 6 dropped its babel option, so both now go through @rolldown/plugin-babel: the macro as a plugin, the compiler as reactCompilerPreset(). Babel runs plugins before presets, and all 1,201 renderer/package macro files compile byte-identical to the previous [macro, compiler] setup.

Production bundle check: all interpolated messages in shipped code are at their call sites with values and in the en catalog, 0 empty-message ids, 2,933 memo sentinels. check:i18n regenerates the catalogs unchanged.

Lingui 6.9's native (Rust) macro transform was tried and not used: inside memo(function …) / forwardRef(function …) it emits an empty message (_-Z5u4) for t({ message: plural(...) }), which hits RichText and V2WorkspaceRow today.

Other changes from the upgrade

  • vite-tsconfig-paths replaced by Vite's resolve.tsconfigPaths.
  • SF Mono faces are now registered with FontFace in styles/bundled-fonts.ts. Vite 8 resolves url("superset-font://…") in CSS as a file path and fails the build (still the case on 8.3.7).
  • Both Storybooks use @rolldown/plugin-babel for the macro.

Measured (live app, same prompts, own workspace chat; dev build, ratios only)

Turn 1Compiler offCompiler on (Vite 7)Compiler on (Vite 8)
Renders213.6k138.1k111.9k (−48%)
React commit ms546442003908 (−28%)
Long-frame ms984521749 (−24%)

Turn 2 on Vite 7: renders −31%, React ms −13%, long-frame ms −45%. Idle is unchanged: it's dominated by V2WorkspaceContent, which the compiler can't skip. One run per cell on a shared machine, so treat these as directional.

Verification

  • bun run test: all suites pass except packages/shared rrule.test.ts "wraps past midnight". That test fails the same way on main on this Mac: local Bun's ICU 78.1 formats "Oct 29, 2026 at 8:00 PM", and main's CI passes.
  • Typecheck (desktop, ui, i18n), biome, sherif: clean.
  • electron-vite build: passes in 52 s, down from 2m22s on Vite 7 with the compiler (1m35s without it).
  • Both Storybook builds pass, with macros compiled.
  • Live app on Vite 8: 19-step smoke pass (workspace, file search, terminal, tasks, PRs, automations, pages, plugins, workspaces, new workspace, search, 4 settings pages) and a streamed chat turn, all with 0 console errors and no error boundaries.
  • Not checked: SF Mono loading in a packaged build. In dev it is blocked by CORS (http://localhost → superset-font://) both before and after this change, and FontFace and @font-face go through the same fetch.

Not changed

  • React stays at 19.3.0: 19.3.1 only changes Server Components, and Expo SDK 58 pins 19.3.0.
  • About 292 renderer functions remain uncompiled (mostly ref reads during render, e.g. Transcript and SessionView); they keep working as before.

Summary by cubic

Enables the React Compiler across the desktop renderer and upgrades the build toolchain to Vite 8, @vitejs/plugin-react 6, electron-vite 6, and Lingui 6.12. In the measured chat turn, render counts drop about 48% and React commit time about 28% versus the compiler off.

Notes

  • SF Mono faces moved from CSS @font-face to a FontFace registration in styles/bundled-fonts.ts because Vite 8 resolves superset-font:// URLs in CSS as file paths and fails the build.
  • The Lingui macro must run before the compiler; in the other order five files throw and three more get different message ids. Both now run through @rolldown/plugin-babel, since plugin-react 6 dropped its babel option.
  • vite-tsconfig-paths is replaced by Vite's resolve.tsconfigPaths.
  • Lingui 6.9's native macro transform was tried but not used; it emits an empty message for t({ message: plural(...) }) inside memo/forwardRef.
  • About 292 renderer functions (mostly ref reads during render) remain uncompiled and keep working as before.

Summary by CodeRabbit

  • Improvements
    • Desktop terminal typography continues to support SF Mono in regular, bold, and italic styles, with fonts displayed while loading.
  • Other Changes
    • No other user-facing changes are noted. The remaining updates affect application build and development tooling and do not describe changes to app functionality.