PR #36173 был объединён 10 июня — 435 коммитов, переписывающих React Compiler с TypeScript на Rust. Большая часть кода написана искусственным интеллектом. Все 1 725 тестов проходят. Полный анализ.
10 июня 2026 года Джозеф Савона — один из ключевых разработчиков React в Meta — объединил PR #36173 в основной репозиторий React. Этот pull request представляет одно из самых значительных изменений в инструментарии React: полный порт React Compiler с TypeScript на Rust.
React Compiler (ранее известный как React Forget) — это инструмент автоматической мемоизации,
устраняющий необходимость в ручных useMemo, useCallback и
React.memo. Если вы не знакомы с его использованием, я подробно описал это в
руководстве по React Compiler для React 19.2 —
эта статья посвящена именно порту на Rust: зачем это было сделано, как устроена архитектура,
какие достигнуты улучшения производительности и что это значит для экосистемы React.
Большинство из 435 коммитов были созданы AI. Люди определяли архитектуру и проверяли результат. Это одна из крупнейших реальных демонстраций AI-ассистированного рефакторинга в инфраструктурном программном обеспечении — полный перевод с TS на Rust боевого компилятора с арена-аллокацией, тремя точками интеграции и покаскадным сравнением IR. Последствия для того, как мы подходим к переписыванию фреймворков, значительны.
TypeScript-реализация React Compiler хорошо работала для небольших кодовых баз, но по мере того как компилятор анализировал всё более крупные деревья компонентов, накладные расходы сборщика мусора JavaScript становились ощутимыми. Компилятор выполняет сложный статический анализ — строит промежуточные представления, графы потоков управления и SSA-форму, что создаёт и уничтожает множество короткоживущих объектов во время компиляции.
В JavaScript такой паттерн аллокации создаёт нагрузку на сборщик мусора. Даже с оптимизированным поколенческим GC от V8, TypeScript-версия компилятора демонстрировала всплески задержек на больших файлах. Rust-порт решает это с помощью арена-аллокации — паттерна, при котором объекты размещаются в смежных областях памяти и освобождаются все сразу при удалении арены.
Ключевое архитектурное различие между TypeScript и Rust версиями — стратегия управления памятью. TypeScript-версия использовала JavaScript-объекты и массивы для внутренних структур (HIR-узлы, базовые блоки, SSA-переменные). Rust-версия заменяет их арена-аллокаторами:
// TypeScript-версия: индивидуальные heap-аллокации
interface BasicBlock {
id: number;
statements: Statement[];
predecessors: number[];
successors: number[];
}
// Rust-версия: арена-аллоцированные
struct BasicBlock {
id: u32,
statements: ArenaVec<Statement>,
predecessors: SmallVec<[u32; 4]>,
successors: SmallVec<[u32; 4]>,
}
struct FunctionArena {
blocks: Arena<BasicBlock>,
statements: ArenaVecStore<Statement>,
// ... все аллокации для функции
}
impl Drop for FunctionArena {
fn drop(&mut self) {
// Вся память освобождается разом — никакого показного GC
}
}
Разница кардинальная. В TypeScript-версии компиляция большой компонентной функции создаёт тысячи отдельных heap-аллокаций — каждая отслеживается GC. В Rust-версии все промежуточные данные для функции живут в одной арене, которая освобождается атомарно после полной обработки функции. Никаких накладных расходов GC, никаких всплесков задержек.
Rust-порт не меняет архитектуру компилятора. Он сохраняет тот же конвейер, что и TypeScript-версия:
Все 1 725 тестовых сценариев проходят — и тестовый набор особенно тщателен: он проверяет не только финальный вывод, но и промежуточное состояние IR после каждого прохода компилятора. Это означает, что корректность проверяется на каждом этапе конвейера, а не только в конце.
Одно из важных архитектурных решений — порт поставляется с тремя интеграционными целями, что даёт гибкость разработчикам и авторам фреймворков:
Babel-плагин вызывает Rust-бинарник через FFI (Foreign Function Interface). С точки зрения пользователя ничего не меняется — вы добавляете тот же Babel-плагин в конфиг. Под капотом плагин компилирует JS-файл, передавая его Rust-компилятору, который обрабатывает AST напрямую. Эта интеграция в 3 раза быстрее чистой TypeScript-версии.
OXC — это Rust-парсер и инструментарий от VoidZero (команды, создавшей Vite). React Compiler теперь может работать напрямую с AST OXC без всякого JavaScript-взаимодействия. Для проектов, уже использующих OXC (доступен через Rolldown и будущие версии Vite), это устраняет накладные расходы на сериализацию — парсер и компилятор работают в одном адресном пространстве.
SWC — ещё один компилятор на Rust, широко используемый в Next.js и других фреймворках. React Compiler может потреблять распарсенный AST от SWC и выдавать оптимизированный результат. Это делает компилятор доступным для всей экосистемы SWC без дополнительных затрат на JavaScript-мосты.
Подход с тремя целями стратегически важен. Он означает, что React Compiler не привязан к одному инструменту сборки — он работает в Babel-проектах (большинство существующих React-приложений), OXC-проектах (будущее экосистемы Vite) и SWC-проектах (Next.js, Turbopack). Это ставка на экосистемную нейтральность.
Ключевые цифры впечатляют, но давайте разберём, что они означают на практике:
Тот факт, что большинство из 435 коммитов были написаны AI (с архитектурным руководством людей), заслуживает отдельного анализа. Это не игрушечный пример — это боевой компилятор, работающий в тысячах сборочных конвейеров, обрабатывающий миллионы строк React-кода ежедневно.
Процесс работы, согласно описанию PR, выглядел так:
Это шаблон, который, вероятно, будет повторён во всей экосистеме JavaScript. Если сложный компилятор можно портировать с TypeScript на Rust с помощью AI за несколько недель, то многие другие инструменты могут пойти тем же путём. Поглощение VoidZero компанией Cloudflare (которое я описал в моём анализе VoidZero) — часть того же тренда: экосистема инструментов JavaScript активно стремится к нативной производительности.
Rust-порт завершает более широкий тренд в инструментарии React и JavaScript. Давайте соединим точки:
Инструменты, обеспечивающие современную React-разработку:
Все основные узкие места производительности в стеке React переписываются на Rust. React Compiler был последним значительным TypeScript-инструментом — и теперь он тоже на Rust.
Важно подчеркнуть, что не меняется:
useMemo и useCallback продолжают работать и имеют приоритетДля полного понимания использования React Compiler (TypeScript или Rust) смотрите моё руководство по React 19.2 с примерами кода и стратегиями миграции.
Rust-порт React Compiler открывает несколько интересных возможностей:
С присоединением VoidZero к Cloudflare (и OXC как их основным парсером) интеграция React Compiler с OXC может стать стандартной для новых проектов. Сочетание Rust-парсера OXC + Rust-компилятора исключает все накладные расходы на JavaScript-взаимодействие.
Next.js уже использует SWC для компиляции. Интеграция со SWC означает, что React Compiler может быть встроен непосредственно в сборочный конвейер Next.js без отдельного Babel-шага.
Экосистема React развивается стремительно — от порта компилятора на Rust до присоединения VoidZero к Cloudflare и расширения Rust-инструментария. Навигация в этих изменениях требует разработчика, который следит за экосистемой и понимает, как выбирать правильные инструменты для вашего проекта.
Я — full-stack веб-разработчик с 20+ годами опыта создания продакшен-приложений на React. Если вы начинаете новый проект, мигрируете существующую кодовую базу или нуждаетесь в консультации по внедрению React Compiler — я с радостью помогу. Свяжитесь со мной для бесплатной консультации.
Также я пишу технические статьи об инструментах и фреймворках, которые имеют значение — следите за моими статьями о последних новинках веб-разработки.
Нужен React-разработчик, который следит за экосистемой? Расскажите о проекте — я дам честную оценку и предварительную смету. Бесплатно.