Skip to content

Getting Started

Tanzim Hossain edited this page Aug 6, 2026 · 4 revisions

Getting Started

Start a NextRush server in under a minute. NextRush v4 is ESM-only and requires Node.js ≥ 22 (TypeScript 5.x, or a Bun/Deno runtime via adapters).

1. Create a project

The fastest path is the scaffolder — one command produces a runnable project:

pnpm create nextrush my-api
# or
npm create nextrush my-api
# or
bun create nextrush my-api

The scaffolder (create-nextrush) asks a few questions — style (functional vs class-based), runtime (node / bun / deno), and middleware defaults — then writes a complete project with src/, tsconfig.json, and scripts. You can also pre-answer everything:

pnpm create nextrush@latest my-api --style functional --runtime node --yes

Want to add NextRush to an existing project instead? Install the meta-package and its optional peers for the runtime you target:

pnpm add nextrush @nextrush/adapter-node

The nextrush meta-package re-exports the core surface (createApp, listen, router, context helpers, errors). For a plain functional install with no class/DI layer, only the meta-package and your runtime adapter are needed.

2. First server

import { createApp, listen } from 'nextrush';

const app = createApp();

app.get('/hello/:name', (ctx) => {
  ctx.body = { message: `Hello, ${ctx.params.name}!` };
});

await listen(app, 8080);

Run it (the scaffold's dev script, or directly):

pnpm dev
# or
tsx src/index.ts
curl http://localhost:8080/hello/world
# → {"message":"Hello, world!"}

Notes on what just happened:

  • createApp() builds the application: router, middleware pipeline, and a fresh Context per request.
  • Handlers write through ctx (ctx.body), they do not return a Response. Serialization, headers, and status are controlled on the context.
  • Port 8080 is the framework default; pass any port (or an existing server) to listen.

3. Middleware and errors

Add middleware with app.use(...) and let errors flow to the default handler:

import { createApp, listen } from 'nextrush';
import { json } from 'nextrush/middleware';
import { NotFoundError } from 'nextrush';

const app = createApp();

app.use(json()); // parse JSON bodies

app.post('/tasks', (ctx) => {
  const task = ctx.body; // parsed request body
  ctx.status = 201;
  ctx.body = { id: 1, ...task };
});

app.get('/tasks/:id', (ctx) => {
  throw new NotFoundError(`No task ${ctx.params.id}`);
});

await listen(app, 8080);

See Middleware and Error Handling for the details.

4. Class-based apps (optional)

Prefer controllers and dependency injection? The class runtime is a registrar on top of the same functional core:

import { createApp, listen } from 'nextrush';
import { Controller, Get, registerControllers } from 'nextrush/class';

@Controller('/users')
class UserController {
  @Get()
  list() {
    return [{ id: 1, name: 'Ada' }];
  }
}

const app = createApp();
await registerControllers(app, { controllers: [UserController] });
await listen(app, 8080);

Jump to Controllers & Decorators and Dependency Injection when you're ready.

Next steps

Clone this wiki locally