← Усі статті

Lovable: 400 маршрутів з Next.js на TanStack Start без одномоментного перемикання

Паралельний проксі, #shared, адаптери й агенти: lovable.dev пішов з Vercel на свій стек при 42 млн відвідувачів на місяць.

Lovable: 400 маршрутів з Next.js на TanStack Start без одномоментного перемикання
Зміст

Коротко

Команда Lovable перенесла lovable.dev (~400 маршрутів, 850K+ рядків, 42M+ унікальних відвідувачів на місяць) з Next.js на Vercel на TanStack Start на власній платформі. Ключ — не «переписати й перемкнути», а місяці паралельної роботи двох фреймворків за проксі, спільна тека коду й поступовий викат групами маршрутів.

Що сталося

Сайт раніше жив на Next.js; Vercel закривав проблеми масштабу, але продукт сам хостить застосунки користувачів як воркери Cloudflare workerd. Мета міграції — їсти власну кашу: той самий шлях обслуговування, що в мільйонів чужих застосунків, короткий цикл зворотного зв’язку й єдиний стек для агента-збирача.

Міграція тривала пів року, поки кодова база росла з ~350K до 850K+ рядків. Перед обома стеками стояв проксі: за маршрутом і прапорцем обирав Next.js або TanStack Start. Жорстка навігація між фреймворками дорожча за м’яку (5 с проти ~1,5 с медіана), тому маршрути згрупували за типовими користувацькими шляхами й катили групи цілком. Для згладжування спалаху білого екрана увімкнули плавні переходи між документами (@view-transition).

Спільний код винесли під псевдонім #shared/ із лінтом «не імпортувати next і TanStack». Різницю API закрили адаптерами через псевдоніми TypeScript (@platform/router тощо). Наприкінці частка Next.js-специфічного коду впала приблизно до 3%. Багато механічної перекладки зробили агенти за повторюваними навичками; рев’ю й викат вів один інженер.

На панелі керування при 20% трафіку стався інцидент нестачі пам’яті на ізолятах V8: зайві мегабайти статики в бандлі вбили перевикористання ізолятів. Відкат за хвилини, потім відкладене завантаження важких шматків.

Чому це важливо

Це рідкісний публічний розбір міграції фронту на десятки мільйонів користувачів без одномоментного перемикання. Головний архітектурний тезис: фреймворк — тонка оболонка, 90–95% коду — переносне ядро. Тоді зміна стека стає проєктом адаптерів і викату, а не переписуванням продукту.

Другий урок — операційний: детерміновані прапорці для тестів, один зовнішній відсотковий викат за раз, синтетика плюс реальні метрики завантаження в користувачів, швидкий відкат важливіший за ідеальне передбачення.

На практиці

  1. Перед зміною фреймворка винесіть next/image, шрифти, вхід користувача й переклади на переносні бібліотеки — звузьте поверхню міграції.
  2. Тримайте два стеки за одним проксі й катіть групами маршрутів, а не по одній сторінці з середини користувацького сценарію.
  3. Введіть #shared + заборону імпортів фреймворка в лінтері; нові можливості за замовчуванням пишіть туди.
  4. Відмінності API закривайте адаптерами через псевдоніми модулів, а не контекстом на кожен клік.
  5. Слідкуйте за розміром бандла ізолята й резидентною пам’яттю: «ще пара мегабайт JSON» може зірвати перевикористання воркерів на краю мережі.

Підсумок

Lovable показав, як агенти + жорсткі правила переносності дають одному розробнику змінити веб-фреймворк під зростаючою кодовою базою. Сайт тепер — ще один бандл серед десятків мільйонів застосунків на тій самій платформі.