From Express
Map Express req/res/next and app.use() patterns to NextRush's ctx and onion-model middleware.
Most of what you know from Express transfers directly — routes, middleware, and error handling
all exist in NextRush. The biggest change is that req and res merge into a single ctx
object, and middleware runs as an onion (before-and-after in one function) instead of a
linear chain.
Concept Mapping
Express → NextRush
| Property | Type | Description |
|---|---|---|
req + res + next | ctx | A single context object carries everything — no third next() parameter to thread through. |
app.get(path, handler) | router.get(path, handler) | Routes are registered on a Router, mounted onto the app. |
app.use(middleware) | app.use(middleware) | Same call shape; the middleware signature changes. |
req.params | ctx.params | Same shape. |
req.query | ctx.query | Same shape. |
req.body | ctx.body | Populated by @nextrush/body-parser, not automatic. |
res.json(data) | ctx.json(data) | Same behavior. |
res.status(code) | ctx.status = code | A property assignment, not a method call. |
res.redirect(url) | ctx.redirect(url) | Same behavior. |
next(err) | throw new HttpError(...) | Throw a typed error instead of calling next with one. |
Before / After
import express from 'express';
const app = express();
app.use(express.json());
app.get('/users/:id', (req, res) => {
const user = findUser(req.params.id);
if (!user) {
return res.status(404).json({ error: 'Not found' });
}
res.json(user);
});
app.listen(8080);import { createApp, createRouter, listen } from 'nextrush';
import { bodyParser } from '@nextrush/body-parser';
import { NotFoundError } from 'nextrush';
const app = createApp();
app.use(bodyParser());
const users = createRouter();
users.get('/:id', (ctx) => {
const user = findUser(ctx.params.id);
if (!user) throw new NotFoundError('Not found');
ctx.json(user);
});
app.route('/users', users);
listen(app, 8080);createApp, createRouter, and listen all come from the nextrush meta package — see the
Quick Start if you haven't installed it yet. bodyParser is a
separate install (@nextrush/body-parser), same as Express's body-parser used to be before
express.json() was folded in.
Middleware: linear chain vs. onion
Express middleware runs once, forward. NextRush middleware wraps the rest of the chain, so "before" and "after" logic live in the same function:
// Express — needs a 'finish' event to run code after the response
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
console.log(`${req.method} ${req.url} ${Date.now() - start}ms`);
});
next();
});// NextRush — before and after in one function
app.use(async (ctx, next) => {
const start = Date.now();
await next();
console.log(`${ctx.method} ${ctx.path} ${Date.now() - start}ms`);
});NextRush's Middleware type accepts both the modern async (ctx) => { await ctx.next(); } form
and this traditional async (ctx, next) => { await next(); } form — pick whichever reads more
naturally for a given handler.
Error handling
Express error middleware must be last-registered and take exactly four parameters. NextRush throws typed error classes and reads the status code off the error itself:
import { NotFoundError, BadRequestError } from 'nextrush';
router.get('/users/:id', (ctx) => {
const user = findUser(ctx.params.id);
if (!user) throw new NotFoundError('User not found');
ctx.json(user);
});
// Optional: a custom handler for anything not already an HttpError
app.setErrorHandler((error, ctx) => {
ctx.status = 500;
ctx.json({ error: 'Internal error' });
});NotFoundError, BadRequestError, and the rest of the HTTP error hierarchy come from
@nextrush/errors and are re-exported by nextrush — see the
error handling reference for the full list.
Common middleware translation
Express package → NextRush package
| Property | Type | Description |
|---|---|---|
cors | @nextrush/cors | Included in the nextrush meta package. |
helmet | @nextrush/helmet | Included in the nextrush meta package. |
body-parser / express.json() | @nextrush/body-parser | Separate install — not automatic. |
express-rate-limit | @nextrush/rate-limit | Separate install. |
cookie-parser | @nextrush/cookies | Separate install. |
compression | @nextrush/compression | Separate install. |
serve-static | @nextrush/static | Separate install. |
No built-in session middleware
NextRush has no equivalent to express-session. Use @nextrush/cookies plus your own session
store, or a stateless approach (JWT) via a custom middleware.
Next steps
- Middleware — the onion model, in depth.
- Context — everything
ctxcarries. - Routing — routers, mounting, and route parameters.