The React Compiler moved to Rust. For a while, that was just a merged pull request nobody could really use. Then, in the last two weeks, it shipped. Vite and Bun got it, and they have the 10X speed claim.
Out of curiosity, I did the obvious thing. I picked out time to build one real app and run the 10x claim through it. Not one lonely test file, the way benchmarks usually do it. I built a whole app; it was faster with Claude.
So here is the short version before we dive into the article: the speedup claim is genuine; it is bigger than 10x, actually. And on a normal app, you will not feel it at all. All three are true at once. I also found where you do feel it. That gap, and where it finally closes, is the whole story.
Vite plugin-react 6.1 added a compiler option. It runs on a new package called oxc-transform-react. The Oxc team says it is more than 10 times faster than the Babel plugin. About 100ms per file, down to 10ms. Around the same time, Bun 1.4 rewrote itself from Zig to Rust, with the React Compiler right in it.
Why should you care? Because of who built it. The React team ported the compiler to Rust. Then the Oxc team at VoidZero cleaned it up and shipped it as real packages. They also checked it against more than 100 repos and 100,000 files to make sure it did not break things. So the work is solid.
But there is a catch in that 10x. It is measured on single files, one at a time. That is a tiny slice of what a build does. Nobody had checked what it does to a real app. The full build. The dev server. The thing you sit and wait for all day. That is the gap I wanted to close.
We saw this coming, by the way. In the LogRocket H1 2026 frontend report, we said the next step for the Rust compiler was going native inside tools like Oxc and SWC. That step just happened. So this is the follow-up. Does it hit 10x in a real app? And would I ship it today?
Three things landed, and they are not the same thing. The Babel React Compiler is the old path. It has been production-ready since React 19; it is the slow one now, and it is the baseline everything else gets measured against. The Oxc Rust compiler lives inside Vite, through @vitejs/plugin-react 6.1, backed by the oxc-transform-react package. That is the Rust port, wrapped so Vite users can turn it on. Bun 1.4 is the third. The whole runtime is Rust now, and the React Compiler is built into Bun.build.
Here is the setup for each. This is the copy-and-paste part.
Babel, the baseline:
npm install -D babel-plugin-react-compiler
// vite.config.babel.ts
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
react({
babel: {
plugins: ['babel-plugin-react-compiler'],
},
}),
],
})
Oxc through Vite:
npm install -D oxc-transform-react
// vite.config.oxc.ts
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
react({
compiler: true,
}),
],
})
Bun, built in:
// bun-build.ts
const result = await Bun.build({
entrypoints: ['./src/main.tsx'],
outdir: './dist-bun',
minify: true,
target: 'browser',
reactCompiler: true,
})
One warning before you copy the Oxc setup. Use the official @vitejs/plugin-react route with compiler: true. Do not use the community unplugin-oxc or vite-plugin-oxc route. There is a known bug on that path where React gets imported twice, and you get hit with the classic “Invalid hook call” error at runtime. I stayed on the official plugin and never saw it. If you see that error, that is your sign you are on the wrong plugin.
Babel runs on JavaScript. JavaScript is interpreted and garbage-collected, which is fine for most things and slow for this one. A compiler spends all its time parsing code and walking trees, and that is exactly the work a garbage collector keeps interrupting. Rust compiles straight to native machine code. There is no interpreter, garbage collector, or tight control over memory. Same job, but with far less overhead. That is most of where the speed comes from.
But Rust is not all of it, and this is the part nobody mentions. The Oxc team says so themselves. The first Rust port still carried a Babel-shaped syntax tree, so Oxc had to convert its own tree into Babel’s format, run the compiler, then convert it back. That round trip cost real time. They pulled the compiler in and made it run directly on their own tree, no conversion, and that alone made it about twice as fast as the plain Rust port.
I built a mid-size admin dashboard. It has 178 exported components across 164 .tsx files, about 3,900 lines of source. Five tabbed views: an overview with metric cards, an analytics page with recharts line, bar, area, and pie charts, sortable and filterable data tables with pagination, five forms with real validation, and a live notifications list.
I mixed the components on purpose. Some are hand-memoized already, with existing useMemo and useCallback. Some are left completely raw, with expensive render paths and no memoization at all. That gives the compiler something real to chew on and shows how it behaves when you already did some of the work by hand.
Dashboard Overview:

