Недавно я перенёс Intlayer (решение для i18n) — монорепозиторий, состоящий из нескольких приложений (Next.js, Vite, React, design-system и т. д.) — с pnpm на Bun.

Кратко (TL;DR): если бы я знал заранее, я бы, вероятно, не делал этого.
Я думал, что это займёт пару часов. В итоге ушло около 20 часов.

Меня привлекло обещание «всё в одном» и впечатляющие показатели производительности.
Я попробовал, я собрал — всё билдилось молниеносно, круто.
Затем я сделал коммит… и столкнулся с первой проблемой.

Husky перестал работать

Оказалось, нужно вручную добавить путь к Bun в файлы commit-msg и pre-commit.
Документации на эту тему нет.
Пришлось копаться в GitHub issues, чтобы найти обходное решение.

Дальше — GitHub Actions.
Изменить → запушить → подождать → проверить → исправить → повторить × 15.
Я потратил 3 часа, отлаживая проблему с кешированием.
Наконец всё собирается. Время запускать приложения… или я так думал.


Backend

Проблема 1:
Использование express-rate-limit ломало все запросы.

Проблема 2:
Моё приложение использует express-intlayer, который зависит от cls-hooked для контекстных переменных.
Bun не поддерживает cls-hooked.

Решение: собирать с помощью Bun, запускать на Node.


Website

Проблема 1:
Билд работал локально, но в контейнере с официальным образом Bun процесс зависал, загружал CPU на 100% и падал.
Пришлось откатиться.
Нашёл issue на GitHub от 2023 года, где советовали использовать Node-образ и устанавливать Bun вручную.

Проблема 2:
Компоненты моего design system начали выдавать ошибки “module not found”.
Bun всё ещё плохо справляется с разрешением путей к пакетам.
Мне пришлось заменить все вызовы createRequire (для совместимости CJS/ESM) и вручную передавать функцию require в каждую зависимость.

Остальные ошибки опущу.


После многих часов мучений я наконец заставил всё работать.
Итак, каковы результаты по производительности CI/CD?

Процесс

Было

Стало

Backend CI/CD

5 мин

4:30

Server MCP

4 мин

3 мин

Storybook

8 мин

6 мин

Next.js приложение

13 мин

11 мин

Во время выполнения мои приложения на Express и Next.js всё равно работают на Node.


Вывод

Если вы спрашиваете: «Пора ли переходить на Bun?»
Мой ответ:

Он работает, но пока не совсем готов для сложных случаев.

Тем не менее, я верю в его потенциал и с интересом наблюдаю, как он развивается.

А вы сталкивались с подобными проблемами при миграции?

