Как мы пересобрали Next.js на Vite за неделю с помощью ИИ: скорость выросла в 4 раза

На прошлой неделе один инженер и ИИ-модель с нуля пересобрали самый популярный фронтенд-фреймворк. Результат — vinext (произносится «ви-некст»), прямая замена для Next.js, построенная на Vite, которая разворачивается на Cloudflare Workers одной командой. Согласно первым тестам, он собирает продакшен-приложения до 4 раз быстрее, а клиентские бандлы получаются до 57% меньше. И у нас уже есть клиенты, использующие его в продакшене.

Вся эта работа обошлась примерно в 1100 долларов за токены.

Проблема с деплоем Next.js

Next.js — самый популярный React-фреймворк. Его используют миллионы разработчиков. На нём работает огромная часть веба в продакшене, и не зря. Опыт разработчика на высшем уровне.

Но у Next.js есть проблемы с развёртыванием в более широкой бессерверной экосистеме. Инструментарий полностью уникален: Next.js много инвестировал в Turbopack, но если вы хотите задеплоить его на Cloudflare, Netlify или AWS Lambda, вам нужно взять результат сборки и преобразовать его во что-то, что целевая платформа действительно может запустить.

Если вы думаете: «Разве не это делает OpenNext?», вы правы.

Именно эту проблему и был призван решить OpenNext. И в OpenNext было вложено много инженерных усилий от разных поставщиков, включая нас в Cloudflare. Он работает, но быстро упирается в ограничения и превращается в игру «бей крота».

Строительство поверх вывода Next.js как основы оказалось сложным и ненадёжным подходом. Поскольку OpenNext приходится реверс-инжинирить результат сборки Next.js, это приводит к непредсказуемым изменениям между версиями, на исправление которых уходит много работы.

Next.js работал над API адаптеров первого класса, и мы сотрудничали с ними в этом направлении. Это всё ещё ранняя стадия, но даже с адаптерами вы всё равно строите на уникальном инструментарии Turbopack. И адаптеры покрывают только сборку и развёртывание. Во время разработки `next dev` работает исключительно в Node.js без возможности подключить другую среду выполнения. Если ваше приложение использует специфичные для платформы API, такие как Durable Objects, KV или AI-биндинги, вы не можете протестировать этот код в режиме разработки без обходных путей.

Представляем vinext

How we rebuilt Next.js with AI in one week

Что, если вместо адаптации вывода Next.js мы заново реализуем API Next.js напрямую на Vite? Vite — это инструмент сборки, используемый большей частью фронтенд-экосистемы за пределами Next.js, он лежит в основе таких фреймворков, как Astro, SvelteKit, Nuxt и Remix. Чистая повторная реализация, а не просто обёртка или адаптер. Честно говоря, мы не думали, что это сработает. Но на дворе 2026 год, и стоимость создания программного обеспечения полностью изменилась.

Мы продвинулись гораздо дальше, чем ожидали.

npm install vinext

Замените next на vinext в ваших скриптах, и всё остальное останется без изменений. Ваши существующие app/, pages/ и next.config.js работают как есть.

vinext dev          # Сервер для разработки с HMR
vinext build        # Продакшен-сборка
vinext deploy       # Собрать и задеплоить на Cloudflare Workers

Это не обёртка вокруг вывода Next.js и Turbopack. Это альтернативная реализация API: маршрутизация, серверный рендеринг, React Server Components, серверные действия, кэширование, промежуточное ПО. Всё это построено поверх Vite в виде плагина. Что самое важное, вывод Vite работает на любой платформе благодаря API среды Vite.

Цифры

Первые тесты обнадёживают. Мы сравнили vinext с Next.js 16, используя общее приложение на App Router с 33 маршрутами. Оба фреймворка выполняют одну и ту же работу: компиляцию, сборку и подготовку серверно-рендеренных маршрутов. Мы отключили проверку типов TypeScript и ESLint в сборке Next.js (Vite не запускает их во время сборки) и использовали `force-dynamic`, чтобы Next.js не тратил дополнительное время на предварительный рендеринг статических маршрутов, что несправедливо ухудшило бы его показатели. Целью было измерить только скорость сборщика и компиляции, и ничего более. Тесты запускались на GitHub CI при каждом слиянии с основной веткой.

