At-least-once delivery, bounded retries
Every event is acknowledged after the handler returns. Failures retry with exponential backoff and land in a typed dead-letter queue if the budget is exhausted.
The NATS JetStream transport NestJS microservices need — durable, retried, traced — under the same @EventPattern decorators you already use.
Each one drops in behind the decorators you already use. Same behavior in dev, staging, and prod.
Every event is acknowledged after the handler returns. Failures retry with exponential backoff and land in a typed dead-letter queue if the budget is exhausted.
One @Broadcast() event reaches every running pod — with no double-processing on the workqueue side.
Request/reply with timeouts, typed responses, and the RecordBuilder for headers.
W3C traceparent propagated through every hop. Wire to OpenTelemetry in three lines.
Stable subject keys give you single-consumer ordering without giving up horizontal scale on the rest of the workload.
Same NestJS surface area you use today. The library does the JetStream work underneath.
import { Module } from '@nestjs/common';
import { JetstreamModule } from '@horizon-republic/nestjs-jetstream';
@Module({
imports: [
JetstreamModule.forRoot({
servers: ['nats://localhost:4222'],
}),
],
})
export class AppModule {}import { Controller, Logger } from '@nestjs/common';
import { EventPattern, Payload } from '@nestjs/microservices';
// At-least-once. Retries on throw. Traced end-to-end.
@Controller()
export class OrdersController {
private readonly log = new Logger(OrdersController.name);
@EventPattern('orders.created')
async onCreated(@Payload() order: Order) {
await this.billing.charge(order);
this.log.log(`charged ${order.id}`);
}
@MessagePattern('orders.lookup')
lookup(@Payload() id: string) {
return this.orders.find(id);
}
}Provisions streams & consumers on boot, routes messages to decorated handlers, drains cleanly on shutdown.
Twelve features in one transport. No surprises across environments.
Workqueue retention with explicit ack after handler resolves.
Per-key ordering on the same partition with stable subjects.
One emit reaches every replica; nothing is shared by accident.
Bounded retries, then a typed sink with original headers preserved.
Drains in-flight handlers, flushes acks, closes the connection.
Drop-in isHealthy() indicator for k8s probes.
Request/reply with deadlines, headers, and typed responses.
Per-message delay or absolute deliver-at, native to the stream.
Expire stale messages before they reach a consumer.
W3C trace context on every hop. OpenTelemetry-compatible.
Stable, documented header schema for tracing & correlation.
Subscribe to TransportEvent for ack, nak, redelivery.
Five-minute quick start. Then drop into your existing NestJS module graph.