NestJS
Three primitives ship from one package: a NestInterceptor that opens an
AsyncLocalStorage frame around every request (with method, url, request ID,
route handler, and scrubbed headers), an ExceptionFilter that captures
every error your controllers, guards, pipes, and interceptors throw, and a
NreactiveModule.forRoot() that wires both as global providers. Because
everything flows through ArgumentsHost / ExecutionContext, the same
package works transparently with the default Express HTTP adapter and
with Fastify when you opt into FastifyAdapter. NestJS 10 and 11
on Node ≥ 20.
AI-assisted setup
Paste the prompt below into Claude Code, Cursor, Copilot, or Codex — your
agent will detect your package manager, install both packages, create the
observability module, and add NreactiveModule.forRoot() to your
AppModule.
You are adding the @nreactive/core + @nreactive/nestjs SDKs to this NestJS project. nreactive is a production error-monitoring service that opens AI-generated pull requests to fix the errors it catches. The NestJS adapter is a single module that registers a global interceptor (for per-request context) and a global exception filter (for error capture) — it works regardless of whether the app uses the default Express HTTP adapter or the FastifyAdapter.
Do the following with the project's existing package manager (detect it from the lockfile: package-lock.json → npm, pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lockb → bun):
1. Install the packages @nreactive/core and @nreactive/nestjs.
2. Create "src/observability/nreactive.ts" that imports init from @nreactive/core and calls it with { appId: process.env.NREACTIVE_APP_ID, environment: process.env.NODE_ENV, release: process.env.APP_VERSION }. Export nothing — the module is used for its import side effect.
3. In "src/main.ts", add import "./observability/nreactive"; as the VERY FIRST import — before any other import including "@nestjs/core" and the AppModule.
4. In "src/app.module.ts", import NreactiveModule from "@nreactive/nestjs" and add NreactiveModule.forRoot() to the AppModule's imports array. That single line registers the global interceptor and exception filter via APP_INTERCEPTOR and APP_FILTER provider tokens — no manual app.useGlobalInterceptors / useGlobalFilters call is needed.
import { Module } from "@nestjs/common";
import { NreactiveModule } from "@nreactive/nestjs";
@Module({
imports: [NreactiveModule.forRoot()],
// ...controllers, providers
})
export class AppModule {}
5. (Optional, only if the project has authentication) In a NestJS guard or middleware that resolves the current user, call addContext({ user: { id: user.id, email: user.email } }) from @nreactive/core after authentication succeeds. This attaches the user identity to any errors thrown later in the request.
6. Add NREACTIVE_APP_ID= to .env.example (create it if missing) and document it in the README's environment-variables section. The user obtains their App ID from https://nreactive.com/dashboard/apps.
7. Restart the server and throw a test error from a controller (e.g. @Get("boom") boom() { throw new Error("nreactive test"); }) and hit it with curl to confirm events appear in the dashboard. The captured event will include the HTTP method, URL, request ID, route handler name, and scrubbed headers.
Do not invent additional configuration. The adapter does not currently capture Microservices/Gateway/GraphQL exceptions — only HTTP. Stop and ask if the project structure doesn't match these assumptions (for example, if the project is not using NestJS).Manual setup
Get your App ID
Sign in and grab your App ID from the Apps page. It looks
like app_ab12cd34ef. Export it as NREACTIVE_APP_ID so the SDK can read
it from process.env.
Install
pnpm add @nreactive/core @nreactive/nestjsOr npm install @nreactive/core @nreactive/nestjs / yarn add … / bun add ….
Wire it up
Create src/observability/nreactive.ts:
import { init } from "@nreactive/core";
init({
appId: process.env.NREACTIVE_APP_ID!,
environment: process.env.NODE_ENV,
release: process.env.APP_VERSION,
});In src/main.ts, import the observability module first — before
@nestjs/core and your AppModule — so the SDK is initialized before any
request can reach a controller:
import "./observability/nreactive";
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();Then add NreactiveModule.forRoot() to your AppModule's imports. That
single line registers both the interceptor and the exception filter as
global providers via APP_INTERCEPTOR and APP_FILTER — no manual
app.useGlobalInterceptors() or app.useGlobalFilters() needed:
import { Module } from "@nestjs/common";
import { NreactiveModule } from "@nreactive/nestjs";
import { AppController } from "./app.controller";
@Module({
imports: [NreactiveModule.forRoot()],
controllers: [AppController],
})
export class AppModule {}Attach user info from a NestJS guard (or any pipe / middleware that runs after authentication) so every downstream error is tagged:
import { Injectable, type CanActivate, type ExecutionContext } from "@nestjs/common";
import { addContext } from "@nreactive/core";
@Injectable()
export class AuthGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const user = await resolveUser(req);
if (user) addContext({ user: { id: user.id, email: user.email } });
return Boolean(user);
}
}Both the Express HTTP adapter (the default) and FastifyAdapter are
supported with the same module — the interceptor duck-types the underlying
request so neither adapter requires special handling.
Verify
Restart the server and hit a controller that throws:
import { Controller, Get } from "@nestjs/common";
@Controller()
export class AppController {
@Get("boom")
boom() {
throw new Error("nreactive test");
}
}curl http://localhost:3000/boomWithin a few seconds the event shows up on the Errors page of your dashboard with method, URL, route handler name, request ID, and scrubbed headers attached. NestJS's built-in exception response is preserved — the filter captures and re-delegates to the platform's default behaviour, so your clients see the same HTTP shape they did before.