Compiler Rust Port
The Rust port is the compiler’s native implementation of program entry and per-function compilation. The react_compiler crate is explicitly described as the Rust implementation and depends on the compiler’s AST, HIR, lowering, inference, optimization, reactive-scope, SSA, type-inference, and validation crates.
It exists alongside the TypeScript compiler rather than replacing it outright: the Rust Babel plugin is loaded as a separate production path, while end-to-end tooling compares Rust output and events with the TypeScript reference.
Sources: compiler/crates/react_compiler/Cargo.toml:1-20, compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts:173-178, compiler/scripts/test-e2e.ts:8-18
Core concepts
Rust compiler entrypoint
The entrypoint is the Rust orchestration layer that discovers functions, compiles them, and applies the results back to the program AST; its module documentation identifies it as a port of Program.ts.
Sources: compiler/crates/react_compiler/src/entrypoint/program.rs:6-15
Function compilation
Function compilation creates an Environment, lowers a function into HIR, runs optimization and validation passes, and returns generated output or compiler errors.
Sources: compiler/crates/react_compiler/src/entrypoint/pipeline.rs:37-1169
Gating rewrite
A gating rewrite selects the compiled or original function at runtime by calling an imported gating function and placing the result into a conditional expression.
Sources: compiler/crates/react_compiler/src/entrypoint/gating.rs:396-414
Outlined function
An outlined function is compiled output represented as a fresh function declaration, given synthetic scope information, and sent through the same lower-and-pass sequence.
The Rust pipeline supports three output modes, mapping CompilerOutputMode to the corresponding environment mode.
| Mode | Environment output |
|---|---|
Ssr | OutputMode::Ssr |
Client | OutputMode::Client |
Lint | OutputMode::Lint |
Sources: compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177-1227, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1231-1327, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:37-1169, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:46-51
How the Rust port is positioned
The port is useful even though the babel-plugin package already works because it supplies a distinct Rust-backed implementation path while preserving a TypeScript reference for comparison. The Rust plugin is selected when useRustCompiler is enabled, and its documented responsibilities include scope extraction, compilation, and event forwarding.
The repository also has dedicated Rust-versus-TypeScript testing and profiling infrastructure. The end-to-end script describes the TypeScript Babel plugin as the reference output and the Rust Babel path as the production path, while the profiling script runs both compilers and collects timing data at each stage.
The package boundary is architectural: react_compiler coordinates specialized Rust crates instead of implementing every compiler concern in one module.
The following view shows the main crate dependencies surrounding the Rust entrypoint.
Evidence
- react-compilercompiler/crates/react_compiler/Cargo.toml:1
- astcompiler/crates/react_compiler/Cargo.toml:10
- hircompiler/crates/react_compiler/Cargo.toml:10
- loweringcompiler/crates/react_compiler/Cargo.toml:10
- optimizationcompiler/crates/react_compiler/Cargo.toml:10
- validationcompiler/crates/react_compiler/Cargo.toml:10
Sources: compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts:173-178, compiler/scripts/test-e2e.ts:8-18, compiler/scripts/profile-rust-port.ts:8-19, compiler/crates/react_compiler/Cargo.toml:10-24
How a function moves through the pipeline
compile_fn first copies configuration and program context into a new Environment, including function type, output mode, source code, filename, instrumentation names, hook-guard name, and known referenced names.
It then lowers the function into HIR. Invariant errors discovered during lowering abort the function before later processing; when debugging is enabled, the HIR is logged after that check.
The early pass sequence prunes possibly throwing paths, validates context-variable l-values and useMemo, drops manual memoization, and inlines immediately invoked function expressions.
The shared pass runner continues with block merging, SSA entry, redundant-phi elimination, constant propagation, type inference, optional hook validation, and property-method optimization.
Later stages infer mutation and aliasing effects, optionally optimize for SSR, eliminate dead code, run render-safety validations, infer reactive places, validate exhaustive dependencies, and infer reactive-scope variables when memoization is enabled.
The outlined-function path follows the same general shape: it builds a function declaration from codegen output, synthesizes scope information, lowers the declaration, checks invariant errors, and calls run_pipeline_passes.
Evidence
- outlined-entrycompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177
- scope-buildercompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177
- scope-buildercompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1231
- lowering-stagecompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177
- pass-runnercompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177
- pass-runnercompiler/crates/react_compiler/src/entrypoint/pipeline.rs:1644
Outlined scope construction reserves position 0 for the function, processes parameters as bindings, walks the body, and creates program and function scopes plus reference-to-binding maps. Variable declarations process initializer references before declaration patterns, while returns and expression statements are traversed for references.
The traversal also assigns positions through identifiers, JSX names, JSX member expressions, JSX attribute values, and JSX children.
Sources: compiler/crates/react_compiler/src/entrypoint/pipeline.rs:37-60, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:62-83, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:86-132, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1644-1687, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1689-1729, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177-1227, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1231-1327, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1432-1474, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1477-1536, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1538-1559, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1561-1581, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1583-1606, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1608-1637
How gating preserves the TypeScript design
The TypeScript gating design describes a runtime dispatcher with an imported gating function, an optimized function, an unoptimized function, and a wrapper that chooses between them.
Rust carries that design through GatingRewrite, which records the original program index, compiled function node, gating configuration, whether the function was referenced before declaration, and whether it is an export default.
apply_gating_rewrites adds the configured gating import, processes rewrites in reverse source order, and either inserts a special declaration for referenced-before-declared functions or replaces the original statement with a gated expression.
For the special hoisting-sensitive case, insert_additional_function_declaration generates unique result, unoptimized, and optimized names, renames the compiled function, renames the original in place, and constructs dispatcher parameters and arguments.
For ordinary functions, build_gating_expression emits a conditional call to the gating identifier whose consequent is the compiled function and whose alternate is the original. Function declarations are converted to function expressions when needed so all three supported node shapes can participate in the expression.
Export-default handling is explicit: named default declarations become a constant plus a re-export, while anonymous or expression defaults receive the conditional expression directly.
Sources: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Gating.ts:15-35, compiler/crates/react_compiler/src/entrypoint/gating.rs:32-43, compiler/crates/react_compiler/src/entrypoint/gating.rs:51-170, compiler/crates/react_compiler/src/entrypoint/gating.rs:191-392, compiler/crates/react_compiler/src/entrypoint/gating.rs:396-414, compiler/crates/react_compiler/src/entrypoint/gating.rs:419-442
How it connects
The Rust implementation is reached through Babel Plugin Integration, where the Babel-facing integration supplies the parser-side context and invokes the native path. The Rust plugin package imports compileWithRust, scope extraction, and option resolution before exposing its Babel plugin entrypoint.
Its pipeline is the Rust counterpart to the ordered compiler flow described in Compiler Overview & Pipeline, while its HIR and pass behavior connects to Compiler HIR & Passes. The react_compiler crate’s dependency list shows that those concerns are split across dedicated AST, HIR, lowering, optimization, inference, reactive-scope, SSA, type-inference, and validation crates.
The Rust path also feeds compiler diagnostics back as logger events, preserving source filename, locations, messages, hints, severity, and diagnostic category information.
Sources: compiler/packages/babel-plugin-react-compiler-rust/src/BabelPlugin.ts:8-22, compiler/crates/react_compiler/Cargo.toml:10-20, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1842-1914
Key takeaways
- The Rust port is a separate native compiler path, with TypeScript retained as a comparison reference.
compile_fnprepares an environment, lowers to HIR, and runs optimization and validation stages.- Outlined functions receive synthetic scope information before re-entering lowering and the shared pass runner.
- Rust gating reuses the TypeScript design of choosing optimized versus original functions through an imported runtime gate.
Sources: compiler/scripts/test-e2e.ts:8-18, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:37-1169, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1644-1838, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1177-1227, compiler/crates/react_compiler/src/entrypoint/pipeline.rs:1231-1327, compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Gating.ts:15-35, compiler/crates/react_compiler/src/entrypoint/gating.rs:51-170