{"id":45593,"library":"node-redis-streams","title":"node-redis-streams","description":"Redis Streams Library for Node.js/TypeScript with full consumer group recovery. Version 1.1.5 provides Kafka-like consumer group semantics on top of Redis Streams, including automatic reclaiming of abandoned messages from failed consumers. Key differentiators include batch acknowledgment (XACK), configurable block intervals, and a dedicated reclaim loop. It exposes a Consumer class that wraps XREADGROUP, XACK, and XCLAIM commands. The library is TypeScript-friendly with bundled types. Released under MIT, with no significant recent updates indicating maintenance mode.","status":"active","version":"1.1.5","language":"javascript","source_language":"en","source_url":"https://github.com/danthegoodman1/node-redis-streams","tags":["javascript","typescript"],"install":[{"cmd":"npm install node-redis-streams","lang":"bash","label":"npm"},{"cmd":"yarn add node-redis-streams","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-redis-streams","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for Redis client instance passed to Consumer constructor.","package":"ioredis","optional":false}],"imports":[{"note":"CommonJS pattern; ESM import is not officially documented but may work.","wrong":"const nrs = require('node-redis-streams'); const consumer = new nrs.Consumer()","symbol":"Consumer","correct":"const { Consumer } = require('node-redis-streams')"},{"note":"Named export, not default. Works with TypeScript and ESM.","wrong":"import Consumer from 'node-redis-streams'","symbol":"Consumer","correct":"import { Consumer } from 'node-redis-streams'"},{"note":"Type import for TypeScript users; interface exported as IConsumerOptions.","wrong":"","symbol":"IConsumerOptions","correct":"import type { IConsumerOptions } from 'node-redis-streams'"}],"quickstart":{"code":"const Redis = require('ioredis');\nconst { Consumer } = require('node-redis-streams');\n\nconst redisClient = new Redis();\n\nconst consumer = new Consumer({\n  consumerName: 'my-consumer',\n  groupName: 'my-group',\n  readItems: 10,\n  recordHandler: async (record) => {\n    console.log('Processing record:', record.id, record.message);\n  },\n  errorHandler: async (record, err) => {\n    console.error('Error processing record', record.id, err);\n  },\n  redisClient,\n  streamName: 'my-stream',\n  blockIntervalMS: 1000,\n  checkAbandonedIntervalMS: 5000\n});\n\nconsumer.StartConsuming().then(() => {\n  console.log('Consuming started');\n});\n\n// Graceful shutdown\nprocess.on('SIGTERM', async () => {\n  await consumer.StopConsuming();\n  redisClient.quit();\n});","lang":"javascript","description":"Creates a Redis Stream consumer group consumer, starts consuming with automatic reclaim, and handles graceful shutdown."},"warnings":[{"fix":"Ensure consumer.StartConsuming() is called.","message":"Do not forget to call StartConsuming() after creating the Consumer instance, or no records will be processed.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Implement idempotent record processing or use a database to track processed record IDs.","message":"The recordHandler is called for each record in a batch; all records are XACK'd only after the batch completes. If an error occurs partway, already-processed records are acknowledged (XACK), but the rest are not. This can lead to duplicate processing on restart if records were processed but not XACK'd.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Always call consumer.StopConsuming() before shutdown, and then quit the Redis client.","message":"If you stop the process without calling StopConsuming(), records may remain pending in the consumer group and require manual XCLAIM or XACK.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Use 'checkAbandonedIntervalMS' instead of 'checkAbandonedMS'.","message":"The 'checkAbandonedMS' option in ConsumerOptions is misspelled; the correct option is 'checkAbandonedIntervalMS'. Using 'checkAbandonedMS' may be silently ignored.","severity":"deprecated","affected_versions":"<=1.1.5"},{"fix":"Use 'StartConsuming()' instead of 'startConsuming()'.","message":"In version 1.0.0, the method 'StartConsuming' was renamed from 'startConsuming' (camelCase) to PascalCase. The old name will cause a runtime error if used.","severity":"breaking","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'/typescript':11 '1.1.5':18 'abandon':35 'acknowledg':44 'automat':32 'batch':43 'block':47 'bundl':73 'class':58 'command':65 'configur':46 'consum':14,23,39,57 'dedic':51 'differenti':41 'expos':55 'fail':38 'friend':71 'full':13 'group':15,24 'includ':31,42 'indic':83 'interv':48 'javascript':86 'kafka':21 'kafka-lik':20 'key':40 'librari':7,67 'like':22 'loop':53 'mainten':84 'messag':36 'mit':77 'mode':85 'node':2 'node-redis-stream':1 'node.js':10 'node.js/typescript':9 'provid':19 'recent':81 'reclaim':33,52 'recoveri':16 'redi':3,5,29 'releas':75 'semant':25 'signific':80 'stream':4,6,30 'top':27 'type':74 'typescript':70,87 'typescript-friend':69 'updat':82 'version':17 'wrap':60 'xack':45,62 'xclaim':64 'xreadgroup':61","created_at":"2026-06-07T12:55:46.328063+00:00","updated_at":"2026-06-07T12:55:46.328063+00:00","problems":[{"fix":"Use named import: import { Consumer } from 'node-redis-streams' (CommonJS: const { Consumer } = require('node-redis-streams')).","cause":"Using default import instead of named import (e.g., import nrs from 'node-redis-streams' instead of import { Consumer } from 'node-redis-streams').","error":"TypeError: nrs.Consumer is not a constructor"},{"fix":"Ensure you pass a valid ioredis instance as 'redisClient'.","cause":"Passing an invalid or non-ioredis client to the Consumer constructor.","error":"RedisClient is not defined"},{"fix":"Create the consumer group using XGROUP CREATE or use a library that auto-creates groups.","cause":"The consumer group has not been created on the stream before starting the consumer.","error":"Error: Consumer group 'my-group' does not exist"},{"fix":"Check if consumer is already started (e.g., maintain a flag) or call StopConsuming() before restarting.","cause":"Calling StartConsuming() on a Consumer that is already consuming.","error":"Unhandled promise rejection: Error: Cannot StartConsuming more than once"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/danthegoodman1/node-redis-streams#readme","github":"https://github.com/danthegoodman1/node-redis-streams","docs":null,"changelog":null,"pypi":null,"npm":"node-redis-streams","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","messaging"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}