Время продакшен-сборки:

Фреймворк Среднее В сравнении с Next.js
Next.js 16.1.6 (Turbopack) 7.38с базовый уровень
vinext (Vite 7 / Rollup) 4.64с в 1.6 раза быстрее
vinext (Vite 8 / Rolldown) 1.67с в 4.4 раза быстрее

Размер клиентского бандла (gzipped):

Фреймворк Gzipped В сравнении с Next.js
Next.js 16.1.6 168.9 КБ базовый уровень
vinext (Rollup) 74.0 КБ на 56% меньше
vinext (Rolldown) 72.9 КБ на 57% меньше

Эти тесты измеряют скорость компиляции и сборки, а не производительность в продакшене. Тестовый пример — одно приложение с 33 маршрутами, а не репрезентативная выборка всех продакшен-приложений. Мы ожидаем, что эти цифры будут меняться по мере развития всех трёх проектов. Полная методология и исторические результаты публичны. Воспринимайте их как ориентир, а не как окончательные.

Тем не менее, тенденция обнадёживает. Архитектура Vite, и особенно Rolldown (сборщик на Rust, который появится в Vite 8), имеет структурные преимущества для производительности сборки, которые здесь чётко видны.

Развёртывание на Cloudflare Workers

vinext создавался с Cloudflare Workers в качестве первой цели для развёртывания. Одна команда переводит вас от исходного кода до работающего Worker:

vinext deploy

Это обрабатывает всё: собирает приложение, автоматически генерирует конфигурацию Worker и выполняет развёртывание. И App Router, и Pages Router работают на Workers с полной гидратацией на стороне клиента, интерактивными компонентами, клиентской навигацией, состоянием React.

Для продакшен-кэширования vinext включает обработчик кэша Cloudflare KV, который предоставляет ISR (инкрементальную статическую регенерацию) из коробки:

import { KVCacheHandler } from "vinext/cloudflare";
import { setCacheHandler } from "next/cache";

setCacheHandler(new KVCacheHandler(env.MY_KV_NAMESPACE));

KV — хороший вариант по умолчанию для большинства приложений, но уровень кэширования спроектирован как заменяемый. Вызов `setCacheHandler` означает, что вы можете подставить любую подходящую бэкенд-систему. R2 может лучше подойти для приложений с большими кэшируемыми данными или разными шаблонами доступа. Мы также работаем над улучшениями нашего Cache API, который должен предоставить мощный уровень кэширования с меньшим количеством настроек. Цель — гибкость: выбирайте стратегию кэширования, которая подходит вашему приложению.

Живые примеры, работающие прямо сейчас:

  • Песочница App Router

  • Клон Hacker News

  • Минимальное приложение на App Router

  • Минимальное приложение на Pages Router

У нас также есть живой пример работы Cloudflare Agents в приложении Next.js без необходимости в обходных путях, таких как getPlatformProxy, поскольку всё приложение теперь запускается в workerd как на этапе разработки, так и на этапе развёртывания. Это означает возможность использовать Durable Objects, AI-биндинги и все другие специфичные для Cloudflare сервисы без компромиссов. Посмотрите здесь.

Фреймворки — это командный вид спорта

Текущая цель развёртывания — Cloudflare Workers, но это лишь малая часть картины. Около 95% vinext — это чистый Vite. Маршрутизация, модульные заглушки, конвейер SSR, интеграция RSC: ничто из этого не является специфичным для Cloudflare.

Cloudflare планирует сотрудничать с другими хостинг-провайдерами по внедрению этого инструментария для их клиентов (усилия минимальны — мы запустили рабочее доказательство концепции на Vercel менее чем за 30 минут!). Это проект с открытым исходным кодом, и для его долгосрочного успеха мы считаем важным работать с партнёрами по всей экосистеме, чтобы обеспечить постоянные инвестиции. PR с других платформ приветствуются. Если вы заинтересованы в добавлении цели развёртывания, создайте issue или свяжитесь с нами.

