DEV Community

Ashraf
Ashraf

Posted on

The Rust React Compiler is now native in Vite — and it's 17 faster than Babel

The Rust React Compiler is now native in Vite — and it's 17× faster than Babel

The oxc project ported React Compiler to Rust and integrated it directly into the Vite build pipeline. No Babel round-trip. No intermediate AST conversion. Just compiler: true in your Vite config — and the compiler portion of your build drops from 14 seconds to under a second.

Here's why this matters, what actually changed, the remaining limitations, and how to switch today.

What the Rust React Compiler in Vite Actually Changes

React Compiler 1.0 shipped as a Babel plugin (babel-plugin-react-compiler). It worked, but every React project processed through Babel, adding 10–14 seconds of compile time per build and creating a gap between what the linter knew and what the build actually compiled.

Three things happened to change that:

  1. The React team open-sourced a Rust port of React Compiler. The oxc project took that port, cleaned it up, and vendored it into oxc for tighter integration.
  2. @vitejs/plugin-react v6.1.0 added experimental native React Compiler support. Pass { compiler: true } and Vite uses oxc-transform-react instead of the Babel plugin.
  3. Oxlint now includes 22 React Compiler-powered lint rules that catch violations of the Rules of React at lint time — using the same compiler passes your build uses.

The key architectural change: instead of converting Oxc's AST to Babel's AST, running the compiler, then converting back, React Compiler now operates directly on the Oxc AST. This eliminated the conversion overhead and memory allocations. The result is oxc's version is about twice as fast as the original Rust port — and more than 10× faster than Babel.

The Real Build Numbers

Andrew Patton switched his 1,036-file React Router codebase (Outlyne, a website builder) and published the results on Master.dev:

Metric Babel (React Compiler) Rust (oxc-transform-react) Speedup
Compiler portion 14.3s 0.81s 17.6×
Total build 22.1s 9.3s 2.4×

The compiler portion is where the dramatic win lives. Your total build time depends on what else you're doing (TypeScript checks, CSS processing, bundling), but the compiler step goes from ~14 seconds to negligible. For CI pipelines and developer iteration loops, that's meaningful.

How to Switch (Two Scenarios)

If you use @vitejs/plugin-react (standard Vite + React)

Before (Babel-based, current approach):

npm install -D @rolldown/plugin-babel babel-plugin-react-compiler
Enter fullscreen mode Exit fullscreen mode
// vite.config.js
import { defineConfig } from 'vite';
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
import babel from '@rolldown/plugin-babel';

export default defineConfig({
  plugins: [
    react(),
    babel({ presets: [reactCompilerPreset()] }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

After (native Rust React Compiler in Vite v8+):

npm install -D oxc-transform-react
npm uninstall @rolldown/plugin-babel babel-plugin-react-compiler
Enter fullscreen mode Exit fullscreen mode
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    react({ compiler: true }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

That's it. Three lines of config replaced by one option.

The compiler option also accepts a config object if you need custom compiler settings:

react({
  compiler: {
    // optional: pass through to oxc-transform-react
    panicOnUnoptimized: 'all',
  },
})
Enter fullscreen mode Exit fullscreen mode

If you use React Router in framework mode

You can't use @vitejs/plugin-react since React Router has its own Vite plugin. Instead, use @acusti/vite-plugin-react-compiler, a minimal standalone plugin from the community:

npm install -D @acusti/vite-plugin-react-compiler
npm uninstall vite-plugin-babel babel-plugin-react-compiler @babel/preset-typescript
Enter fullscreen mode Exit fullscreen mode
// vite.config.js
import { defineConfig } from 'vite';
import reactCompiler from '@acusti/vite-plugin-react-compiler';
import { reactRouter } from '@react-router/dev/vite';

export default defineConfig({
  plugins: [
    reactRouter(),
    reactCompiler(),
    // optional: reactCompiler({ compiler: { ... your config ... } })
  ],
});
Enter fullscreen mode Exit fullscreen mode

What Limitations Were Fixed

The Babel-based compiler had several patterns that would cause it to bail out (skip optimizing a component). The Rust port fixed three common ones:

Conditional logic in try/catch blocks — previously a hard blocker, now supported:

function Component() {
  try {
    // conditional logic here
  } catch (e) {
    // handled — compiler doesn't skip anymore
  }
}
Enter fullscreen mode Exit fullscreen mode

Reassigning a destructured prop — previously caused a bailout:

function Foo({ value }: { value: null | string }) {
  value = value ?? 'fallback';
  return <button onClick={() => console.log(value)}>{value}</button>;
}
Enter fullscreen mode Exit fullscreen mode

Computed object property keys — now properly handled:

function Header({ itemCount }: { itemCount: number }) {
  return (
    <header className={clsx({
      [`items-${itemCount}`]: itemCount > 0
    })}>
      {/* ... */}
    </header>
  );
}
Enter fullscreen mode Exit fullscreen mode

These fixes expanded compiler compatibility by an additional seven functions in Patton's codebase alone.

What Still Won't Compile

Two patterns still cause the compiler to skip a component or hook:

  • throw from inside a try block
  • Logical assignment operators (??=, &&=, ||=)

These are known gaps. But being on the Rust compiler means you'll get fixes when they land — unlike the Babel plugin, which is now a dead end for new features.

Why Toolchain Consistency Matters

Before this change, Oxlint's React Compiler rules and the build-time compiler could drift apart. You'd get lint passing but the build skipping compilation because of a version mismatch in compiler support.

Now Oxlint and oxc-transform-react use the exact same compiler passes. If lint flags something, the build will catch it too. If the compiler supports a pattern, lint won't give you a false positive. No coverage gaps.

Should You Switch Today?

Switch if:

  • You're on Vite v8+ and @vitejs/plugin-react v6.1.0+
  • The patterns listed under "What Still Won't Compile" don't affect you (check your codebase)
  • Your CI build times matter and you're currently using Babel-based React Compiler

Hold if:

  • You rely heavily on throw from try blocks in components or logical assignment operators
  • You're not yet on Vite v8 (the native integration requires it)
  • You're benchmarking against your specific codebase and the 17× compiler win doesn't translate to meaningful total build time savings

The Rust React Compiler in Vite is a genuine engineering improvement — simpler config, faster builds, consistent toolchain. The 17× compiler speedup is real for large codebases. Just verify your patterns are supported before pulling the trigger.


Sources: Master.dev — React Now Rusted All The Way Out, oxc.rs — React Compiler Support, @vitejs/plugin-react v6.1.0 release, HN discussion (113 pts). Performance numbers from Patton's 1,036-file codebase. oxc benchmark claims from oxc.rs blog.

Top comments (0)