[v6] Use the Rust React Compiler via jsc.transform.reactCompiler
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 42/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- react, typescript, webpack
- Área
- build-system, tooling
Línea de trabajo
Empieza por packages/repack/src/loaders/babelSwcLoader/swc.ts y los puntos de entrada getSwcLoaderOptions/getJsTransformRules; lee las pruebas de transformación existentes y ejecútalas. Verifica el comportamiento de Babel-then-SWC con react-native-worklets/plugin y packages/plugin-reanimated, y cubre después las opciones compatibles y no compatibles, el manejo de versiones y la documentación, para que la ruta opt-in quede probada y documentada.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Motivation
The React Compiler has been ported to Rust and is exposed through builtin:swc-loader as jsc.transform.reactCompiler since Rspack 2.1. Rspack measures the Rust implementation at 7–13x the speed of babel-plugin-react-compiler.
Re.Pack has no React Compiler support of any kind today — no mention in packages/, website/src or the templates. Users who want it add babel-plugin-react-compiler to their own babel.config.js, and because of how babel-swc-loader partitions work, that plugin then runs on the Babel side for every component file in the app.
Part of #1414 (Roadmap to V6), which lists "rust react compiler support" as a deliverable. Adjacent to #1422 (SWC setup rework) — both touch getSwcLoaderOptions, and the config surface should be designed once.
Why it lands on the Babel side today
babelSwcLoader reads the project's Babel config, partitions the detected plugins into "SWC can do this" vs "Babel must do this", then runs Babel with excludePlugins: supportedSwcTransforms followed by SWC:
const { includedSwcTransforms, supportedSwcTransforms, swcConfig } =
partitionTransforms(this.resourcePath, detectedBabelTransforms);
const babelResult = await transform(source, baseBabelConfig, {
excludePlugins: supportedSwcTransforms,
...
});
babel-plugin-react-compiler appears in none of SWC_SUPPORTED_NORMAL_RULES / SWC_SUPPORTED_CONFIGURABLE_RULES / SWC_SUPPORTED_CUSTOM_RULES in swc.ts, so it is never excluded and always runs through Babel. React Compiler is by far the most expensive Babel plugin in a typical RN app's config — it does whole-function dataflow analysis on every component. Mapping it into jsc.transform.reactCompiler is the single biggest remaining Babel offload available to us.
Verified behaviour
All of the below was checked against @rspack/[email protected] via experiments.swc.transformSync.
It works, and composes with the RN-shaped config we already emit:
| config | result |
|---|---|
reactCompiler: true |
memoized, emits react/compiler-runtime |
+ env.include (RN-style transform list from getSwcLoaderOptions) |
memoized |
+ module.type: 'commonjs' |
memoized, emits require("react/compiler-runtime") |
The last row matters — getSwcLoaderOptions emits module.type: 'commonjs' by default, and the compiler runtime import survives the module transform correctly.
The accepted option surface is narrower than the Babel plugin's. Probed exhaustively:
| option | accepted values |
|---|---|
target |
'17', '18', '19' — '20' rejected |
compilationMode |
'infer', 'annotation', 'all', 'syntax' |
panicThreshold |
'none', 'critical_errors', 'all_errors' (lowercase only) |
| anything else | rejected — expected boolean or object |
Notably sources is rejected. The Babel plugin uses it to scope which files get compiled; here that has to be expressed with the loader rule's include / exclude instead. Same for the enable* escape hatches (e.g. enableTreatRefLikeIdentifiersAsRefs) — projects depending on those cannot move off Babel yet.
Version floor. @rspack/core >= 2.1.0. #1414 currently targets "Rspack 2+", which is not sufficient for this; the floor needs to be 2.1 if this ships as a supported feature (or the option needs a version guard, which Re.Pack already has machinery for — see getRspackMajorVersion / isRspack2 in src/helpers/rspackVersion.ts).
React version. The workspace catalog is on react: 19.2.3, where react/compiler-runtime is built in and target can be omitted. React 17/18 projects need an explicit target and the separate react-compiler-runtime package installed — that's a user-facing install step we have to document, not something we can do for them.
Proposed direction
Two independent surfaces, both opt-in and off by default:
-
babel-swc-loader(the default path). Addbabel-plugin-react-compilerto the custom-transform map inswc.tsso a project that already has it inbabel.config.jsgets it lifted to SWC automatically, with its Babel options translated to thereactCompilershape. Because the surface is narrower, the mapping must detect unsupported options and leave the plugin on the Babel side rather than silently dropping them — asourcesorenable*option present means "keep using Babel for this project". -
getSwcLoaderOptions/getJsTransformRules(the SWC-native path). Add areactCompiler?: boolean | { target?, compilationMode?, panicThreshold? }option that maps tojsc.transform.reactCompiler, defaulting to off.
Ordering caveat to verify
In babelSwcLoader, Babel runs first and SWC second, so lifting React Compiler to SWC moves it from "before everything" to "after the remaining Babel plugins". JSX survives the Babel pass (transform-react-jsx is in the SWC-supported set, so it is excluded from Babel), which is the main thing React Compiler needs to see intact — but this needs a real test, not an assumption. Projects with worklet-style plugins that rewrite function bodies (react-native-worklets/plugin is in apps/tester-app/babel.config.js, and Reanimated is a first-party integration in packages/plugin-reanimated) are the interesting case: those stay on the Babel side and would now run before the compiler instead of after it.
Scope
Core
- Add
reactCompilertogetSwcLoaderOptions(+ thread throughgetJsTransformRules), off by default, mapping tojsc.transform.reactCompiler - Guard the option behind Rspack >= 2.1 with a clear error/warning on older majors and on webpack (
builtin:swc-loaderis Rspack-only) - Map
babel-plugin-react-compilerinswc.ts'sSWC_SUPPORTED_CUSTOM_RULES, translatingtarget/compilationMode/panicThreshold - Bail out of the mapping (leave the plugin on Babel) when the project passes options SWC does not accept —
sources,enable*, anything outside the three above - Decide whether
targetis inferred from the resolvedreactversion or left explicit
Apps and tests
- Verify the Babel-then-SWC ordering is safe, specifically alongside
react-native-worklets/pluginandpackages/plugin-reanimated - Enable React Compiler in
apps/tester-app(or a variant) so the path is exercised on device, not just in unit tests - Unit tests for the
swc.tsmapping, including the unsupported-option bail-out - Snapshot coverage in
getSwcLoaderOptionstests
Docs
- New guide page for React Compiler — how to enable it on both loader paths, the Rspack >= 2.1 requirement, and the React 17/18
target+react-compiler-runtimeinstall step - Document the option gap vs
babel-plugin-react-compiler(sources→ use ruleinclude/exclude) and when a project should stay on Babel - Update
website/src/latest/api/utils/get-swc-loader-options.mdandget-js-transform-rules.md
Open questions
- Does v6 raise the Rspack floor to 2.1 (making this unconditional), or keep 2.0 and version-guard the option?
- Should Re.Pack enable React Compiler by default for new projects in
templates/, follow React Native's own default, or leave it entirely opt-in? - Is auto-lifting from
babel.config.jsthe right default forbabel-swc-loader, or should it require an explicit loader option? Auto-lifting is the bigger win but silently changes where a plugin runs in the pipeline.
- Lenguaje dominante
- TypeScript
- Estrellas
- 1.9k
- Forks
- 168
- Merge medio
- 2 d 6 h
- PR fusionados (30 d)
- 18
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de callstack/repack
-
json as string in JS bundleAbierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
callstack/repack#1461 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[v6] Rework the SWC setup: native Flow support and a modernized getJsTransformRulesPosiblemente ocupada @whydidoo la tomó hace 1 día. Abiertoarea:repack type:feature
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
callstack/repack#1422 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
area:repack type:feature
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
callstack/repack#1420 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Roadmap to V6Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
callstack/repack#1414 · 1 comentario · 3 reacciones ·
Los mantenedores suelen responder en 1 día
-
question type:feature
Dificultad 4/5 3-5 días Aptitud para principiantes 42/100
callstack/repack#1298 · 13 comentarios · 9 reacciones ·
Los mantenedores suelen responder en 1 día
Todos los issues de callstack/repack
Issues similares
-
chore v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
modelcontextprotocol/servers#5115 ·
Los mantenedores suelen responder en 1 día
-
beginner bug good first issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
philaconvalley/website#168 ·
Los mantenedores suelen responder en 1 día
-
bug frontend good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
oss-slu/lrda_mobile#294 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
hatchet-dev/hatchet#5179 ·
Los mantenedores suelen responder en 1 día