Статус: Экспериментальный

Мы хотим внести ясность: vinext — экспериментальный проект. Ему нет и недели, и он ещё не прошел проверку каким-либо значительным трафиком в масштабе. Если вы оцениваете его для производственного приложения, действуйте с соответствующей осторожностью.

Тем не менее, набор тестов обширен: более 1700 тестов Vitest и 380 сквозных (E2E) тестов Playwright, включая тесты, напрямую портированные из тестового набора Next.js и набора на соответствие Cloudflare от OpenNext. Мы проверили его на примере App Router Playground от Next.js. Покрытие составляет 94% поверхности API Next.js 16. Ранние результаты от реальных клиентов обнадёживают. Мы работали с National Design Studio, командой, которая стремится модернизировать каждый государственный интерфейс, над одним из их бета-сайтов, CIO.gov. Они уже используют vinext в production, с заметным улучшением времени сборки и размеров бандлов.

В файле README честно указано, что не поддерживается и поддерживаться не будет, а также известные ограничения. Мы хотим быть откровенными, а не давать пустых обещаний.

А как насчёт предварительной отрисовки?

vinext уже из коробки поддерживает инкрементальную статическую регенерацию (ISR). После первого запроса к любой странице она кэшируется и обновляется в фоновом режиме, как в Next.js. Эта часть уже работает.

vinext пока не поддерживает статическую предварительную отрисовку на этапе сборки. В Next.js страницы без динамических данных отрисовываются во время next build и отдаются как статический HTML. Если у вас динамические маршруты, вы используете generateStaticParams() для перечисления страниц, которые нужно собрать заранее. vinext этого пока не делает…

Это было осознанное дизайнерское решение для запуска. Это есть в планах, но если ваш сайт на 100% состоит из предварительно собранного HTML со статическим контентом, вы, вероятно, не увидите большой пользы от vinext сегодня. Тем не менее, если один инженер может потратить $1100 на токены и пересобрать Next.js, вы, вероятно, можете потратить $10 и перейти на фреймворк на основе Vite, созданный специально для статического контента, такой как Astro (который также развёртывается на Cloudflare Workers).

Однако для сайтов, которые не являются чисто статическими, мы думаем, что можем предложить нечто лучшее, чем предварительная отрисовка всего на этапе сборки.

Представляем предварительную отрисовку с учётом трафика

Next.js предварительно отрисовывает каждую страницу, указанную в generateStaticParams(), во время сборки. Сайт с 10 000 страницами товаров означает 10 000 отрисовок во время сборки, даже если 99% этих страниц никогда не получат запроса. Сборки масштабируются линейно с количеством страниц. Вот почему у больших сайтов на Next.js сборка может занимать 30 минут.

Поэтому мы создали предварительную отрисовку с учётом трафика (TPR). На данный момент это экспериментальная функция, и мы планируем сделать её по умолчанию, когда проведём больше тестов в реальных условиях.

Идея проста. Cloudflare уже является обратным прокси для вашего сайта. У нас есть данные о вашем трафике. Мы знаем, какие страницы действительно посещаются. Поэтому вместо того, чтобы предварительно отрисовывать всё или ничего, vinext запрашивает аналитику зоны Cloudflare во время развёртывания и предварительно отрисовывает только те страницы, которые имеют значение.

vinext deploy --experimental-tpr

  Сборка...
  Сборка завершена (4.2с)

  TPR (экспериментально): Анализ трафика для my-store.com (последние 24ч)
  TPR: 12 847 уникальных путей — 184 страницы покрывают 90% трафика
  TPR: Предварительная отрисовка 184 страниц...
  TPR: 184 страницы предварительно отрисованы за 8.3с → KV-кэш

  Развёртывание на Cloudflare Workers...

