Bun
Install NextRush on Bun, run a hello-world server on Bun.serve(), and see exactly where the Bun adapter's import path diverges from Node's.
Runtime · Fast startup
Fast startup, native TypeScript. Bun runs your .ts files directly — no tsx, no separate
transpile step — and starts significantly faster than Node. The createApp/createRouter API is
identical; only the adapter import changes. The tradeoff is a younger runtime with a smaller
production track record than Node.
Where Bun fits
| Runtime | Best for | Tradeoff |
|---|---|---|
| Node | Production APIs, long-running servers, full ecosystem | Heavier footprint than Bun or edge |
| Bun · this page | Local dev speed, native TypeScript, fast cold start | Younger ecosystem, some node:* gaps |
| Deno | Secure by default, permission model | Smaller package ecosystem |
| Edge | Global low latency, Cloudflare/Vercel | No long-running server, node:* limited |
| Serverless | Pay-per-request, auto-scaling | Cold starts, no persistent state |
Not sure which runtime fits? See the runtime decision guide.
What changes from Node
This is the first question everyone asks. Almost nothing:
| Same | Different |
|---|---|
createApp() | listen() import — comes from @nextrush/adapter-bun, not nextrush |
createRouter() | Runtime underneath — Bun.serve(), not node:http |
| Route registration | No tsx needed — Bun runs .ts directly |
| Context API | Hot reload — bun --hot run src/index.ts |
| Middleware |
One import line. That's the real divergence.
"Partial" means the adapter is Stable but not yet verified against the real platform in CI (see the compatibility matrix) — not that it's missing features.
Before you begin
- ✓ Bun installed (bun.sh)
- ✓ A terminal
- ✓ ~10 minutes
Confirm your Bun version
- Why this matters:
@nextrush/adapter-buntargets Bun's stableBun.serve()surface.
bun --version
# needs to read 1.x.x or higherIf Bun isn't installed yet, follow the install instructions before continuing.
Install NextRush and the Bun adapter
- Why this matters: unlike Node, the
nextrushmeta-package does not bundle the Bun adapter — you add@nextrush/adapter-bunalongside it.
$ pnpm add nextrush @nextrush/adapter-bun
Or scaffold instead:
bunx create-nextrush my-api --runtime bunBehind the scenes:
createAppandcreateRouterstill come fromnextrush— runtime-independentlisten,serve, andcreateHandlercome from@nextrush/adapter-bun— the meta-package'slistenis wired to@nextrush/adapter-nodespecifically
This is the one place Bun's setup differs from Node's. import { listen } from 'nextrush'
starts a Node server even when running under Bun (Bun's Node-compat layer makes that import
resolve, but it never reaches Bun.serve()). Import listen/serve from
@nextrush/adapter-bun explicitly to run on Bun's native server.
Run a hello-world server
Create src/index.ts:
import { createApp, createRouter } from 'nextrush';
import { listen } from '@nextrush/adapter-bun';
const app = createApp();
const router = createRouter();
router.get('/', (ctx) => {
ctx.json({ runtime: 'bun', status: 'ok' });
});
app.route('/', router);
await listen(app, 8080);Run it:
bun run src/index.tsExpected result — curl http://localhost:8080/ returns {"runtime": "bun", "status": "ok"}
Behind the scenes:
listen(app, 8080)from@nextrush/adapter-buncallsBun.serve()directly- Each request goes to NextRush's router through the same Context API Node uses
ctx.runtimereads'bun'because the adapter, not your handler, decides that value- Hot reload:
bun --hot run src/index.tsrestarts on file change — no NextRush setup needed
Why Bun diverges from Node
Your server is now running. Before moving on, it's worth understanding what's genuinely different — and what isn't.
Same: the Context API (ctx.json, ctx.params, ctx.query, ctx.set, …), createApp,
createRouter, route registration, and middleware all behave identically to Node. Nothing in your
route handlers is Bun-specific.
Different: the import path (Step 2) is the real divergence. One behavioral difference follows
from a platform gap — Bun.serve() has no built-in request timeout the way node:http does, so
@nextrush/adapter-bun adds its own AbortController-based timeout (defaults to 30 seconds, same
as Node). The request body size limit is a deliberate match too: Bun.serve() reads the full body
before NextRush sees it, so @nextrush/adapter-bun caps maxRequestBodySize at the same 1 MB
default as @nextrush/adapter-node.
@nextrush/adapter-bun is a Stable, independently-versioned package — CI-tested against a real Bun
runtime, not Node's Bun-compat layer. See the Bun adapter reference
for its full surface.
Bun runtime working — you're ready to verify and move on.
Bun baseline complete
Confirm the server answers:
curl -i http://localhost:8080/
# → HTTP/1.1 200 OK
# → {"runtime":"bun","status":"ok"}Your project now looks like:
my-api/
package.json
src/
index.tsBaseline complete — a real NextRush server on Bun. The only thing that changed from Node was one import line.
What you learned
- ✓
nextrushgives you the runtime-independent half —createApp,createRouter, and route registration are identical on Bun and Node - ✓
listen/serve/createHandlercome from@nextrush/adapter-bun, not the meta-package - ✓ The adapter ships independently and is Stable — CI-tested against real Bun, not Node's compat layer
The same app, every runtime
The code you just wrote runs on every runtime NextRush supports. Only the adapter import changes:
- createApp()
- Router
- Handler
- Bun adapter
- Running
// Node: import { listen } from '@nextrush/adapter-node';
// Bun: import { listen } from '@nextrush/adapter-bun'; // ← you are here
// Deno: import { listen } from '@nextrush/adapter-deno';
// Edge: import { serve } from '@nextrush/adapter-edge';
// Serverless import { handler } from '@nextrush/adapter-serverless';The route handler, middleware, and Context API never change. You learned one runtime today — the same code runs on all of them.
Next steps
🚀 Build a Task API — recommended · ~20 min
Go past hello-world on the runtime you set up: routing, a JSON body, and a real 404. Start the tutorial →
Deploy to production
Docker and Bun-runtime deployment paths for a NextRush server on Bun.
Bun adapter reference
The full @nextrush/adapter-bun surface — serve(), createHandler(), and Bun-specific utilities.