🥟
Hosting

Bun Instead of Node.js? When It Works and How to Run It on a Server

11.11.2026
← All articles

Bun has become one of the most talked-about tools in the JavaScript world. Like Node.js, it runs JavaScript and TypeScript on the server, but it also ships with a package manager, a bundler and a test runner. The first question most teams ask is whether it can replace Node.js entirely. The honest answer depends on your project, your dependencies and how much risk you can accept.

How Bun differs from Node.js

Node.js is built on Google's V8 engine, while Bun uses JavaScriptCore, the engine behind Safari, and is written largely in Zig. Bun runs TypeScript files directly, so small projects no longer need tsc or ts-node, and package installs are usually much faster. Bun aims for Node.js API compatibility and most npm packages work, but not all: native C++ addons and libraries relying on Node internals can still break. Only testing your own project, plus a look at the compatibility notes in the official docs, gives a real answer.

When Bun is a good choice

A cautious middle path is to use Bun only as a package manager or test runner while keeping Node.js as the runtime.

Installing Bun on a VPS

Bun runs as a long-lived process, so a VPS is the natural place for it; shared hosting usually does not let you install a runtime or keep background processes alive. For such projects, consider a VPS from sayt.uz or ask support. Create a dedicated user and install Bun with the official script:

sudo adduser --disabled-password app
sudo -iu app
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc
bun --version

A minimal HTTP server

// 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 });
  },
});

Run bun install, then bun run src/index.ts, and test with curl http://127.0.0.1:3000/menu. For an existing Express app, replacing node server.js with bun server.js is often enough to try it.

Running it as a systemd service

# /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

Enable it with sudo systemctl daemon-reload and sudo systemctl enable --now menu-api, and follow logs with journalctl -u menu-api -f. Put Nginx in front with proxy_pass http://127.0.0.1:3000; and get a certificate with Certbot. PM2 also works: pm2 start src/index.ts --interpreter ~/.bun/bin/bun.

A safe migration path

Do not switch everything at once. Run your test suite under Bun first, then watch the app on a staging server for a few days before moving production. Bun releases frequently, so pin the version on your server and test upgrades before applying them. If one library misbehaves, keeping that single service on Node.js while the rest runs on Bun is a perfectly reasonable setup.

Finally, keep an eye on memory and response times during the first weeks. Bun's performance advantage is real for many workloads, but it varies by use case, so measure your own endpoints under realistic load before drawing conclusions. Recording a simple baseline on Node.js first makes that comparison fair and helps you decide with data rather than headlines.

Related articles

⏱️ max_execution_time: handling long-running PHP scripts 📦 Telegram Bot API Local Server: Running Your Own for Large Files 💻 VS Code Remote SSH: editing code directly on your server 🚦 MySQL "Too many connections" Error: Causes and Fixes
🌐 Language
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский 🇬🇧 English ✓