Analytics:

Tables:

Forms:

Notifications:


The versions, for the record: React 19.2.8, Vite 8.3.0, @vitejs/plugin-react 6.1.1, oxc-transform-react 0.145.0, babel-plugin-react-compiler 1.0.0, Bun 1.4.2. All of it on an Apple M4 with 16 GB of RAM, Node 22.14.0. Each build ran six times with hyperfine, with the first run thrown out as a warm-up. I report the median. One run is noise, and five clean runs are data.
This is the part that matters. Start with the full cold build, everything cleared before each run.
| Pipeline | Median cold build | Speedup vs Babel |
|---|---|---|
| Babel | 305.9 ms | 1.0x |
| Oxc via Vite | 317.1 ms | 0.96x (slower) |
| Bun | 34.9 ms | 8.8x |
Read that again. The Oxc Rust compiler produced a build that was slightly slower than Babel. Twelve milliseconds slower, about four percent. On the pipeline that is supposed to be 10x faster.
That is not a mistake, and it is not a contradiction. It is the whole point. Here is why. I isolated the raw transform step, the actual layer the 10x claim describes, and ran all 164 files straight through each compiler with no bundler in the way.
| Layer | Babel | Oxc Rust | Speedup |
|---|---|---|---|
| Raw transform, 164 files | 986.6 ms | 51.7 ms | 19.1x |
| Per file | 6.02 ms | 0.32 ms | 18.8x |
There it is. At the transform layer, Oxc is 19x faster. The “more than 10x” claim was conservative.
The Rust compiler is doing real work far faster than Babel, exactly as promised. So why did the full build not get faster? Because the compiler is a tiny sliver of a real build. On this app, the Babel compiler pass adds roughly four milliseconds of wall clock time to a 300ms build. That is barely one percent. The other 97 percent is bundling: Rolldown reading files, resolving the module graph, tree-shaking, minifying, writing output. Making one percent of the build 19x faster saves you about a millisecond. You will never feel a millisecond.

This is the trap with headline benchmark numbers. Transform speed is one slice of total build time. A giant win on a tiny slice is still a tiny win. The vendors are not lying; the 19x is real. It just lives in a place you do not spend your time.
Now, for Bun. Bun’s full build was 8.8x faster, 35ms against 306ms, and that is a big difference. But be careful with it. That number is not a clean compiler comparison. Bun is a completely different bundler that does JSX, TypeScript, the compiler pass, and bundling all in one native Rust binary. So the 8.8x is Bun’s whole toolchain being fast, not the React Compiler being fast. It tells you Bun is quick. It does not tell you the compiler is the reason.
One note on dev server startup and incremental builds. Startup was basically identical across the Vite pipelines, around 254ms each, because Vite transforms modules lazily on request and the compiler does not run at startup at all. And incremental production builds matched cold builds, because Vite re-bundles everything every time and does not cache transforms between production builds. So the word “incremental” is mostly aspirational here. That is a Vite behavior, not a compiler one.
Speed is worthless if the output is wrong. A compiler that is fast and breaks your app is not a fast compiler; it is a bug. So I checked whether the Rust port produces the same thing Babel does. It does. I diffed five representative components across all three pipelines: a memoized revenue card, the data table with sort and filter, a validated form, the sidebar, and a debounced search widget.
| Component | Babel cache slots | Oxc cache slots | Match |
|---|---|---|---|
| RevenueCard | 50 | 50 | Yes |
| DataTable | 118 | 118 | Yes |
| UserForm | 56 | 56 | Yes |
| Sidebar | 37 | 37 | Yes |
| SearchWidget | 28 | 28 | Yes |
Same number of cache slots, same maximum slot index, same compiled function shapes. Bun matched too. The RevenueCard used a 24-slot cache in all three.
The outputs are not byte-identical, and they should not be. Babel uses single quotes and two-space indents. Oxc uses double quotes and tabs, drops the now-unused useMemo import, and pulls in react/compiler-runtime explicitly. All of that is cosmetic. The memoization structure, the actual behavior, is the same. Same sentinel checks, same cache slot patterns, no behavioral differences.

