The NestJS Kafka transport still runs on unmaintained kafkajs. I built a drop-in replacement that stays wire-compatible, so you can migrate one service at a time
Two years, 60+ comments, no shipped fix. That's the state of the NestJS issue asking to stop depending on kafkajs: https://github.com/nestjs/nest/issues/13223
Core won't swap it (backwards compatibility). The maintainer suggested "a separate transport strategy so people migrate over time". The one snippet posted was event-only and, quoting a team that tried it in production, "full of any, no reconnection support".
So I built that transport: nestjs-kafka-transport, on top of u/platformatic/kafka (pure JS, written by Node core contributors).
Repo: https://github.com/fadiroot/nestjs-kafka-transport
npm: https://www.npmjs.com/package/nestjs-kafka-transport
The part that matters: it speaks the exact same wire format as the built-in transport. Same kafka_correlationId / kafka_replyTopic / kafka_replyPartition headers, same <pattern>.reply topics, same parser rules. A service on the new transport talks to services still on Transport.KAFKA. There are e2e tests for both directions (kafkajs ClientKafka to the new server, the new client to the built-in ServerKafka). Migrate consumers first, one service at a time, no big bang.
Your controllers don't change; only main.ts does:
before: { transport: Transport.KAFKA, options: { client: { brokers }, consumer: { groupId: 'orders' } } }
after: { strategy: new KafkaTransportServer({ client: { bootstrapBrokers: brokers }, consumer: { groupId: 'orders' } }) }
What you get on top:
• Request-reply with a real reply-partition assigner (every client owns a partition of each reply topic; that's what the snippet in the thread was missing).
• KafkaRetriableException → re-run with exponential backoff; offsets committed after each handled record (at-least-once); per-partition ordering preserved.
• Numbers, booleans and null come back as numbers, booleans and null, not "6", via a content-type header that kafkajs peers simply ignore.
• Options typed all the way down, no any in the public API. CI on Node 22/24 against Kafka 3.9 and 4.0.
Honest limits: v0.1. Node 22.22 or newer (Platformatic's floor). RegExp patterns resolve against topics that exist at startup. Next: dead-letter/retry topics with Nest's kafka_dlt-* headers, manual commits, batch handlers, OpenTelemetry, in that order unless you tell me otherwise.
If you run NestJS + Kafka in production: try it on one consumer and tell me what breaks. I'll be in the comments.