React Compiler in Rust: Faster Builds, Real Bailouts, and How to Enable It
By Arash Latifi
The official Rust React Compiler landed August 2026; in one 1,036-file codebase the compiler portion of the build got ~17.6x faster. But some patterns still make the compiler skip your component.
TL;DR — The oxc team shipped official Rust support for React Compiler; in one real codebase the compiler portion of the build dropped from 14.3s (Babel) to 0.81s (~17.6x, single-threaded). But
throwinsidetryand logical assignment operators still cause silent bailouts.
If you're tired of sprinkling useMemo everywhere, React Compiler automates that — and its Rust version is now official and dramatically faster. There's a catch: several common patterns still make the compiler skip a component entirely, silently. Here's both sides.
What shipped
The oxc team (behind Oxlint and Rust JS tooling) released official React Compiler support in Rust on August 4, 2026. React Compiler auto-memoizes components so manual useMemo becomes unnecessary; the Babel-based version was slow enough that many teams skipped adoption.
Real-world numbers from the Master.dev write-up (migrating Outlyne, a 1,036-file React Router codebase):
- Compiler portion of the build: 14.3s with Babel → 0.81s with Rust, single-threaded — roughly 17.6x faster
- Whole build: 22.1s → 9.3s (~2.4x) — because builds contain more than the compiler
- oxc's preliminary benchmark claim: "more than 10 times faster than Babel"
Important framing: only the compiler stage got the 17x. Your total build improvement will be smaller — in this case it diluted to 2.4x.
Not just speed: language support improved too
The Babel-based v1.0 compiler had annoying limitations, now fixed in the Rust version:
- Conditional logic inside
try/catchblocks — a blocker in v1.0, now supported - Reassigning a destructured prop that's then used in a nested closure — previously skipped, now fully supported
- Computed object property keys (like
{ [`items-${count}`]: true }) — previously caused bailouts
In the Master.dev case, these fixes alone brought 7 additional components into optimization. But two patterns still bail out: a throw from inside a try block, and logical assignment operators (??=, &&=, ||=). If you use them, the component is skipped — no error, no warning.
The hidden win: one compiler everywhere
A subtler point from the write-up: if Oxlint (which supports React Compiler) runs a different compiler version than your build, a component can be unoptimized in the build while lint reports nothing — exactly the kind of confusing bug that looks like a tooling failure. In the case study, the mismatch was merely v0.145.0 vs v0.144.0 of oxc-transform-react, and it led to a mistaken issue filed against oxc. Unifying on the Rust compiler means linter and build share the same behavior and the same limitations.
Enabling it
Vite (any project)
@vitejs/plugin-react v6.1.0 added "experimental native React Compiler support":
If you're on React Router in framework mode and can't use the Vite React plugin, @acusti/vite-plugin-react-compiler is a minimal plugin that works regardless of the rest of your pipeline.
Next.js (16.4)
Next.js runs the Rust compiler inside Turbopack (experimental since 16.3). Per the 16.4 release post, Turbopack memory-allocation changes cut React Compiler memory usage by ~30% and compile time by 15%, plus a new fast check that skips files that don't need optimization:
Comparing the options
| Option | Where it works | Notes |
|---|---|---|
| @vitejs/plugin-react with { compiler: true } | Standard Vite projects | Simplest path; since v6.1.0 |
| @acusti/vite-plugin-react-compiler | Any pipeline, independent of the React plugin | For React Router framework mode |
| Next.js + turbopackRustReactCompiler | Next.js 16.3+ | No Babel, inside Turbopack; fast check in 16.4 |
Pre-flight checklist
- [ ] Update React and plugins to latest so you get the try/catch and computed-key fixes
- [ ] Search for
throwinsidetryand??=/&&=/||=in render-sensitive components — still bailouts - [ ] If you run Oxlint or similar, confirm linter and build use the same compiler version
- [ ] Time your build before/after — judge the improvement on total build time, not the compiler stage
- [ ] Don't mass-delete
useMemoon day one; verify runtime behavior first — the compiler replaces memoization, not tests
Bottom line
The Rust compiler finally moves React Compiler from "interesting but heavy" to "sensible default": faster builds, cheaper CI (the case-study author notes GitHub Actions minutes became a real cost center), and language support that improves with every release. If your codebase has few bailout patterns, trying it this week is the cheapest optimization available.
FAQ
Q: Should I delete all my useMemo calls after enabling?
Not all at once. The compiler memoizes automatically, so manual useMemo is no longer required, but removal is a cleanup, not a migration. Practical approach: enable on a branch, let your tests pass, then remove manual memoization gradually.
Q: Does the compiler error when it skips a component?
No. Bailouts are silent — the component simply isn't optimized and behaves as it would without the compiler. That's why knowing the bailout patterns (throw in try, ||=-style operators) matters for render-sensitive code.
Q: Will my whole build get 17x faster?
No. The 17x applied to the compiler stage only (single-threaded, in that case study). Total builds include bundling, CSS, type checking and more; the same case saw the full build get ~2.4x faster. Set expectations based on the compiler's share of your build.