После того как команда oxc выпустила официальную поддержку React Compiler на Rust 4 августа 2026 года, она перенесла кодовую базу React Router из 1036 файлов (Outlyne, конструктор сайтов) на новый компилятор и получила ускорение ~17,6× на этапе компиляции.
В релизе v6.1.0 плагина @vitejs/plugin-react появилась "экспериментальная поддержка нативного React Compiler". Включить её можно, передав { compiler: true } в конфигурацию Vite. Для тех, кто не может использовать плагин (например, при использовании React Router в режиме фреймворка), есть @acusti/vite-plugin-react-compiler — минимальный Vite-плагин для компиляции React независимо от остального конвейера сборки.
Быстрее собирается — разработчики довольнее, CI дешевле
Главное изменение — это скорость. По словам Босена, ведущего разработчика oxc:
Это более чем в 10 раз быстрее, чем Babel, согласно нашим предварительным тестам.
Результаты показали ускорение более чем в 17 раз: 1036 файлов компилировались за 14,3 с с Babel, а нативно — за 0,81 с (однопоточно). Для разработки это критично, потому что с быстрым изменением кода (особенно при AI-ассистентах) затраты на CI и GitHub Actions становятся существенными, а ожидание сборки отвлекает внимание.
Важно понимать: такое ускорение касается только компилятора. Во время сборки обычно запускается много других процессов, поэтому общее время собирания будет улучшено не так сильно. В данном случае вся сборка ускорилась в 2,4 раза (22,1 с → 9,3 с).
Но у React Compiler есть ограничения?
Хотя скорость — главное преимущество, большинство волнует другое: новая версия Rust-компилятора уже исправила существенные проблемы в поддержке JavaScript, которые были в v1.0 Babel-версии. Это включает поддержку условной логики в блоках try/catch — то, что было блокирующей проблемой для многих при релизе 1.0. Ещё одно полезное исправление, попавшее в код на прошлой неделе — поддержка переприсваивания деструктурированного пропса компоненты, который затем используется в вложенном замыкании:
export default function Foo({ value }: { value: null | string }) {
value = value ?? "this is a fallback";
return <button onClick={() => console.log(value)}>{value}</button>;
}
Раньше пропускалось, теперь поддерживается полностью. Третий распространённый паттерн, вызывавший отказы в Babel-компиляторе и теперь поддерживаемый — вычисляемые ключи свойств объекта:
import { clsx } from "clsx";
export default function Header({ itemCount }: { itemCount: number }) {
return (
<header className={clsx({ [`items-${itemCount}`]: itemCount > 0 })}>
{/* ... */}
</header>
);
}
Благодаря этим исправлениям совместимость компилятора в приложении расширилась на семь функций: пять благодаря улучшению try/catch, две — благодаря поддержке вычисляемых ключей. Конечно, ограничения остаются. Две конструкции, которые всё ещё заставляют компилятор пропускать компоненты и хуки — это throw из блока try и операторы логического присваивания (??=, &&=, ||=). Но переход на Rust-компилятор гарантирует, что исправления будут получены сразу же, когда они выйдут. С мёртвым Babel-компилятором такого не будет.
Единая версия в toolchain — никаких пробелов в покрытии
Последняя причина для переезда — полный toolchain теперь использует одну и ту же версию React Compiler с одинаковой поддержкой функций. После того как линтер Oxlint получил поддержку React Compiler, но сборка всё ещё использовала более старую версию, был подан некорректный баг-репорт в oxc: компонента не оптимизировалась во время сборки, но и ошибок линтера не было, поэтому казалось, что есть рассинхрон. Оказалось, что Oxlint использовал oxc-transform-react v0.145.0 (поддерживает нужный паттерн), а сборка — v0.144.0.
Теперь линтер и сборка используют один React Compiler с одинаковыми улучшениями и ограничениями, поэтому не нужно беспокоиться, что некомпилированные компоненты попадут в production.
Как использовать
С @vitejs/plugin-react
Если используется Vite v8+, переключение на нативный React Compiler — это просто упрощение конфигурации. Текущие инструкции на react.dev для Babel указывают запустить:
npm install -D @rolldown/plugin-babel
С такой конфигурацией Vite:
// 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()] })],
});
При переходе на нативный вариант можно избавиться от лишней конфигурации. Выполните:
npm install -D oxc-transform-react
И упростите конфигурацию Vite:
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react({ compiler: true })],
});
Также можно удалить @rolldown/plugin-babel из dev-зависимостей в package.json.
Без @vitejs/plugin-react (например, React Router в режиме фреймворка)
Для кодовых баз на React Router в режиме фреймворка переключение немного отличается. React Router имеет собственный Vite-плагин, который должен использоваться вместо стандартного, поэтому раньше нужно было запустить:
npm install -D vite-plugin-babel babel-plugin-react-compiler @babel/preset-typescript
С такой конфигурацией:
// vite.config.js
import { defineConfig } from "vite";
import babel from "vite-plugin-babel";
import { reactRouter } from "@react-router/dev/vite";
const ReactCompilerConfig = {
/* optional config if you have it */
};
export default defineConfig({
plugins: [
reactRouter(),
babel({
babelConfig: {
presets: ["@babel/preset-typescript"], // if you use TypeScript
plugins: [["babel-plugin-react-compiler", ReactCompilerConfig]],
},
exclude: /node_modules/,
include: /\.[jt]sx?$/,
}),
],
});
Теперь можно полностью отказаться от vite-plugin-babel, babel-plugin-react-compiler и @babel/preset-typescript, установив только:
npm install -D @acusti/vite-plugin-react-compiler
И упростить конфигурацию:
// 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()],
// или, если нужно передать кастомную конфигурацию компилятора:
// reactCompiler({ compiler: { /* your existing ReactCompilerConfig */ } })
});
Проще, быстрее и мощнее. За такое есть что отметить.