Source maps were the thing I most expected to be broken, because the Oxc team specifically had to repair them during integration. They held up. Both Vite pipelines produced source maps with full source content for every TSX file, pointing back to the right original lines. One gap, though: Bun does not generate source maps by default with Bun.build, at least not in the config I tested. So if you debug against original source a lot, that is a real cost on the Bun path today.

Runtime behavior was clean everywhere. Tables sorted, forms validated, charts rendered, theme toggled, no console errors on any build. Nothing broke on the Rust path that worked on Babel. That is the sentence I most wanted to be able to write, and I can write it.
So, would I ship it today? The answer splits by which tool you are on.
If you are a Vite user on plugin-react 6.1, ship it. The switch is genuinely one line. You go from this:
- react({ babel: { plugins: ['babel-plugin-react-compiler'] } })
+ react({ compiler: true })
Plus one dev dependency. No source changes. The output is memoization-identical to Babel, source maps work, and I found no runtime regressions across a 178-component app. Rollback is trivial if you change your mind.
Just switch for the right reason. On a small or mid-size app, you are not switching for speed, because the build will not get faster and may get a hair slower. You are switching because the config is simpler, the output is identical, and you are lining yourself up for the version where this does matter. That version is coming. The Babel compiler pass grows with your component count, about 6ms per file. At 1,000 components, that is real seconds. At 5,000 it is around 30 seconds of pure compiler time, and the Oxc path would do that in under two. The crossover, where the 19x stops being invisible, is somewhere north of 1,000 components.
If you are a Bun user, look closer before you commit. The compiler works and produces correct output, and the build is dramatically faster. But the bundle came out 43 percent larger than the Vite output; there are no source maps by default, and the option has no TypeScript types yet, so you are writing @ts-expect-error to use it. Those are not compiler problems. They are a young bundler still catching up. If you already ship on Bun, turn it on. If you are thinking about migrating to Bun just for this, wait for the bundler to mature.
The React Compiler going native is the build-tooling story of the season, and it deserves the attention. But the headline number and the real experience are two different things. The 19x is real, and it is bigger than the 10x anybody promised. It also will not show up in your build until your app gets big, because bundling, not compiling, is what you are actually waiting on. That is not a disappointment. It is the honest shape of the win. Switch to Vite because it is free and safe. Watch Bun. And do not pick a build tool based on a benchmark that measures one percent of your build.
No. For Vite users on @vitejs/plugin-react 6.1 and up, it is a config change and one dev dependency: set react({ compiler: true }) and install oxc-transform-react. For Bun users, add reactCompiler: true to your Bun.build options. No source changes either way. The compiler reads your existing components and adds memoization automatically, and it works fine alongside useMemo, useCallback, and useContext you wrote by hand. I tested components with and without hand-memoization, and it handled both.
On Vite, yes, with one caveat. The memoization output is identical to the Babel compiler, which has been production-ready since React 19. Source maps work. I found no runtime regressions in a 178-component app.
Debugging Rust applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking the performance of your Rust apps, automatically surfacing errors, and tracking slow network requests and load time, try LogRocket.
LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.
LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.
Modernize how you debug your Rust apps — start monitoring for free.
Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not
server-side
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
// Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>

Compare the top AI development tools and models of September 2026. View updated rankings, feature breakdowns, and find the best fit for you.

Which Markdown library is right for your React docs site? We rebuilt the same documentation app using TanStack Markdown and react-markdown to compare bundle size, setup complexity, and performance.

Can a Rust toolkit speed up Node.js? We tested Nub’s script running, package management, and benchmarks to see how it compares to Bun and Deno.

Compare React Native Track Player and Expo Audio across background playback, lock-screen controls, queue management, licensing, and developer experience.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now