Production-ready NestJS libraries by NestJSTools
Open-source libraries for NestJS focused on accelerating development while keeping patterns consistent.

Libraries
Modular, lightweight and production-ready tools for the NestJS ecosystem.
Why NestJS Tools?
Built for Distributed Systems - Messaging lib
Reduce Boilerplate. Ship Faster.
Production-Ready Defaults
Built for NestJS Framework
TypeScript-First
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.

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.
Dispatch Stage
Message dispatch SideExecution Stage
Handler SideOutcome Stage
Final State@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.
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