Production-ready NestJS libraries by NestJSTools

Open-source libraries for NestJS focused on accelerating development while keeping patterns consistent.

TypeScript-first
NestJS-friendly
Maintained & documented

Libraries

Modular, lightweight and production-ready tools for the NestJS ecosystem.

@nestjstools/messaging

Featured

A production-ready NestJS messaging library for event-driven and distributed systems. Unified API across RabbitMQ, Google Pub/Sub, Amazon SQS, Azure Service Bus, NATS and Redis with retries and DLQ support.

@nestjstools/clock

Featured

Deterministic and testable time abstraction for NestJS applications. Simplify scheduling, time-based workflows and domain logic with injectable clock providers.

@nestjstools/domain-driven-starter

A clean architecture starter template for NestJS focused on Domain-Driven Design and modular boundaries. Build aggregates faster with built-in domain primitives like UUID value objects, base entities and domain utilities.

@nestjstools/apisix-client

A lightweight APISIX client for NestJS and Node.js. Manage routes, upstreams and plugins programmatically with strong typing and clean API integration.

Why NestJS Tools?

Built for Distributed Systems - Messaging lib

Designed for event-driven and microservice architectures. Supports reliable messaging patterns, retries, dead-letter queues and broker abstraction out of the box.

Reduce Boilerplate. Ship Faster.

Prebuilt abstractions, opinionated defaults, and reusable building blocks remove repetitive setup code. Focus on business logic instead of infrastructure wiring.

Production-Ready Defaults

Sensible configuration, strong typing and integration patterns that work in real-world production environments, not just demos.

Built for NestJS Framework

Built specifically for the NestJS ecosystem with first-class support for dependency injection, modules, decorators, and clean architectural separation.

TypeScript-First

Fully typed APIs and explicit contracts to reduce runtime errors, improve maintainability, and scale codebases with confidence.
NestJS Messaging Library

A NestJS messaging library for event-driven and distributed systems. Use a unified API across popular message brokers and implement reliable messaging patterns without boilerplate.

Works with RabbitMQ, Google Pub/Sub, Amazon SQS, Azure service bus, Nats, and Redis with production-friendly defaults like retries, dead-letter queues (DLQ) and more.

NestJS messaging library preview with RabbitMQ, Kafka and Redis adapters

See the difference

Stop fighting boilerplate. Start building features.

Standard Node.js Config (RabbitMQ)

const amqp = require('amqplib');

class OrderCreatedHandler {
  async handle(message) {
    console.log('Processing order:', message.orderId);
  }
}

async function bootstrap() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();
  const handler = new OrderCreatedHandler();

  await channel.assertQueue('orders.created', {
    durable: true,
  });

  channel.consume('orders.created', async (msg) => {
    if (!msg) return;

    try {
      // manual deserialization
      const content = msg.content.toString();
      const payload = JSON.parse(content);

      // call handler manually
      await handler.handle(payload);

      // manual ack
      channel.ack(msg);
    } catch (error) {
      console.error('Message processing failed:', error);

      // manual retry / DLQ decision
      channel.nack(msg, false, false);
    }
  });

  console.log('Listening on orders.created');
}

bootstrap().catch(console.error);

Verbose, error-prone boilerplate and complex manual ack logic.

NestJSTools Messaging

import { Injectable, Module } from '@nestjs/common';
import { IMessageHandler, MessageHandler, MessagingModule } from '@nestjstools/messaging';
import { MessagingRabbitmqExtensionModule } from '@nestjstools/messaging-rabbitmq-extension';

// Handler
@Injectable()
@MessageHandler('orders.created')
export class OrderCreatedHandler implements IMessageHandler<OrderCreatedMessage> {
  async handle(message: OrderCreatedMessage): Promise<void> {
    console.log('Processing order:', message.orderId);
  }
}

// RabbitMQ config
@Module({
  imports: [
    MessagingRabbitmqExtensionModule,
    MessagingModule.forRoot({
      channels: [
        new RmqChannelConfig({
            name: 'async-command',
            connectionUri: rabbitMqUrl,
            exchangeName: 'my_app_command.exchange',
            bindingKeys: ['my_app_command.#'],
            exchangeType: ExchangeType.TOPIC,
            queue: 'my_app.command',
            avoidErrorsForNotExistedHandlers: false,
            deadLetterQueueFeature: true,
            middlewares: [
              MiddlewareExample,
            ],
            autoCreate: true,
            enableConsumer: true,
        }),
      ],
    }),
  ],
})
export class AppModule {}

Declarative handlers with transport-specific config options.

outgoing_mail

Dispatch Stage

Message dispatch Side
Before DispatchAfter Dispatch
settings_input_component

Execution Stage

Handler Side
Before HandleAfter Handle
task_alt

Outcome Stage

Final State
On SuccessOn Failure
@Injectable()
@MessagingLifecycleHook(LifecycleHook.BEFORE_MESSAGE_NORMALIZATION)
export class BeforeMessageNormalizationHook implements MessagingLifecycleHookListener {
  constructor(private readonly logger: Logger) {}

  async on(message: MessagingData): Promise<void> {
    this.logger.log('Message received before normalization');
  }
}

Full control with message lifecycle hooks

Tap into every stage of message processing. From dispatch to consumption - add logging, tracing, validation or custom logic without touching your handlers.

auto_fix_high
Focus on feature delivery in consistent way

Build cross-cutting features without boilerplate.

  • check_circle Global Hooks
  • check_circle Ready for metrics & tracing integration
  • check_circle Dependency Injection
  • check_circle Async/Await Support