Skip to main content

State 005: Swapping Socket.IO for NATS

Published: Tuesday, March 31, 2026

State 005-messaging-nats-replacement is in place as the messaging architecture transition on top of 004-postgres-database-replacement.

For a long time, TraderX used a deliberately simple messaging layer that was easy to run but increasingly brittle as we pushed toward more realistic multi-service evolution. The old Socket.IO-centric setup worked, but it forced us into awkward conventions for server-to-server eventing and created fragility when we wanted clearer protocol behavior.

What Changed​

We replaced the trade-feed Socket.IO runtime role with a nats-broker component and migrated eventing to NATS subjects.

This change keeps baseline user flows intact, but modernizes the transport layer:

  • backend pub/sub now uses a broker pattern designed for service-to-service communication,
  • browser streaming now uses NATS WebSocket routing through ingress (/nats-ws),
  • runtime remains approachable in Docker Compose for this branch.

Code and specs:

Why NATS​

We selected NATS because it is a better fit for this stage of TraderX evolution:

  • lightweight and simple to operate locally,
  • strong multi-language clients (Java, .NET, Node.js, Python),
  • clean subject model and wildcard subscriptions,
  • request/reply support with room for future durability extension,
  • browser support through websocket-compatible clients.

The formal state-scoped rationale is captured in:

Why This Was Easier With SpecKit​

This change is a clear example of why we moved to SpecKit-first maintenance:

  • requirements and deltas were defined once in the feature pack,
  • code generation and runtime scripts were updated from that intent,
  • docs and learning guides were regenerated with lineage and compare links,
  • tests and conformance checks were updated as part of the same state delta.

Instead of manually curating long-lived code branches, we changed the system of record and regenerated state outputs.

Track Implications​

State 005 sets up the messaging baseline that later states inherit:

  • 006 adds observability,
  • 007 layers pricing streams on top of NATS,
  • 008 layers order matching on top of pricing and NATS.

This keeps transitions explicit, diffs reviewable, and runnable outputs available at each step.