$ open source · GPL-3.0 — need a commercial license? imqueue.com →
← all posts

@imqueue vs NestJS microservices: framework vs transport

NestJS is a full application framework with a microservices module; @imqueue is a focused RPC transport. They're not really competitors — here's how they differ and how they can work together.

NestJS comes up in almost every conversation about TypeScript back-ends, and it has a microservices module, so it's natural to line it up against @imqueue. But they sit at different layers, and understanding that is more useful than declaring a winner. (NestJS details reflect its documented behavior at the time of writing.)

Different layers of the stack

NestJS is a full application framework: dependency injection, modules, controllers, guards, interceptors, an opinionated structure for the whole app. Its microservices module lets a Nest app send and receive messages over a transporter (Redis, NATS, Kafka, RabbitMQ, MQTT, gRPC, TCP), using decorators like @MessagePattern() to bind handlers to message patterns.

@imqueue is not an application framework. It's a focused RPC layer: self-describing service classes over a message queue, with typed clients generated from the services. It doesn't have opinions about DI, HTTP controllers, or app structure — it's the piece that moves typed calls between services.

So the honest framing is: NestJS is how you might build a whole service; @imqueue is how services call each other.

The typing difference

With the NestJS microservices module, a caller uses a ClientProxy and sends to a message pattern; the payload and response types are something you annotate and keep correct yourself. It's decorator-driven and clean, but the contract between caller and handler isn't automatically derived.

@imqueue generates the client from the service, so the remote call is typed end-to-end without you maintaining a matching interface on the caller side. If a method's signature changes, regenerating the client turns mismatches into compile errors.

Feature scope & structure

NestJS gives you a great deal of structure and a huge ecosystem — validation pipes, config, testing utilities, an enormous plugin catalog. If you want a framework to build entire services in, that's its job.

@imqueue keeps its footprint small and pairs with @imqueue/cli for scaffolding services, wiring VCS/CI/registry providers, generating clients, and running a local fleet. You bring your own app structure; @imqueue handles the inter-service RPC.

Can you use them together?

Largely, yes — they're not mutually exclusive. You could build a service's internals however you like and use @imqueue as the typed transport between your back-end services, while a NestJS app handles an HTTP edge. The main thing to decide is which tool owns service-to-service calls, so you're not running two RPC mechanisms for the same traffic.

Quick comparison

@imqueue NestJS (microservices)
Layer RPC transport + typed clients Full application framework
Transport Message queue Pluggable (Redis, NATS, Kafka, gRPC, …)
Inter-service typing Client generated from service Annotate patterns/payloads yourself
App structure Unopinionated Opinionated (DI, modules, controllers)
Scope Small, focused Broad ecosystem

How to choose

  • Choose NestJS if you want a complete, opinionated framework to build services in, with a large ecosystem, and you're happy managing inter-service contract types by hand.
  • Choose @imqueue if you specifically want typed, low-ceremony RPC between services and don't want a full framework dictating your app structure.
  • Consider both if you like Nest for building a service and want @imqueue as the typed wire between services.

To see @imqueue's model in practice, the Tutorial builds a multi-service app step by step.


Building on @imqueue? The open-source packages live on GitHub and the docs at imqueue.org. Shipping inside a closed-source product? See commercial licensing & support.