The best Bun hosting platforms in 2026
Bun stopped being a curiosity a while ago. It installs faster, it runs TypeScript without a build step, and its HTTP server is quick enough that a small API can serve a lot of traffic from very little hardware. The runtime is no longer the risky part of adopting Bun. Deployment is.
The specific trap: many platforms advertise "Bun support" and mean they will run `bun install` during the build, then execute your application with Node. For a plain Express app that is invisible and fine. For anything using `Bun.serve`, `Bun.file`, the built-in SQLite driver, or Bun-specific test tooling, it fails at startup with an error that looks like a missing dependency and is actually a missing runtime.
I build PandaStack, which is one of the options here. It's listed with the same caveats as everything else.
The one-line test for real Bun support
Deploy this and hit it. If it responds, the platform is running Bun. If it throws a ReferenceError, the platform installed with Bun and ran with Node.
// server.ts — uses Bun's native server, not a Node-compatible one
const port = Number(process.env.PORT ?? 3000);
Bun.serve({
port,
hostname: "0.0.0.0", // bind all interfaces, not localhost
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/healthz") return new Response("ok");
return new Response(`bun ${Bun.version} serving ${url.pathname}`);
},
});
console.log(`listening on ${port}`);The platforms
Railway and Render — the straightforward choices
Both detect a Bun lockfile and will run your app with Bun, and both give you a long-lived process rather than a request handler, which is what a `Bun.serve` app wants. This is the shortest path from repo to URL for a Bun API, and you get the usual platform conveniences: environment variables, logs, managed Postgres nearby. Expect an instance that mostly stays up and bills accordingly.
Fly.io — Bun in a container you control
With a Dockerfile based on the official Bun image, there is no ambiguity about which runtime executes your code, and Fly's Machines give you regions, volumes, and control over the lifecycle. This is the option to take when Bun's version matters to you precisely, or when you need something that is not in the platform's detection logic. More setup, fewer surprises.
A VPS with systemd — genuinely underrated
Bun is a single binary. Copying it to a small server, writing a twelve-line systemd unit, and putting Caddy in front is an hour of work and costs a few dollars a month, with no platform semantics to learn. For a side project or an internal service, this is often the correct answer, and the thing you give up is push-to-deploy and someone else's on-call.
Cloudflare Workers, Deno Deploy, and other edge runtimes — not Bun
These are frequently suggested to Bun users because the code looks similar: a fetch handler, web-standard Request and Response. They are different runtimes with different APIs and different limits. Hono or Elysia code written against web standards may port with little friction; anything touching Bun's native APIs, the filesystem, or a long-lived process will not. Treat it as a rewrite target, not a hosting option.
PandaStack — Bun pre-installed, running as a normal process
PandaStack's base template ships Bun pre-warmed alongside Node 24, Python 3.12, and Go, managed by mise, so `bun` is on PATH in the microVM without an install step at deploy time. Because an app is a long-lived process inside its own VM rather than a function invocation, `Bun.serve` behaves exactly as it does locally: the server stays up, WebSocket connections persist, and background timers keep firing.
The one thing to be explicit about: framework detection sees a package.json and treats the repo as a Node app, so you set the start command yourself. That is one flag, and it removes the ambiguity that causes the Node-instead-of-Bun failure elsewhere.
# Bun is already in the base template — just tell the platform how to start
pandastack app create --name bun-api \
--git-url https://github.com/acme/bun-api \
--install-command 'bun install --frozen-lockfile' \
--start-command 'bun run server.ts' \
--port 3000
# Pin a specific Bun version the same way you would locally
echo 'bun = "1.2"' >> mise.tomlRunning Bun in production without regretting it
- Pin the version. Bun moves quickly and minor releases have changed behaviour in ways that matter. Commit a version file and use the same one in CI, or you will eventually debug a difference that does not exist in your repository.
- Use `bun install --frozen-lockfile` in the build. Resolving fresh on every deploy is how you ship a dependency you never tested.
- Read PORT from the environment and bind 0.0.0.0. Bun defaults to a friendly local binding, and localhost-only is the most common reason a healthy-looking deploy receives no traffic.
- Add a health endpoint that does not touch the database. Platforms restart instances that fail health checks, and a check that queries Postgres turns a slow database into a restart loop.
- Handle SIGTERM. Deploys send it before killing the process; without a handler, in-flight requests die mid-response during every deploy.
- Decide about Node compatibility deliberately. Bun implements most of Node's API surface, but native addons and a few less common modules still differ. Run your dependency-heavy paths under Bun in CI rather than discovering the gaps in production.
The last one deserves emphasis, because it is where Bun deployments actually fail. It is rarely your code — it is a transitive dependency doing something with a native binding or an obscure Node internal. Running your full test suite under Bun in CI, on the same version you deploy, catches essentially all of it before a user does.
The short version
Fastest to a URL: Railway or Render. Most control over the exact runtime: Fly with the official Bun image, or a VPS with systemd if you'd rather own the box. Long-lived processes, WebSockets, or background work alongside the server, with idle costs that go to nearly zero: a microVM platform such as PandaStack. And if someone suggests an edge runtime, check whether your code calls anything on the `Bun` global before you agree — that one question saves a wasted weekend.
Frequently asked questions
Is Bun production-ready in 2026?
For most web services, yes — it has been running real production traffic for a couple of years and the stability of the core runtime is no longer the concern it was. The residual risk lives in the ecosystem rather than in Bun itself: a native addon that assumes Node's binary interface, a tool that shells out to `node` by name, or a library that inspects `process.versions` and takes a different code path. The practical mitigation is boring and effective — run your entire test suite under the exact Bun version you deploy, in CI, on every pull request.
Can I use Bun just as a package manager and run Node in production?
Yes, and it is a completely reasonable strategy. `bun install` is dramatically faster than npm and produces a working node_modules that Node can execute, so you can take the install-speed win in CI without changing your runtime at all. The constraint is that your application code must stay Node-compatible: no `Bun.serve`, no `bun:sqlite`, no Bun-specific test APIs in code paths that run in production. Many teams do exactly this deliberately, and it is the safest way to adopt Bun incrementally.
Does Bun help with cold starts?
It helps with process startup, which is only part of a cold start. Bun's own startup is measurably faster than Node's and TypeScript runs without a separate build step, so the moment between 'process launched' and 'first request handled' shrinks. But on a serverless platform, most cold-start latency is provisioning — pulling an image, allocating a sandbox, setting up networking — and no runtime choice touches that. If cold starts are your actual problem, the platform's provisioning model matters far more than whether you run Bun or Node.
How do I pin the Bun version on a hosting platform?
Every platform has a mechanism and they differ, which is exactly why this is worth doing explicitly. Some read a `packageManager` field or an engines entry in package.json, some use a platform-specific setting, and tool-version managers such as mise or asdf read a version file committed to the repo. On a Docker-based deploy, the base image tag is the pin. Whichever applies, put it in the repository rather than in a dashboard setting, so the version travels with the code and CI tests the same runtime production runs.
Elysia or Hono — does the framework affect where I can host?
It affects your portability more than your hosting quality. Hono is written against web standards and runs on Bun, Node, Deno, Cloudflare Workers, and several edge runtimes, so choosing it keeps your options open at a small cost in Bun-specific ergonomics. Elysia is built for Bun and leans into its APIs, which makes it faster and more pleasant there and effectively pins you to a Bun runtime. Neither is wrong — just make the choice knowing that one of them is also a hosting decision.
Keep reading
- App hosting on PandaStack — Bun, Node, Python and Go pre-warmed in the base template
- Templates — what ships inside the microVM image
- The best Node.js hosting platforms
- Hosting WebSocket apps and persistent connections
- The best Express hosting platforms
49ms p50 cold start. Fork, snapshot, and scale to zero.