npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nest-toolbox/request-context

v1.8.1

Published

Lightweight AsyncLocalStorage-based request context for NestJS with auto-generated request IDs

Readme

@nest-toolbox/request-context

Lightweight AsyncLocalStorage-based request context for NestJS with auto-generated request IDs.

npm version License: MIT

Features

  • 🪶 Zero dependencies — uses Node.js built-in AsyncLocalStorage, nothing else
  • 🚀 Zero config — import the module and every request gets a unique ID
  • 🆔 Auto-generated request IDs — UUIDv4 by default, or reads from an incoming header
  • 📤 Response header — sets x-request-id on every response automatically
  • 🎯 Static API — no DI needed, read context from anywhere with RequestContext.get()
  • 🔀 Express & Fastify — works with both adapters out of the box
  • 🔒 Type-safe — generic get<T>(key) for typed access

Installation

npm install @nest-toolbox/request-context

Peer dependencies: @nestjs/common and @nestjs/core (^10.0.0)

Quick Start

// app.module.ts
import { Module } from '@nestjs/common';
import { RequestContextModule } from '@nest-toolbox/request-context';

@Module({
  imports: [RequestContextModule.forRoot()],
})
export class AppModule {}

That's it! Every HTTP request now has a unique context. Access it from anywhere:

import { RequestContext } from '@nest-toolbox/request-context';

// In any service, repository, pipe, or helper — no injection needed
const requestId = RequestContext.requestId;
const userId = RequestContext.get<string>('userId');

API Reference

RequestContextModule.forRoot(options?)

Register the module globally with static options.

RequestContextModule.forRoot({
  requestIdHeader: 'x-correlation-id',
  generateId: () => nanoid(),
  setResponseHeader: true,
  responseIdHeader: 'x-correlation-id',
});

| Option | Type | Default | Description | |--------|------|---------|-------------| | requestIdHeader | string | 'x-request-id' | Header to read the incoming request ID from | | generateId | () => string | crypto.randomUUID | Custom ID generator when no header is present | | setResponseHeader | boolean | true | Whether to set the request ID on the response | | responseIdHeader | string | 'x-request-id' | Response header name for the request ID |

RequestContextModule.forRootAsync(options)

Register the module with async factory injection.

RequestContextModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (config: ConfigService) => ({
    requestIdHeader: config.get('CORRELATION_HEADER', 'x-request-id'),
    setResponseHeader: config.get('SET_RESPONSE_HEADER') !== 'false',
  }),
  inject: [ConfigService],
});

RequestContext.requestId

Get the current request ID. Returns undefined if called outside a request context.

import { RequestContext } from '@nest-toolbox/request-context';

const id = RequestContext.requestId;
// → "550e8400-e29b-41d4-a716-446655440000"

RequestContext.get<T>(key)

Get a typed value from the context store.

const userId = RequestContext.get<number>('userId');
// → 42 (typed as number | undefined)

RequestContext.set(key, value)

Set a value in the context store. No-op if called outside a context.

RequestContext.set('userId', 42);
RequestContext.set('tenantId', 'acme-corp');

RequestContext.has(key)

Check whether a key exists in the context store.

if (RequestContext.has('userId')) {
  // user is authenticated
}

RequestContext.delete(key)

Remove a key from the context store. Returns true if the key existed.

RequestContext.delete('tempToken');

RequestContext.getAll()

Get all key-value pairs as a ReadonlyMap<string, unknown>.

const entries = RequestContext.getAll();
// → Map { 'userId' => 42, 'tenantId' => 'acme-corp' }

RequestContext.run(requestId, fn)

Run a function within a manually created request context. Useful for testing, WebSocket handlers, message queue consumers, and CRON jobs.

const result = await RequestContext.run('test-request-1', async () => {
  RequestContext.set('userId', 1);
  return await myService.doSomething();
});

Common Patterns

Setting user info in a guard

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { RequestContext } from '@nest-toolbox/request-context';

@Injectable()
export class AuthGuard implements CanActivate {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const user = await this.authService.validate(request.headers.authorization);

    // Store user info — available everywhere downstream
    RequestContext.set('userId', user.id);
    RequestContext.set('userRole', user.role);

    return true;
  }
}

Reading tenant ID in a service

import { Injectable } from '@nestjs/common';
import { RequestContext } from '@nest-toolbox/request-context';

@Injectable()
export class InvoiceService {
  async findAll() {
    const tenantId = RequestContext.get<string>('tenantId');

    return this.invoiceRepo.find({
      where: { tenantId },
    });
  }
}

Using with loggers (injecting request ID)

import { LoggerService } from '@nestjs/common';
import { RequestContext } from '@nest-toolbox/request-context';

export class AppLogger implements LoggerService {
  log(message: string) {
    const requestId = RequestContext.requestId ?? 'no-context';
    console.log(`[${requestId}] ${message}`);
  }

  error(message: string, trace?: string) {
    const requestId = RequestContext.requestId ?? 'no-context';
    console.error(`[${requestId}] ${message}`, trace);
  }

  warn(message: string) {
    const requestId = RequestContext.requestId ?? 'no-context';
    console.warn(`[${requestId}] ${message}`);
  }
}

Testing with RequestContext.run()

import { RequestContext } from '@nest-toolbox/request-context';

describe('InvoiceService', () => {
  it('should filter by tenant', async () => {
    const result = await RequestContext.run('test-req-1', async () => {
      RequestContext.set('tenantId', 'acme-corp');
      return invoiceService.findAll();
    });

    expect(result).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ tenantId: 'acme-corp' }),
      ]),
    );
  });
});

Integration with Other Toolbox Packages

@nest-toolbox/http-logger-middleware

The HTTP logger automatically picks up the request ID to correlate log entries:

import { RequestContextModule } from '@nest-toolbox/request-context';
import { HttpLoggerMiddleware } from '@nest-toolbox/http-logger-middleware';

@Module({
  imports: [RequestContextModule.forRoot()],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(HttpLoggerMiddleware).forRoutes('*');
  }
}
// Every log line now includes the request ID for tracing.

@nest-toolbox/typeorm-audit-log

Store the current user in context so audit logs automatically record who made each change:

// In your auth guard
RequestContext.set('userId', user.id);

// The audit log subscriber reads from the same context
// to attribute every INSERT, UPDATE, and DELETE.

Comparison with nestjs-cls

nestjs-cls is a popular, feature-rich CLS library. If you need middleware hooks, proxy providers, or plugin extensibility, it's a great choice.

@nest-toolbox/request-context is intentionally simpler:

| | request-context | nestjs-cls | |---|---|---| | Dependencies | 0 (Node.js built-in) | 1+ | | API surface | Static class, 7 methods | Service + decorators + plugins | | Setup | forRoot(), done | forRoot() + configure enhancer | | Access pattern | RequestContext.get() anywhere | Inject ClsService via DI | | Request IDs | Built-in, auto-generated | Manual setup | | Best for | Simple context + request IDs | Complex CLS with plugins |

If all you need is request IDs and a lightweight key-value store per request, this package gets out of your way.

Types

All types are exported from the package:

| Type | Description | |------|-------------| | ContextStore | Internal store shape (requestId + values map) | | RequestContextOptions | Static options for forRoot() | | RequestContextAsyncOptions | Async options for forRootAsync() |

License

MIT © Bogdan Lupu