Skip to content

feat(config): support next.config reactCompiler option#2678

Draft
314systems wants to merge 3 commits into
cloudflare:mainfrom
314systems:314systems-react-compiler-next-config
Draft

feat(config): support next.config reactCompiler option#2678
314systems wants to merge 3 commits into
cloudflare:mainfrom
314systems:314systems-react-compiler-next-config

Conversation

@314systems

@314systems 314systems commented Jul 23, 2026

Copy link
Copy Markdown

Summary

Adds support for the stable Next.js reactCompiler config option:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  reactCompiler: true,
};

export default nextConfig;

The object form is also supported: reactCompiler: { compilationMode: "annotation", panicThreshold: "critical_errors" }.

Closes #2674

Implementation

Mirrors Next.js behavior from packages/next/src/build/get-babel-loader-config.ts:

  • runs the compiler on client transforms only
  • requires babel-plugin-react-compiler and reports a clear install error when missing
  • pins target: "18" when React 18 is installed
  • enables anonymous-function names in development
  • runs the compiler before user-supplied Babel plugins

Both supported plugin-react generations are handled:

  • @vitejs/plugin-react v5 uses its function-form babel option
  • @vitejs/plugin-react v6 uses @rolldown/plugin-babel with a lazy, client-only preset; this path additionally requires @rolldown/plugin-babel

The v6 path also pre-optimizes react/compiler-runtime or react-compiler-runtime, depending on the detected React target. With vinext({ react: false }), vinext warns that the compiler must be configured in the user's own React plugin setup.

Verification

  • config normalization and compiler helper unit tests
  • plugin-react auto-registration integration test
  • isolated real client transform using @rolldown/plugin-babel@0.2.3 and babel-plugin-react-compiler@1.0.0; output contains react.memo_cache_sentinel
  • verified the matching compiler runtime is included in client optimizeDeps.include

Documentation

The README configuration table documents the accepted values, dependencies, client-only behavior, and react: false caveat.

Model `reactCompiler` (boolean or { compilationMode, panicThreshold })
in NextConfig/ResolvedNextConfig, and wire it into the auto-registered
@vitejs/plugin-react Babel pipeline.

Mirrors Next.js behavior (packages/next/src/build/get-babel-loader-config.ts):
- the compiler plugin runs on client transforms only (skipped for SSR)
- babel-plugin-react-compiler must be installed in the project (throws
  with an install hint otherwise)
- target: '18' is pinned when the installed React major version is 18
- anonymous functions are named in dev
- the compiler plugin runs first in the Babel pipeline

Uses a function-form babel option so the compiler can be toggled by
next.config even though @vitejs/plugin-react is instantiated before
config resolution. With vinext({ react: false }), a warning tells the
user to add the plugin to their own react() setup.

Closes cloudflare#2674

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@314systems
314systems marked this pull request as draft July 23, 2026 06:40
@vitejs/plugin-react v6 no longer accepts the legacy babel option. Use
@rolldown/plugin-babel with a lazy client-only compiler preset instead,
while retaining the v5 Babel callback path.

Pre-optimize the matching compiler runtime and document the additional
v6 dependency requirement.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@314systems

Copy link
Copy Markdown
Author

I re-verified this against the installed @vitejs/plugin-react v6 implementation and found that the initial commit used the removed v5 babel option, so v6 silently ignored the compiler configuration.

Fixed in 88cfbf4:

  • plugin-react v6 now uses @rolldown/plugin-babel with a lazy, client-only React Compiler preset
  • plugin-react v5 retains the function-form babel callback path
  • the matching compiler runtime is added to client optimizeDeps.include
  • the README and missing-dependency error now mention the additional @rolldown/plugin-babel requirement for v6

I also ran an isolated real transform with @rolldown/plugin-babel@0.2.3 and babel-plugin-react-compiler@1.0.0 through vinext({ nextConfig: { reactCompiler: true } }). The transformed client module contains react.memo_cache_sentinel, and react/compiler-runtime is present in the client optimizer includes.

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.

docs: Add guide for using React Compiler with vinext

1 participant