Getting StartedChoose Your Runtime

Node.js

Install NextRush on Node.js, run a hello-world server, and see how the Node adapter sets the baseline every other runtime is measured against.

Runtime · Baseline

The baseline runtime. Everything in NextRush is designed here first — every capability, every middleware package, and every adapter contract is built and tested against Node.js before any other runtime. Maximum compatibility, the largest ecosystem, and every doc example assumes it unless stated otherwise.

Baseline Runtime⭐ Recommended for beginners~10 minBeginner

Where Node fits

RuntimeBest forTradeoff
Node.js · this pageProduction APIs, long-running servers, full ecosystemHeavier footprint than Bun or edge
BunLocal dev speed, fast cold startYounger ecosystem, some node:* gaps
DenoSecure by default, permission modelSmaller package ecosystem
EdgeGlobal low latency, Cloudflare/VercelNo long-running server, node:* limited
ServerlessPay-per-request, auto-scalingCold starts, no persistent state

Not sure which runtime fits? See the runtime decision guide.

"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

  • ✓ Node.js 22+ installed (nvm or nodejs.org)
  • ✓ A package manager (pnpm, npm, yarn, or bun)
  • ✓ ~10 minutes

Confirm your Node.js version

  • Why this matters: NextRush targets Node.js 22+ — the ESM-only policy and node:* APIs assume it.
node --version
# needs to read v22.x.x or higher

If you're on an older line, install 22+ with nvm or from nodejs.org before continuing.

Install NextRush

  • Why this matters: the nextrush meta-package already includes the Node adapter — one install is everything.
$ pnpm add nextrush
$ pnpm add -D tsx typescript @types/node

Or scaffold instead:

pnpm create nextrush my-api --runtime node

Behind the scenes:

  • @nextrush/core, @nextrush/router, and @nextrush/adapter-node are all re-exported through nextrush
  • On every other runtime (Bun, Deno, edge, serverless) the same import stays identical — only the adapter changes

Run a hello-world server

Create src/index.ts:

src/index.ts
import { createApp, createRouter, listen } from 'nextrush';

const app = createApp();
const router = createRouter();

router.get('/', (ctx) => {
  ctx.json({ runtime: 'node', status: 'ok' });
});

app.route('/', router);
await listen(app, 8080);

Run it:

npx tsx src/index.ts

Expected result — curl http://localhost:8080/ returns {"runtime": "node", "status": "ok"}

Behind the scenes:

  • listen(app, 8080) calls @nextrush/adapter-node, which starts a plain node:http server
  • Each incoming request goes to NextRush's router through the Context API
  • The same four calls (createApp, createRouter, route, listen) are what every runtime starts from

Why Node is the baseline

Your server is now running. Before moving to Bun or Deno, it's worth understanding why Node is the reference runtime — and what that means for portability.

What Node gives you:

  • Full node:* module access — no restrictions
  • No cold-start behavior to design around
  • Every middleware package (@nextrush/body-parser, @nextrush/static, @nextrush/form-data) targets it directly

This does not mean Node is required — Bun, Deno, edge, and serverless adapters all implement the same Context and Application contract (see each adapter's reference). Node is where that contract has the fewest constraints, so it's the reference point the runtime compatibility concept measures every other adapter against.

Node runtime working — you're ready to verify and move on.

Node baseline complete

Confirm the server answers before moving on:

curl -i http://localhost:8080/
# → HTTP/1.1 200 OK
# → {"runtime":"node","status":"ok"}

Your project now looks like:

my-api/
  package.json
  src/
    index.ts

Baseline complete — a real NextRush server on Node.js. Every capability the framework ships targets this runtime first.

What you learned

Three things describe how a request reaches your code on Node.js:

  • Node is the baseline runtime — the framework's node:*-using packages, the Node adapter, and the docs' default code examples all target it first
  • One nextrush import covers the adaptercreateApp, createRouter, and listen all come from the meta-package; you never import @nextrush/adapter-node directly unless you need its lower-level surface
  • The same code moves between runtimes — nothing in src/index.ts above is Node-specific; swapping to Bun changes the runtime underneath, not your route handlers

The same app, every runtime

This is the core promise — the code you just wrote runs on every runtime NextRush supports. Only the adapter import changes:

  1. createApp()
  2. Router
  3. Handler
  4. Node adapter
  5. Running

Swap the adapter, same everything else:

// Node:      import { listen } from '@nextrush/adapter-node';
// Bun:       import { listen } from '@nextrush/adapter-bun';
// 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. That's the point — you're learning one runtime today, but you're building toward a portable mental model.

Next steps

Continue learning

Was this helpful?

On this page