Комментарии (17)


  1. savostin
    14.10.2025 17:54

    Я бы сказал, пора переходить на bun в новых проектах. Перетягивание застарелых монстров из Node мало что даст.


  1. cmyser
    14.10.2025 17:54

    Husky ? Really ? Зачем эту фигню поддерживать в принципе, которая ничего не даёт


    1. aymericzip Автор
      14.10.2025 17:54

      Я не поклонник Husky, но проверки перед коммитом, это действительно большое преимущество при создании open-source проекта с участием других разработчиков.


      1. Lodin
        14.10.2025 17:54

        `simple-git-hooks`? Гораздо легковеснее, а работу выполняет не хуже


        1. aymericzip Автор
          14.10.2025 17:54

          Спасибо, я посмотрю. Надеюсь, что установить будет проще, чем Bun


        1. megahertz
          14.10.2025 17:54

          В последних версиях husky заметно похудел и теперь сравним с simple-git-hooks


      1. dlartagnan
        14.10.2025 17:54

        Используйте lefthook, вам больше не нужен husky и lint-staged


        1. aymericzip Автор
          14.10.2025 17:54

          Спасибо


        1. YegorP
          14.10.2025 17:54

          Зачем вообще полагаться на хуки гита и греть комп разраба на коммитах когда можно в ПРах проверки прописать по стилю и тестам? Тогда возможность раздать стрёмный код обрубается на корню, а мотивация каждого участника настроить IDEшку повышается - чтобы красным светилось ещё до коммита.

          А ещё желаю удачи тем, кто собирается ОС-независимые хуки сваять. Ну, чтобы разрабов с виндой не блочить своим никсовым bashизмом. Там похлеще извращаться приходится, чем для написания платформонезависимого кода самой программы.

          Особенно не понимаю тех, кто в husky и подобное всякую ерунду прописывает секунд на 30 и дольше (типа все тесты прогнать). То, что занимало 0 сек, превращается в чаепитие.


          1. dlartagnan
            14.10.2025 17:54

            Мы используем хуки на push, а не на коммит, что вполне приемлемо с точки зрения DX. Проверяем типы, запускаем линтер и выполняем дополнительные проверки.

            В CI проверки тоже конечно есть. Это нужно как раз в первую очередь для экономии времени, потому что когда у вас сложный пайплайн, то он выполняется долго и не хочется чтобы он падал из-за линтера.


    1. Tony-Sol
      14.10.2025 17:54

      Согласен, какую только ерунду не ставят, лишь бы маны гита не читать


  1. Resursator
    14.10.2025 17:54

    Как обычно.


  1. polearnik
    14.10.2025 17:54

    Перешел на бун пару месяцев назад но начал писать с нуля новые микросервисы. Проект активно развивается и много чего еще нет. привлекло то что можно собрать проект в один бинарник и запустить в дистролесс контейнере но мультитредовое прилождение таким образом работать не хочет. Проверю еще раз на версии 1.4. ну и руки не доходят проверить производительность стресс тестированием. хотя я и так использовал uWebsocket.js который встроен в бун так что разницы особо наверное не будет. но попробую переписать какойто микросервис на express.js и сравнить результаты


  1. ZiGGi
    14.10.2025 17:54

    Какой-то неполноценный переход на Bun, потому что у вас в качестве бандлера используется депрекейтнутый tsup, а для запуска тестов vitest. В Bun есть встроенный бандлер, который будет однозначно быстрее и так-же есть встроенный jest-совместимый тестраннер, у которого, в версии Bun 1.3, появилась возможность запускать тесты параллельно, благодаря этому он стал быстрее vitest.


    1. aymericzip Автор
      14.10.2025 17:54

      Я попробовал бандлер Bun, и там нет опции bundle: false, из-за чего возникают ошибки с next-intlayer
      Если указать несколько точек входа, расширения не разрешаются.
      Я был бы очень рад перейти на их бандлер, но он всё ещё на очень ранней стадии.
      Поэтому я остаюсь с бандлером на основе esbuild

      И я доволен Vitest, не хочу переносить все тесты своего кода


      1. ZiGGi
        14.10.2025 17:54

        Согласен, бандлер Bun имеет мало настроек и подойдёт далеко не всем. Я сам где-то использую esbuild вместо него.

        А bun test на моих тестах отрабатывал примерно в 10 раз быстрее vitest, но такого результата можно добиться только на синхронных тестах. Если в проекте есть много асинхронных тестов, то, из-за ожиданий, результат будет менее значительным.


  1. francyfox
    14.10.2025 17:54

    Bandler bun можно использовать только для приложений написанных на bun для повышение скорости (target: bun) для остальных вещей использовать неэффективно. Кстати с rolldown vite билдится быстрее, но подойдёт тем у кого esm только. Хотя использовать cjs это вообще не про скорость.

    Использовать bun вместо npm давно можно. Но все же как runtime начинать проект опасно. Что-то вечно до конца работает ни так. Редиска с сертификатом не подключается, хотя писали что cyphers добавили. На машине с proxmox не запускается хотя делаю baseline билд.

    А вообще очень часто начинаешь использовать Bun утилиты, а потом все равно подключаешь node библиотеку. При всем желании использовать максимально Bun не выйдет, спасает совместимость с nodejs.