Для сайта со 100 000 страницами товаров степенной закон означает, что 90% трафика обычно приходится на 50–200 страниц. Они предварительно отрисовываются за секунды. Всё остальное откатывается к SSR по запросу и кэшируется через ISR после первого запроса. Каждое новое развёртывание обновляет набор на основе текущих шаблонов трафика. Страницы, которые становятся вирусными, подхватываются автоматически. Всё это работает без generateStaticParams() и без привязки вашей сборки к производственной базе данных.

Принимаем вызов Next.js, но на этот раз с ИИ

Проект такого уровня обычно занимает у команды инженеров месяцы, если не годы. Несколько команд в различных компаниях пытались это сделать, и объём работ просто колоссальный. Мы тоже пытались в Cloudflare! Два роутера, 33+ шимов модулей, конвейеры серверного рендеринга, потоковая передача RSC, файловая система маршрутизации, промежуточное ПО, кэширование, статический экспорт. Есть причина, по которой ни у кого не получилось.

На этот раз мы сделали это меньше чем за неделю. Один инженер (формально менеджер по разработке) руководил ИИ.

Первый коммит был добавлен 13 февраля. К концу того же вечера и Pages Router, и App Router уже имели базовый рабочий SSR, а также middleware, server actions и streaming. К следующему полудню App Router Playground отрисовывал 10 из 11 маршрутов. К третьему дню vinext deploy уже разворачивал приложения на Cloudflare Workers с полной гидратацией на клиенте. Остаток недели ушёл на укрепление: исправление краевых случаев, расширение набора тестов, доведение покрытия API до 94%.

Что изменилось по сравнению с предыдущими попытками? ИИ стал лучше. Намного лучше.

Почему эта проблема идеально подходит для ИИ

Не каждый проект пошёл бы таким путём. Этот удался, потому что несколько вещей сошлись в нужное время.

Next.js хорошо специфицирован. У него обширная документация, огромная пользовательская база и годы ответов на Stack Overflow и руководств. Поверхность API полностью представлена в обучающих данных. Когда вы просите Claude реализовать getServerSideProps или объяснить, как работает useRouter, он не галлюцинирует. Он знает, как работает Next.

У Next.js сложный набор тестов. Репозиторий Next.js содержит тысячи сквозных (E2E) тестов, охватывающих каждую функцию и краевой случай. Мы портировали тесты напрямую из их набора (авторство можно увидеть в коде). Это дало нам спецификацию, которую можно было механически проверять.

Vite — отличный фундамент. Vite решает сложные части фронтенд-инструментария: быстрый HMR, нативный ESM, чистый API плагинов, продакшен-бандлинг. Нам не пришлось создавать бандлер. Нам просто нужно было научить его говорить на языке Next.js. @vitejs/plugin-rsc всё ещё на ранней стадии, но он дал нам поддержку React Server Components, без необходимости создавать реализацию RSC с нуля.

Модели догнали. Мы не думаем, что это было бы возможно даже несколько месяцев назад. Ранние модели не могли поддерживать согласованность в кодовой базе такого размера. Новые модели могут удерживать полную архитектуру в контексте, рассуждать о взаимодействии модулей и достаточно часто выдавать правильный код, чтобы сохранять динамику. Иногда я видел, как она углублялась во внутренности Next, Vite и React, чтобы понять ошибку. Современные модели впечатляют, и, кажется, они продолжают становиться лучше.

Все эти условия должны были быть выполнены одновременно: хорошо задокументированный целевой API, комплексный набор тестов, надёжный инструмент сборки под капотом и модель, которая действительно могла справиться со сложностью. Уберите что-то одно — и это не сработает так же хорошо.

Как мы на самом деле это построили

Почти каждая строка кода в vinext была написана ИИ. Но вот что важнее: каждая строка проходит те же контрольные точки качества, которых вы ожидаете от кода, написанного человеком. В проекте более 1700 тестов Vitest, 380 сквозных (E2E) тестов Playwright, полная проверка типов TypeScript через tsgo и линтинг через oxlint. Непрерывная интеграция запускает всё это на каждый pull request. Установка набора надёжных ограничений критически важна для повышения продуктивности ИИ в кодовой базе.

