ReferenceClass Runtime
@nextrush/class

Class Runtime

The class runtime — decorators, dependency injection, modules, guards, interceptors, filters, and lifecycle hooks.

@nextrush/class is the single package behind every class-based NextRush API. It merges what used to be three separate packages — @nextrush/decorators, @nextrush/controllers (both removed), and a re-export of @nextrush/di — into one import surface: nextrush/class.

Source & internals

@nextrush/class: README · ARCHITECTURE. @nextrush/di (re-exported, covered by DI reference): README · ARCHITECTURE.

@nextrush/decorators and @nextrush/controllers were removed

Both packages were compatibility shims that re-exported from @nextrush/class. Import from nextrush/class directly. See Removed packages below.


Package Overview

Loading diagram...
CapabilityReference page
Controllers, routes, params, guards, interceptors, filtersDecorators
Auto-discovery & registration (registerControllers)Controllers
@Module, registerModule, composing featuresModules
Dependency injection — @Service, scopes, containerDependency Injection

For the mental model behind each of these — why NextRush shapes them this way, beyond how to call them — see the Concepts pages: Modules, Dependency Injection & Scopes, Interceptors, Exception Filters, Lifecycle Hooks.


Installation

If you use the nextrush meta package, everything is included:

$ pnpm add nextrush

Or install @nextrush/class directly:

$ pnpm add @nextrush/class

reflect-metadata

@nextrush/class imports reflect-metadata as a side effect at its own entry point — decorator metadata (routes, params, DI) depends on this import running before any decorated class is defined. The nextrush meta package re-exports the same entry point, so no separate setup is needed either way.

Required tsconfig.json settings:

tsconfig.json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Most modern runners (tsx, esbuild, node --experimental-strip-types) strip types without emitting decorator metadata. Use tsc + node or @nextrush/dev for correct behavior.


Quick Example

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

@Service()
class UserService {
  findAll() {
    return [{ id: 1, name: 'Alice' }];
  }
}

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

  @Get()
  findAll() {
    return this.users.findAll();
  }
}

const app = createApp();
await registerControllers(app, { root: './src' });
await listen(app, 8080);

Everything Exported From nextrush/class

Verified against packages/class/src/index.ts. Grouped by concern, not by the old package split — everything below is one import surface.

// Class & route decorators
import { Controller, Get, Post, Put, Patch, Delete, Head, Options, All } from 'nextrush/class';

// Parameter decorators
import { Body, Ctx, Header, Param, Query, Req, Res, createCustomParamDecorator } from 'nextrush/class';

// Response decorators
import { HttpCode, Redirect, SetHeader } from 'nextrush/class';

// Guards
import { UseGuard, getAllGuards, getClassGuards, getMethodGuards } from 'nextrush/class';

// Exception filters
import { Catch, UseFilter, getAllFilters, getCatchTypes, getClassFilters, getMethodFilters } from 'nextrush/class';

// Interceptors
import { UseInterceptor, getAllInterceptors, getClassInterceptors, getMethodInterceptors } from 'nextrush/class';

// Lifecycle hooks (duck-typed — no decorator)
import type { OnInit, OnShutdown } from 'nextrush/class';
import { isOnInit, isOnShutdown } from 'nextrush/class';

// Metadata readers
import {
  isController,
  getControllerMetadata,
  getControllerDefinition,
  getRouteMetadata,
  getParamMetadata,
  getAllParamMetadata,
  getHttpCode,
  getRedirectMetadata,
  getResponseHeaders,
} from 'nextrush/class';
import { Module, getModuleMetadata, isModule } from 'nextrush/class';
import { registerModule } from 'nextrush/class';
import { collectModuleControllers, collectModuleGraph } from 'nextrush/class';

import type {
  ModuleMetadata,
  ModuleOptions,
  ModuleProvider,
  ModuleProviderConfig,
  ModuleRegistrationOptions,
} from 'nextrush/class';
import { registerControllers } from 'nextrush/class';
import { discoverControllers, getControllersFromResults, getErrorsFromResults } from 'nextrush/class';
import { FilesystemSource, MemorySource } from 'nextrush/class';
import { ControllerRegistry } from 'nextrush/class';
import { buildRoutes } from 'nextrush/class';
import { getClassDiagnostics } from 'nextrush/class';

import type { DiscoverySource } from 'nextrush/class';
import type { ApplicationGraph } from 'nextrush/class';
import type {
  CircularDependency,
  DiagnosticsReport,
  DuplicateRoute,
  ProviderEntry,
  RouteEntry,
  TimingEntry,
} from 'nextrush/class';

// Errors
import {
  ControllerError,
  ControllerResolutionError,
  DiscoveryError,
  GuardRejectionError,
  HttpError,
  MissingParameterError,
  NoRoutesError,
  NotAControllerError,
  NotAModuleError,
  ParameterInjectionError,
  RouteRegistrationError,
} from 'nextrush/class';
// Re-exported from @nextrush/di — same imports, one package
import { Repository, Service, container, createContainer, inject } from 'nextrush/class';
import type { Container } from 'nextrush/class';

Removed packages

@nextrush/decorators and @nextrush/controllers were thin compatibility shims that re-exported the corresponding symbols from @nextrush/class, and have been removed from the workspace — they no longer publish new versions.

Removed importReplacement
@nextrush/decoratorsnextrush/classDecorators reference
@nextrush/controllersnextrush/classControllers reference

Next Steps

Was this helpful?

On this page