В последние годы среди JavaScript-разработчиков всё чаще говорят о Bun. Это рантайм, который, как и Node.js, выполняет JavaScript и TypeScript на сервере, но при этом приносит с собой пакетный менеджер, бандлер и тест-раннер. Первый вопрос, который задают почти все: можно ли полностью заменить им Node.js? Ответ зависит от типа проекта, используемых библиотек и того, какой риск готова принять ваша команда. Разберём это на практических примерах.
Чем Bun отличается от Node.js
Node.js построен на движке V8 от Google, а Bun использует JavaScriptCore — движок браузера Safari — и написан в основном на языке Zig. Bun умеет запускать TypeScript-файлы напрямую, без предварительной компиляции, поэтому в небольших проектах отпадает необходимость настраивать tsc или ts-node. Установка пакетов обычно заметно быстрее, что особенно ощущается в CI и в проектах, где install выполняется много раз в день.
Разработчики Bun уделяют много внимания совместимости с API Node.js: модули fs, path, http и большая часть npm-пакетов работают. Но совместимость пока не стопроцентная. Нативные модули на C++, некоторые редко используемые API Node и библиотеки, завязанные на внутреннее поведение Node, могут давать неожиданные ошибки. Поэтому точный ответ для вашего проекта даст только тестирование; полезно также заглянуть в таблицу совместимости в официальной документации.
Когда разумно выбрать Bun
Bun хорошо показывает себя в новых проектах с небольшим числом зависимостей и современными библиотеками. Например, для маленького API ташкентского кафе, которое отдаёт меню и принимает заказы, для Telegram-бота или внутренних скриптов отчётности Bun может быть удобным выбором. А вот в системах, которые работают годами, имеют десятки нативных пакетов и простой которых стоит дорого, нужна осторожность. В таких случаях можно начать с Bun только как пакетного менеджера или тест-раннера, оставив рантайм на Node.js.
- Bun подходит: новые API, боты, скрипты, небольшие сервисы на TypeScript.
- Будьте осторожны: нативные модули вроде
bcryptиsharp, старые middleware для Express, сложные монорепозитории. - Оставьте на Node.js: критичные сервисы, работающие с платёжными системами, которые нельзя менять без тестов.
Установка Bun на VPS
Bun — постоянно работающий процесс, поэтому удобнее всего запускать его на VPS. На обычном shared-хостинге, как правило, нельзя самостоятельно установить рантайм и держать фоновый процесс, поэтому для таких проектов стоит рассмотреть VPS на sayt.uz или проконсультироваться с техподдержкой. Для установки используется официальный скрипт, который кладёт Bun в домашний каталог пользователя.
sudo adduser --disabled-password app
sudo -iu app
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc
bun --version
Мы создали отдельного пользователя app, чтобы не запускать приложение от root. Bun в этом случае окажется по пути /home/app/.bun/bin/bun — он понадобится на следующем шаге.
Простой HTTP-сервер и проверка
У Bun есть собственный HTTP-сервер, который запускается функцией Bun.serve. Пример ниже отдаёт меню кафе в формате JSON и берёт порт из переменной окружения. Хотя у файла расширение .ts, запускать его можно без какой-либо компиляции.
// src/index.ts
const menu = [{ id: 1, name: "Osh", price: 45000 }];
Bun.serve({
port: Number(process.env.PORT ?? 3000),
hostname: "127.0.0.1",
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/menu") return Response.json(menu);
return new Response("Not found", { status: 404 });
},
});
Установите зависимости командой bun install и запустите bun run src/index.ts. Затем из другого терминала проверьте ответ через curl http://127.0.0.1:3000/menu. Если хотите попробовать существующий проект на Express, обычно достаточно написать bun server.js вместо node server.js.
Постоянная работа как сервис systemd
В production процесс не должен зависеть от терминала, должен подниматься после падения и стартовать вместе с сервером. Для этого напишем unit-файл systemd. Такой способ не требует дополнительных программ, а логи удобно смотреть через journalctl.
# /etc/systemd/system/menu-api.service
[Unit]
Description=Menu API (Bun)
After=network.target
[Service]
User=app
WorkingDirectory=/home/app/menu-api
Environment=NODE_ENV=production
Environment=PORT=3000
ExecStart=/home/app/.bun/bin/bun run src/index.ts
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now menu-api
sudo systemctl status menu-api
journalctl -u menu-api -f
Внешние запросы, как и в случае с Node.js, принимает Nginx: reverse proxy настраивается строкой proxy_pass http://127.0.0.1:3000;, а сертификат Let's Encrypt выпускается через Certbot. Тем, кто привык к PM2, он тоже подойдёт: pm2 start src/index.ts --interpreter ~/.bun/bin/bun.
Как безопасно перейти с Node.js на Bun
Вместо одномоментного переноса существующего проекта лучше двигаться поэтапно. Сначала запустите тесты под Bun, затем несколько дней понаблюдайте за приложением на staging-сервере и только после этого переключайте основной сервер. Обновления Bun выходят часто, поэтому зафиксируйте версию на сервере и проверяйте новую в тестовой среде перед обновлением. Если какая-то библиотека создаёт проблемы, вполне нормально оставить этот сервис на Node.js, а остальные запускать на Bun.