Процесс начался с плана. Я потратил пару часов на обсуждение с Claude в OpenCode, чтобы определить архитектуру: что строить, в каком порядке, какие абстракции использовать. Этот план стал путеводной звездой. С этого момента рабочий процесс был прост:

  1. Определить задачу («реализовать шим next/navigation с usePathname, useSearchParams, useRouter»).

  2. Позволить ИИ написать реализацию и тесты.

  3. Запустить набор тестов.

  4. Если тесты проходят — слить. Если нет — передать ИИ вывод об ошибке и позволить ему итерировать.

  5. Повторить.

Мы также подключили AI-агентов для код-ревью. Когда открывался PR, агент проверял его. Когда возвращались комментарии ревью, другой агент их обрабатывал. Цикл обратной связи был в основном автоматизирован.

Это не всегда работало идеально. Были PR, которые были просто ошибочными. AI уверенно реализовывал что-то, что казалось правильным, но не соответствовало фактическому поведению Next.js. Мне регулярно приходилось корректировать курс. Архитектурные решения, расстановка приоритетов, понимание, когда AI заходил в тупик: всё это лежало на мне. Когда вы даёте AI хорошее направление, хороший контекст и хорошие ограничения, он может быть очень продуктивным. Но человек всё равно должен управлять.

Для тестирования на уровне браузера я использовал agent-browser для проверки фактического отображаемого вывода, клиентской навигации и поведения гидратации. Модульные тесты упускают множество тонких проблем браузера. Этот инструмент их выявлял.

В ходе проекта мы провели более 800 сессий в OpenCode. Общая стоимость: примерно $1,100 в токенах API Claude.

Что это значит для программного обеспечения

Почему у нас так много слоёв в стеке? Этот проект заставил меня глубоко задуматься над этим вопросом. И рассмотреть, как AI влияет на ответ.

Большинство абстракций в программном обеспечении существуют потому, что людям нужна помощь. Мы не могли удержать всю систему в голове, поэтому мы строили слои, чтобы управлять сложностью за нас. Каждый слой облегчал работу следующему человеку. Вот как получаются фреймворки поверх фреймворков, библиотеки-обёртки, тысячи строк связующего кода.

AI не имеет таких же ограничений. Он может удерживать всю систему в контексте и просто писать код. Ему не нужен промежуточный фреймворк для организации. Ему нужна только спецификация и основа для построения.

Пока не ясно, какие абстракции действительно фундаментальны, а какие были лишь костылями для человеческого познания. Эта граница будет сильно смещаться в ближайшие годы. Но vinext — это точка данных. Мы взяли API-контракт, инструмент сборки и AI-модель, и AI написал всё остальное. Промежуточный фреймворк не понадобился. Мы считаем, что этот паттерн повторится во множестве программ. Слои, которые мы построили за годы, не все сохранятся.

Благодарности

Спасибо команде Vite. Vite — это основа, на которой всё стоит. @vitejs/plugin-rsc ещё на ранней стадии, но это дало мне поддержку RSC без необходимости строить её с нуля, что было бы препятствием. Сопровождающие Vite были отзывчивы и полезны, когда я продвигал плагин в области, где он раньше не тестировался.

Мы также хотим отметить команду Next.js. Они потратили годы на создание фреймворка, который поднял планку того, как может выглядеть разработка на React. То, что их API так хорошо документирован, а набор тестов так всеобъемлющ, во многом сделало этот проект возможным. vinext не существовал бы без стандарта, который они установили.

Попробуйте

vinext включает Agent Skill, который обрабатывает миграцию за вас. Он работает с Claude Code, OpenCode, Cursor, Codex и десятками других AI-инструментов для программирования. Установите его, откройте ваш Next.js проект и скажите AI мигрировать:

npx skills add cloudflare/vinext

Затем откройте ваш Next.js проект в любом поддерживаемом инструменте и скажите:

migrate this project to vinext

Навык обрабатывает проверку совместимости, установку зависимостей, генерацию конфигурации и запуск dev-сервера. Он знает, что поддерживает vinext, и пометит всё, что требует ручного внимания.

Или, если вы предпочитаете делать это вручную: