I’ve spent the last while building a saga orchestration engine for the TypeScript and Node ecosystem, because I kept running into the same gap.
Queues like BullMQ are great for one-off jobs, but they don’t help much once you need durable, multi-step workflows that react to multiple events over time. On the other end, Temporal is powerful, but often feels heavy if all you want is message-driven orchestration using your existing infrastructure and databases.
In the .NET world, MassTransit’s saga pattern solves this nicely. I couldn’t find a clean equivalent in TypeScript, so I built one.
Saga Bus is a TypeScript-first, MassTransit-style saga engine for Node and Bun. It provides durable saga state stored in Postgres or Prisma with pluggable stores, message-driven orchestration over RabbitMQ with an in-memory transport for tests, explicit retries, backoff and dead-letter queues, fully type-safe saga definitions using a small DSL, and framework-agnostic usage across plain Node workers, Next.js producers, and NestJS applications.
A saga ends up looking like a proper state machine rather than ad-hoc queue handlers, and it scales horizontally across workers using optimistic concurrency.
deanforan•1h ago
I’ve spent the last while building a saga orchestration engine for the TypeScript and Node ecosystem, because I kept running into the same gap. Queues like BullMQ are great for one-off jobs, but they don’t help much once you need durable, multi-step workflows that react to multiple events over time. On the other end, Temporal is powerful, but often feels heavy if all you want is message-driven orchestration using your existing infrastructure and databases.
In the .NET world, MassTransit’s saga pattern solves this nicely. I couldn’t find a clean equivalent in TypeScript, so I built one.
Saga Bus is a TypeScript-first, MassTransit-style saga engine for Node and Bun. It provides durable saga state stored in Postgres or Prisma with pluggable stores, message-driven orchestration over RabbitMQ with an in-memory transport for tests, explicit retries, backoff and dead-letter queues, fully type-safe saga definitions using a small DSL, and framework-agnostic usage across plain Node workers, Next.js producers, and NestJS applications. A saga ends up looking like a proper state machine rather than ad-hoc queue handlers, and it scales horizontally across workers using optimistic concurrency.
GitHub: https://github.com/d-e-a-n-f/saga-bus Docs: https://d-e-a-n-f.github.io/saga-bus
This is early but functional, and I’m mainly looking for feedback from people running distributed workflows in Node.
Does this solve a real problem for you? Where does it fall down compared to what you’re using today? What transports or stores would you expect first?
Happy to answer questions or explain design decisions.