Why JetStream?
Use whenyou are deciding whether the built-in NestJS NATS transport is already enough.
You getthe line where Core NATS stops being enough, and what this library adds over raw JetStream.
The built-in NestJS NATS transport runs on Core NATS: fire-and-forget pub/sub with no persistence. This page marks the line where that stops being enough.
Stay on the built-in transport when
- Messages are idempotent hints, like a cache invalidation or a metric update.
- Losing one is acceptable, because retrying or recomputing is cheap.
- No consumer needs history.
- Latency is the thing you tune for, ahead of durability.
Persistence costs disk I/O, stream provisioning and consumer state. If the list above describes your workload, stop here.
Where Core NATS drops messages
| Situation | Core NATS | With this library |
|---|---|---|
Pod gets SIGTERM with 40 messages in flight | All 40 are gone: the publisher was already acked | Messages return to pending, the next pod takes them |
| Downstream is down for 3 minutes | 200 events delivered into the void | Events wait in the stream, processed in order on return |
| Handler throws on a specific payload | Lost on the first throw | Retried to max_deliver (default 3), then written to the DLQ stream with tracking headers |
| New service needs the last 7 days | Custom backfill job against the database | A consumer with deliver_policy by start time replays the stream |
| New replica missed a broadcast during startup | No answer | Per-service durable consumers catch it up |
The first row needs one line from you: call app.enableShutdownHooks() so NestJS runs the shutdown lifecycle. See Graceful Shutdown and Dead Letter Queue.
What the library adds over raw JetStream
Driving JetStream from the @nats-io/* packages directly means building this yourself:
Delivery
- Workqueue events: at-least-once, one handler instance per message
- Broadcast events: fan-out to every subscribing service
- Ordered events: strict sequence over ephemeral consumers
- RPC in Core or JetStream mode
Durability and recovery
- Dead letter queue for messages that exhaust every retry
- Stream migration for locked settings such as storage type
- Self-healing consumers after broker restarts and external deletion
- Graceful shutdown that drains in-flight work first
Publishing
- Per-message TTL
- Delayed delivery and cron and interval schedules, fired by NATS itself
- Deduplication by deterministic message ID
- Publisher-only mode for gateways
Operations
- Health indicator for Kubernetes probes
- Lifecycle hooks for metrics, tracing and alerting
- Handler metadata registry over NATS KV
- Ack extension for handlers slower than
ack_wait
Every item sits behind @EventPattern, @MessagePattern and ClientProxy.
HTTP, Core NATS or JetStream
| Best at | Cost | |
|---|---|---|
| HTTP | Request/response with mature tooling | Couples caller and callee in time; retries and circuit breakers are yours |
| Core NATS | Low-latency in-cluster RPC | No persistence |
| JetStream | Work that must not be lost | Disk I/O, stream and consumer state |
Most systems run all three. HTTP serves the edge, and internally the split is Core NATS for hot calls against JetStream for durable events. RPC mode is per module (rpc.mode: 'core' or 'jetstream') while @EventPattern stays on durable delivery.
Other NestJS NATS packages
| Package | Focus |
|---|---|
@nestjs/microservices | Official Core NATS integration, maintained by the NestJS team |
@nestjs-plugins/nestjs-nats-jetstream-transport | Community JetStream transport |
@mirasys/nestjs-jetstream-transporter | Custom JetStream transporter |
@horizon-republic/nestjs-jetstream | This library: DLQ, health indicators, broadcast, ordered delivery, tracing |
Don't use this library when
- You don't run NATS. Operating it costs real time. Solve the problem you have now.
- Your workload is request/response without durability. The built-in transport is lighter.
- You need cross-region replication under strict latency SLAs. Mirrors and sources exist, though tuning them for multi-region is its own project.
- You're prototyping.
Next
- Installation
- Quick Start: the four-step example
- Events and RPC: the patterns you use daily
- Module Configuration, DLQ, Health Checks, Graceful Shutdown