Features
NUTS turns a NATS JetStream into a browser-friendly, replayable event stream — with the operational guard rails you need to run it in production.
Streaming
Real-time SSE
Stream NATS messages directly to browsers using the standard
EventSource API. No WebSocket bridge, no polling, no client SDK.
Multiple topics per connection
Subscribe to several NATS subjects in a single SSE stream via repeated
?topic= params or path-based shorthand.
Topic prefixing
Apply a server-side topic_prefix so clients use friendly
names while NUTS subscribes to the fully-qualified NATS subjects.
Heartbeat keep-alives
Configurable heartbeat frames keep idle connections open through proxies and CDNs.
Persistence & replay
JetStream-backed durability
Messages live in JetStream — NUTS just routes them to subscribers, so retention, deduplication, and storage policies stay in NATS.
Resumable streams
Reconnecting clients pick up exactly where they left off using
?last-id= or the standard Last-Event-ID header.
Browser EventSource sends the header for free.
Replay storm guards
Bound large catch-ups with replay_max_messages and
replay_window so a single stale client can't drag the
server through tens of thousands of historical events.
No silent message loss
Slow clients are disconnected before queued messages are dropped — they reconnect with their last event ID and resume cleanly.
Security & auth
JWT subscriber auth
HMAC-signed JWTs with per-topic subscribe claims, accepted
from Authorization: Bearer or a configurable cookie for
browser EventSource clients.
NATS authentication
Connect to NATS using credentials files, tokens, or user/password — keep the broker secured independently of subscriber auth.
NATS TLS & mTLS
Optional nats_tls_ca, nats_tls_cert, and
nats_tls_key directives for encrypted, mutually
authenticated NATS connections.
CORS done right
Echoes Origin from the allow-list, adds Vary: Origin,
and only advertises credentials for explicitly listed origins —
no accidental wildcard credential leaks.
Operations
Prometheus metrics
Built-in nuts_* counters and gauges — active connections,
messages delivered, slow-client disconnects, replay stats, rejected
connections, and more.
Liveness & readiness probes
Separate /livez and /readyz endpoints for
Kubernetes probes and load-balancer health checks — readiness
actually verifies the NATS connection and stream.
Connection caps
max_connections bounds concurrent SSE streams; rejected
clients receive 503 with Retry-After instead
of degrading the whole instance.
Per-frame write bounds
Optional dispatch_timeout and write_timeout
keep slow downstream connections from tying up a handler indefinitely.
Hub discovery
Optional Link header with rel="nuts" lets
clients discover the hub URL automatically from any response that
carries it.
Structured logs
Every stream emits structured fields — topics,
subjects, replay_mode,
disconnect_reason — ready for log aggregation and
incident response.
Deployment
Caddy native
First-class Caddy module — install with xcaddy,
configure via Caddyfile or JSON, and inherit Caddy's TLS and routing.
Prebuilt Docker image
Multi-arch idcttech/nuts image on Docker Hub for
amd64 and arm64 — mount a Caddyfile and go.
Compose-ready
Reference docker-compose.yml in the repo brings up NATS
with JetStream and NUTS together for local development.
Ready to wire it up?
Build with xcaddy or pull the Docker image — you'll be streaming in minutes.