React Compiler Support
We are excited to announce React Compiler support in Oxlint and Oxc Transform.
Oxlint now includes 22 React Compiler-powered rules that use the compiler's validation passes to catch violations of the Rules of React.
The package oxc-transform-react applies React Compiler's automatic memoization. It is more than 10 times faster than Babel in our preliminary benchmark.
Integration with @vitejs/plugin-react is coming soon.
Getting started
Oxlint
Enable the React plugin and its correctness rules:
{
"plugins": ["react"],
"categories": {
"correctness": "error"
}
}React Compiler rule categories are aligned with the upstream ESLint presets. We added all recommended rules to Oxlint's correctness category.
If you enabled the previous nursery react/react-compiler rule, remove it from your configuration. It has been replaced by the category-specific rules below.
| Rule name | ESLint preset | Oxlint category | Note |
|---|---|---|---|
error-boundaries | recommended | correctness | |
globals | recommended | correctness | |
immutability | recommended | correctness | |
incompatible-library | recommended | correctness | |
preserve-manual-memoization | recommended | correctness | |
purity | recommended | correctness | |
refs | recommended | correctness | |
set-state-in-effect | recommended | correctness | |
set-state-in-render | recommended | correctness | |
static-components | recommended | correctness | |
use-memo | recommended | correctness | |
unsupported-syntax | recommended | restriction | |
config | recommended | Not implemented | Oxlint uses fixed, valid compiler options. |
gating | recommended | Not implemented | Oxlint does not expose compiler gating options yet. |
void-use-memo | recommended-latest | correctness | |
no-deriving-state-in-effects | off | perf | |
invariant | off | restriction | |
rule-suppression | off | restriction | |
syntax | off | restriction | |
todo | off | restriction | |
capitalized-calls | off | suspicious | |
exhaustive-effect-dependencies | off | suspicious | |
hooks | off | suspicious | |
memo-dependencies | off | suspicious | |
fbt | off | Not implemented | This is a Meta-internal FBT category. |
memoized-effect-dependencies | off | Not implemented | Upstream's EffectDependencies category is absent from the Rust compiler port. |
Transform
Install oxc-transform-react:
pnpm add -D oxc-transform-reactimport { transformSync } from "oxc-transform-react";
const result = transformSync(
"Component.tsx",
`
export function Component({ name }: { name: string }) {
return <div>Hello {name}</div>;
}
`,
{
reactCompiler: {
target: "19",
},
jsx: {
runtime: "automatic",
},
},
);
if (result.fatal) {
console.error(result.errors);
} else {
console.log(result.code);
}@vitejs/plugin-react
Native integration is waiting for vitejs/vite-plugin-react#1419 to land.
We keep this framework-specific integration in @vitejs/plugin-react, rather than adding it to Vite or Rolldown, so the core toolchain remains vendor-neutral.
Benchmark
Our preliminary benchmark shows that oxc-transform-react is more than 10 times faster than babel-plugin-react-compiler.
Files that used to take around 100 ms to compile now take around 10 ms.
Background
React Compiler is a build-time compiler that automatically memoizes React components and hooks. React Compiler 1.0 was released last year as babel-plugin-react-compiler.
Earlier this year, the React team ported React Compiler to Rust. We started looking for ways to integrate it into Oxc.
Our initial integration added more than 5 MiB to the binary, and we believed we could improve its performance significantly.
Our first attempt was to maintain a synchronized fork and publish it as crates. The goal was to let the Rust tooling ecosystem, including SWC, Bun, and Biome, use and maintain one shared fork.
We then discovered that this version of React Compiler maintained its own Babel-shaped AST. Oxc had to convert its AST into that representation before running the compiler, then convert it back afterwards. We knew we could make it faster by running the compiler directly on Oxc's AST. The Rust port was also unfinished, had bugs, and did not yet conform to the original Babel implementation.
We eventually decided to vendor React Compiler into Oxc for tighter integration. This allowed us to remove the intermediate Babel AST and make React Compiler operate directly on the Oxc AST.
After a lot of work, we made it significantly faster and smaller, with better conformance, diagnostics, and source maps.
Improvements
The original Rust port was unfinished when it was merged. We finished many missing pieces, fixed bugs, and added the improvements below.
Performance
In our local measurements, Oxc's version is about twice as fast as the original Rust port of React Compiler.
Running directly on Oxc's AST also reduced memory allocations.
Conformance
Oxc conforms to the latest experimental release of babel-plugin-react-compiler, while its default options remain aligned with Babel React Compiler v1 because the latest experimental release changed some defaults.
We have compared our output against this version across more than 100 large and popular repositories, covering over 100,000 source files, and made sure all files compile to the same output.
Diagnostics
We improved React Compiler diagnostics to make issues easier for coding agents to fix. Oxlint now shows compact codeframes, related source locations, help messages, and links.
⚠ react(immutability): This value cannot be modified
╭─[immutability.tsx:7:11]
6 │ const [state, setState] = useState({a: 0});
7 │ state.a = 1;
· ──┬──
· ╰── value cannot be modified
8 │ return <div>{props.foo}</div>;
╰────
help: Modifying a value returned from 'useState()', which should not be modified directly. Use the setter function to update instead
note: React Compiler skipped optimizing this component or hook. Additional guidance: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutabilityBinary size
Our first fork-based integration produced an 8.66 MiB macOS ARM64 binary. After removing the Babel AST and JSON round-trip, replacing the full regex engine, and removing unused compiler code, the published oxc-transform-react v0.144.0 binding is 3.97 MiB.
React Compiler remains in a separate optional package, so it does not increase the binary size for Oxc Transform.
Source maps
The original Rust port had incomplete source map support.
We made sure source maps work correctly across React Compiler, TypeScript, JSX, and React Fast Refresh.
Future work
There are still many TODOs in the code. At the time of writing, the original Rust crates contain 16 literal TODO markers and 62 code paths that emit Todo diagnostics. Oxc's vendored compiler contains 10 literal TODO markers and 57 centralized Todo diagnostic constructors.
We will maintain the Rust port, complete the remaining TODOs, and fix reported React Compiler issues. We have also found bugs in the original Babel implementation and want to investigate and fix them. Bug reports and contributions are welcome.
Acknowledgements
Thank you to the React Compiler team, especially Joseph Savona, for developing and open sourcing the Rust port that made this integration possible.
Thank you to Lauren Tan for answering our questions.
Please try it and report any issues with a minimal reproduction.

