🕮5 min read · 999 words
Meta just merged something significant into the React repository: a complete Rust rewrite of the React Compiler. Not an experiment in a separate branch — merged into the main React monorepo, shipping in Next.js 16.3, and already delivering 20–50% faster builds in real applications.
If you’ve been watching the frontend toolchain shift toward Rust over the past two years — SWC replacing Babel, Turbopack replacing webpack, Biome replacing ESLint — this is the next piece of that picture snapping into place.
What the React Compiler Actually Does
Before getting into the Rust rewrite, a quick refresher on what the React Compiler is.
React Compiler (formerly called React Forget) automatically memoizes your components and hooks. In plain English: it makes React smarter about when to re-render components, without you having to manually sprinkle useMemo and useCallback everywhere.
// Before React Compiler — you manually memoize
function ExpensiveComponent({ data, filter }) {
const filtered = useMemo(
() => data.filter(item => item.category === filter),
[data, filter]
);
const handleClick = useCallback(() => {
console.log(filtered);
}, [filtered]);
return <List items={filtered} onSelect={handleClick} />;
}
// With React Compiler — the compiler handles this automatically
function ExpensiveComponent({ data, filter }) {
const filtered = data.filter(item => item.category === filter);
const handleClick = () => {
console.log(filtered);
};
return <List items={filtered} onSelect={handleClick} />;
}
The compiler analyzes your code and inserts the memoization automatically at build time. Your code is cleaner. Runtime performance is the same or better. You stop writing useMemo by instinct.
Why Rewrite It in Rust?
The original React Compiler was written in TypeScript. This made sense for developer familiarity and iteration speed — the React team could ship and iterate quickly.
But TypeScript compilers run on Node.js, and Node.js has overhead that Rust doesn’t. As the React Compiler integrated deeper into the build pipeline — running on every file, every build, in watch mode — that overhead became a real cost.
The Rust rewrite has a specific technical advantage beyond raw speed: it can be linked directly into Turbopack (Vercel’s Rust-based bundler) without going through a serialization boundary. Previously, running the compiler as a Babel plugin meant data had to cross from JavaScript into the plugin and back — adding overhead on every file transformation. The Rust version eliminates this entirely.
The Numbers
Performance improvements from the Rust port:
| Scenario | Improvement |
|---|---|
| As a Babel plugin drop-in | ~3x faster than TypeScript version |
| Isolated transformation logic | Up to 10x faster |
| Integrated with Turbopack (v0 app) | >40% faster compilation |
| Next.js 16.3 test apps | 20–50% faster route compilation |
All 1,725 test fixtures pass. Intermediate states match the TypeScript version almost byte for byte. The migration isn’t just fast — it’s correct.
What Changed, What Didn’t
What changed: The internals. The compiler is now rebuilt with arena allocation and index-based data structures — Rust memory patterns that avoid the garbage collection overhead of JavaScript runtimes.
What didn’t change: The public API. The configuration is identical. Upgrading is intended to be a drop-in swap.
// vite.config.ts — same config, faster compiler
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react({
babel: {
plugins: [
['babel-plugin-react-compiler', {
target: '19', // same as before
}],
],
},
}),
],
});
Using the React Compiler Today
With Next.js (Experimental in 16.3)
// next.config.ts
import type { NextConfig } from 'next';
const config: NextConfig = {
experimental: {
reactCompiler: true,
},
};
export default config;
With Vite + React
npm install babel-plugin-react-compiler
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react({
babel: {
plugins: ['babel-plugin-react-compiler'],
},
}),
],
});
Incremental Adoption
If your codebase has components that aren’t compiler-compatible (those that violate React’s rules), you can enable the compiler selectively:
// Opt out a specific file
// @ts-nocheck
'use no memo'; // Tells React Compiler to skip this file
// Or configure globally with an allowlist
// next.config.ts
const config: NextConfig = {
experimental: {
reactCompiler: {
compilationMode: 'annotation', // Only compile annotated components
},
},
};
// Then in components you want compiled:
// 'use memo'; // Opt this component in
The Bigger Picture — Rust Is Eating the Frontend Toolchain
This isn’t an isolated event. It’s part of a deliberate shift across the entire JavaScript toolchain toward Rust:
| Tool | JavaScript Version | Rust Replacement |
|---|---|---|
| Transpiler | Babel | SWC ✅ (widely deployed) |
| Bundler | Webpack | Turbopack ✅ (Next.js), Rolldown (Vite) |
| Linter/Formatter | ESLint + Prettier | Biome ✅ (growing fast) |
| React Compiler | TypeScript | Rust ✅ (just merged) |
| Type Checker | tsc | ts-go (Microsoft, in progress) |
| Package Manager | npm | bun ✅, cargo (for WASM targets) |
The pattern is consistent: JavaScript tooling works, then gets rewritten in Rust when it becomes a bottleneck. The React Compiler joining this list is a signal that build performance is now a first-class concern, not an afterthought.
The Legitimate Concern
The InfoQ report noted a fair criticism from the developer community: this rewrite leaned heavily on LLMs for the mechanical porting work. Humans handled architecture and review, but the bulk of the code was AI-generated.
One Hacker News commenter raised the obvious question: if no human deeply understands the implementation, what happens when it breaks in a subtle way?
This is a genuine concern. Rust that compiles doesn’t mean Rust that’s well-written — a model can satisfy the borrow checker with RefCell and push failures to runtime. Whether this specific codebase has those problems is unknown until it gets production load and edge case exposure.
The 1,725 passing tests are reassuring. Production use over the next 6 months will tell the real story.
What This Means for Laravel + React Developers
Practically — if you’re building React frontends with Laravel and Vite:
- Enable the React Compiler now if you’re not already. Even the TypeScript version is stable and removes the need for manual memoization.
- When the Rust version stabilizes as a non-experimental feature in Vite/Next.js, upgrade — it’s a config change, not a code change.
- If you’re using Next.js 16.3+, experimental Turbopack + React Compiler integration gives you the full performance stack.
- Stop writing
useMemoanduseCallbackby instinct — the compiler handles this better than manual annotation.
The build time improvements are real and compound over a large codebase. A 40% faster build means your developers spend less time waiting and more time writing code. For teams doing continuous integration, it also means cheaper CI bills.
If you’re setting up a new React project or optimizing an existing build pipeline, our frontend team at Softcrony can help you configure the right toolchain.
Leave a comment