{"id":15776,"library":"rabbitmq-stream-js-client","title":"RabbitMQ Stream Client for JavaScript/TypeScript","description":"This library provides a client for the RabbitMQ stream protocol, enabling JavaScript and TypeScript applications to interact with RabbitMQ Streams. Designed for high-throughput, low-latency messaging, it facilitates publishing and consuming messages with advanced features like super streams, deduplication, and single active consumers. The current stable version is 1.0.0, released in April 2024. The project exhibits an active release cadence with frequent updates and bug fixes, indicated by multiple minor and patch releases leading up to 1.0.0, addressing features like external authentication, SSL options, and enhanced connection management. Key differentiators include its native support for RabbitMQ's stream protocol, enabling advanced features for horizontal scaling, message deduplication for exactly-once semantics, and single active consumer patterns for workload distribution. It also provides robust connection handling, including explicit connection pooling and automatic reconnect mechanisms, making it suitable for high-reliability, distributed systems.","status":"active","version":"1.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/coders51/rabbitmq-stream-js-client","tags":["javascript","RabbitMQ","Stream","typescript"],"install":[{"cmd":"npm install rabbitmq-stream-js-client","lang":"bash","label":"npm"},{"cmd":"yarn add rabbitmq-stream-js-client","lang":"bash","label":"yarn"},{"cmd":"pnpm add rabbitmq-stream-js-client","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"For modern TypeScript and ESM projects, prefer named imports. The 'require' style is shown in older examples but may cause issues with type inference or bundlers.","wrong":"const rabbit = require('rabbitmq-stream-js-client');\nconst client = await rabbit.connect(...);","symbol":"connect","correct":"import { connect } from 'rabbitmq-stream-js-client';"},{"note":"While 'connect' is the primary entry point, importing StreamClient is useful for type annotations or if you need to extend its functionality.","symbol":"StreamClient","correct":"import { StreamClient } from 'rabbitmq-stream-js-client';"},{"note":"Publisher instances are typically created via `client.declarePublisher()`, but the type can be imported for explicit typing.","symbol":"Publisher","correct":"import { Publisher } from 'rabbitmq-stream-js-client';"}],"quickstart":{"code":"import { connect } from 'rabbitmq-stream-js-client';\nimport { Buffer } from 'buffer'; // Node.js Buffer is needed for message content\n\nasync function runRabbitStreamExample() {\n  const client = await connect({\n    hostname: process.env.RABBITMQ_HOST ?? 'localhost',\n    port: parseInt(process.env.RABBITMQ_STREAM_PORT ?? '5552', 10),\n    username: process.env.RABBITMQ_USERNAME ?? 'rabbit',\n    password: process.env.RABBITMQ_PASSWORD ?? 'rabbit',\n    vhost: process.env.RABBITMQ_VHOST ?? '/',\n  });\n\n  const streamName = 'my-first-stream';\n\n  // Declare a stream (if it doesn't exist, it will be created)\n  await client.declareStream({ stream: streamName });\n\n  const publisher = await client.declarePublisher({\n    stream: streamName,\n    publisherRef: 'my-publisher-ref',\n  });\n\n  const messageContent = Buffer.from('Hello, RabbitMQ Stream!');\n  await publisher.send(messageContent);\n  console.log('Message published:', messageContent.toString());\n\n  const consumer = await client.createConsumer(\n    {\n      stream: streamName,\n      consumerRef: 'my-consumer-ref',\n      offset: 'first',\n    },\n    (message) => {\n      console.log('Message consumed:', message.getData().toString());\n      consumer.close(); // Close consumer after first message for this example\n    }\n  );\n\n  // Give some time for the consumer to receive the message\n  await new Promise(resolve => setTimeout(resolve, 1000));\n\n  await publisher.close();\n  await client.close();\n  console.log('Client and publisher closed.');\n}\n\nrunRabbitStreamExample().catch(console.error);\n","lang":"typescript","description":"Demonstrates connecting to RabbitMQ Stream, declaring a stream, publishing a message, and consuming it."},"warnings":[{"fix":"Review connection management strategies. The client now handles auto-reconnecting internally. Refer to updated README examples for managing connection stability, e.g., how to handle auto-reconnects as shown in the v0.4.0 changelog.","message":"The `Connection closed` listener is no longer called by the client. Applications relying on this specific event for connection state management will need to adjust.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Implement a robust strategy for generating unique and monotonic `publishingId`s, potentially using a shared sequence generator or UUIDs with external storage for persistence across application restarts.","message":"When using message deduplication with `publisherRef` or `publishingId`, it is solely the user's responsibility to guarantee the uniqueness and incremental order of these IDs. RabbitMQ Stream does not enforce or manage these across producers, which can lead to message loss or unexpected deduplication if not handled correctly.","severity":"gotcha","affected_versions":">=0.5.0"},{"fix":"Always provide the `ca` (Certificate Authority) certificate when connecting through TLS/SSL in production environments to ensure proper certificate chain validation and secure communication.","message":"The `ca` parameter for SSL/TLS connections is optional. If not provided, the client will rely on the system's default CAs or accept self-signed certificates depending on Node.js configuration, which might be a security risk in production environments.","severity":"gotcha","affected_versions":">=0.6.2"},{"fix":"Rely on the client's public API for connection management. Avoid direct manipulation of internal connection objects, as the library now explicitly manages connection lifecycles within its pool.","message":"Internal refactoring around connection pooling (e.g., connection pool as an instance, managing connections inside the pool) in v0.6.2 might affect applications that previously attempted to interfere with or manage underlying connections directly.","severity":"breaking","affected_versions":">=0.6.2"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure all messages intended for RabbitMQ Streams are published using `rabbitmq-stream-js-client`. Do not mix publishing messages to streams using `amqplib` or other AMQP 0-9-1 clients, as the stream protocol has its own specific message structure.","cause":"Messages published via the AMQP 0-9-1 protocol (e.g., using `amqplib`) might not be compatible with the RabbitMQ Stream protocol due to differences in message formatting and properties.","error":"Error: Code 83 (NOT_SUPPORTED_FORMAT) when message is published using amqplib"},{"fix":"Verify that your RabbitMQ server is running and the Stream plugin is enabled. Check the `hostname` and `port` (default 5552 for streams) in your connection configuration. Ensure no firewall rules are preventing the connection.","cause":"The client could not establish a connection to the RabbitMQ Stream server. This typically means the server is not running, is not listening on the specified host/port, or a firewall is blocking the connection.","error":"Error: connect ECONNREFUSED 127.0.0.1:5552"},{"fix":"Use ESM named imports: `import { connect } from 'rabbitmq-stream-js-client';`. If you must use `require`, destructure it: `const { connect } = require('rabbitmq-stream-js-client');`.","cause":"You are likely attempting to use a CommonJS `require` syntax in a TypeScript or ESM project without correctly destructuring the module's named exports.","error":"TypeError: rabbit.connect is not a function"}],"ecosystem":"npm"}