NextRush
Concepts

Core Concepts

The mental models that make NextRush predictable and composable

Before you write code, understand how NextRush thinks.

These are the core abstractions that determine how your application processes requests, composes behavior, and handles failure.

The Four Pillars

NextRush is built on four core abstractions. Everything else builds on top of these.

How They Work Together

When a request arrives, it flows through a predictable pipeline:

HTTP Request

┌─────────────────────────────┐
│  Application                │
│  ┌───────────────────────┐  │
│  │  Middleware Pipeline  │  │
│  │  ┌─────────────────┐  │  │
│  │  │  cors → auth    │  │  │
│  │  │      ↓          │  │  │
│  │  │  body-parser    │  │  │
│  │  │      ↓          │  │  │
│  │  │  router         │  │  │
│  │  └─────────────────┘  │  │
│  └───────────────────────┘  │
│           ↓                 │
│  ┌───────────────────────┐  │
│  │  Router               │  │
│  │  Match path → Handler │  │
│  └───────────────────────┘  │
└─────────────────────────────┘

HTTP Response

The flow is always the same:

  1. Request arrives at the adapter
  2. Adapter creates a fresh Context object
  3. Application passes context through Middleware
  4. Router matches the path and extracts params
  5. Handler executes and writes to context
  6. Response flows back through middleware
  7. Adapter sends the HTTP response

Context is Per-Request

Every request gets a new ctx object. There's no shared state between requests unless you explicitly create it.

Two Programming Styles

NextRush supports both functional and class-based programming. Choose based on your project's needs.

Simple, direct, minimal abstraction. Often fits small services and APIs.

Functional API
import { createApp } from '@nextrush/core';
import { createRouter } from '@nextrush/router';

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

router.get('/users/:id', async (ctx) => {
  const user = await db.users.findById(ctx.params.id);
  ctx.json({ user });
});

app.route('/api', router);

Structured, with dependency injection. Often fits larger applications and shared codebases.

Class-Based with DI
import { createRouter } from 'nextrush';
import { Controller, Get, Param, Service, controllersPlugin } from 'nextrush/class';

@Service()
class UserService {
  async findById(id: string) {
    return db.users.findById(id);
  }
}

const router = createRouter();

@Controller('/users')
class UserController {
  constructor(private users: UserService) {}

  @Get('/:id')
  async getUser(@Param('id') id: string) {
    return { user: await this.users.findById(id) };
  }
}

await app.plugin(controllersPlugin({ router, root: './src' }));

You Can Mix Styles

Both styles work together. Start with functions, add classes when you need structure. There's no forced migration.

Extension Points

Beyond the four pillars, NextRush provides two ways to extend functionality:

Plugins

Add capabilities without modifying core:

import { eventsPlugin } from '@nextrush/events';
import { controllersPlugin } from '@nextrush/controllers';

app.plugin(eventsPlugin());
app.plugin(controllersPlugin({ router, root: './src' }));

Learn about Plugins →

Guards

Control access to routes declaratively:

@UseGuard(AuthGuard)
@UseGuard(RoleGuard('admin'))
@Controller('/admin')
class AdminController {
  @Get('/dashboard')
  dashboard() {
    return { admin: true };
  }
}

Learn about Guards →

What You Should Learn First

Context API

Understand the ctx object—it's your primary interface for everything. Read Context →

Middleware

Learn the onion model. It determines execution order and error handling. Read Middleware →

Routing

Map URLs to handlers efficiently with radix tree routing. Read Routing →

Mental Model Summary

ConceptResponsibilityKey Insight
ApplicationOrchestrationHolds everything together, manages lifecycle
ContextRequest/ResponseFresh per-request, mutable state for sharing
MiddlewareTransformationOnion model—before, next(), after
RoutingURL MatchingO(k) radix tree, params and wildcards
PluginsExtensionAdd features without modifying core
GuardsAccess ControlBoolean gatekeepers for routes

Common Misconception

Middleware order matters. Error handlers must come first. Body parsers must run before you access ctx.body. If something isn't working, check your registration order.

Next Steps

On this page