{"id":17458,"library":"rate-limit-redis","title":"Redis Store for Express Rate Limit","description":"rate-limit-redis is a Redis-backed storage engine designed for the `express-rate-limit` middleware, enabling distributed rate limiting across multiple application instances. It is currently at stable version 4.3.1, with frequent minor and patch releases, as indicated by the recent changelog entries, reflecting an active maintenance schedule. This library supports popular Redis clients such as `node-redis` and `ioredis`, and also explicitly lists compatibility with `redict` and `valkey`, offering flexibility in deployment. A key differentiator is its flexible `sendCommand` abstraction, which allows seamless integration with various Redis client libraries by adapting their specific command execution functions. It requires Node.js 16 or above and Redis 2.6.12 or above for operation. The project maintains an active development status, ensuring compatibility with the latest `express-rate-limit` versions and modern Node.js environments.","status":"active","version":"4.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/express-rate-limit/rate-limit-redis","tags":["javascript","typescript"],"install":[{"cmd":"npm install rate-limit-redis","lang":"bash","label":"npm"},{"cmd":"yarn add rate-limit-redis","lang":"bash","label":"yarn"},{"cmd":"pnpm add rate-limit-redis","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This package provides a Redis store for the express-rate-limit middleware, which is a required peer dependency.","package":"express-rate-limit","optional":false},{"reason":"A Redis client (like `node-redis` or `ioredis`) is required at runtime to connect to a Redis server. Users choose their preferred client.","package":"redis","optional":true}],"imports":[{"note":"For CommonJS projects, use `const { RedisStore } = require('rate-limit-redis')`. This package provides both ESM and CJS builds.","wrong":"const RedisStore = require('rate-limit-redis').RedisStore","symbol":"RedisStore","correct":"import { RedisStore } from 'rate-limit-redis'"},{"note":"When using TypeScript, import the type explicitly for type safety in store configurations.","symbol":"RedisStore","correct":"import type { RedisStore } from 'rate-limit-redis'"},{"note":"This type is often used in TypeScript projects when configuring the `sendCommand` function for clients like `ioredis` to correctly type the return promise.","symbol":"RedisReply","correct":"import type { RedisReply } from 'rate-limit-redis'"}],"quickstart":{"code":"import { rateLimit } from 'express-rate-limit';\nimport { RedisStore } from 'rate-limit-redis';\nimport { createClient } from 'redis';\nimport express from 'express';\n\nconst app = express();\n\nasync function setupRateLimiter() {\n  // Create a `node-redis` client\n  const client = createClient({\n    url: process.env.REDIS_URL ?? 'redis://localhost:6379'\n  });\n\n  // Then connect to the Redis server\n  client.on('error', (err) => console.error('Redis Client Error', err));\n  await client.connect();\n  console.log('Connected to Redis');\n\n  // Create and use the rate limiter\n  const limiter = rateLimit({\n    windowMs: 15 * 60 * 1000, // 15 minutes\n    max: 100, // Limit each IP to 100 requests per window\n    standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers\n    legacyHeaders: false, // Disable the `X-RateLimit-*` headers\n\n    // Redis store configuration\n    store: new RedisStore({\n      sendCommand: (...args: string[]) => client.sendCommand(args),\n    }),\n  });\n\n  app.use(limiter);\n\n  app.get('/', (req, res) => {\n    res.send('Hello, you are rate-limited!');\n  });\n\n  const PORT = process.env.PORT || 3000;\n  app.listen(PORT, () => {\n    console.log(`Server running on http://localhost:${PORT}`);\n  });\n}\n\nsetupRateLimiter().catch(console.error);","lang":"typescript","description":"Demonstrates setting up an Express application with rate limiting using Redis as a store, configured with the node-redis client. It connects to Redis and applies the rate limiter to all routes."},"warnings":[{"fix":"Upgrade your Node.js runtime environment to version 16 or later.","message":"Version 4.0.0 dropped support for Node.js 14. Projects must now use Node.js 16 or newer to ensure compatibility.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Update your `express-rate-limit` package to version 7 or newer in your project's dependencies.","message":"Version 4.0.0 introduced support for `express-rate-limit` v7. Ensure your `express-rate-limit` dependency is updated to a compatible version (v7 or higher) to avoid potential issues.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure your Redis server instance is running version 2.6.12 or newer.","message":"This package requires a Redis server version 2.6.12 or above. Using an older Redis version may lead to unexpected behavior or errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to version 4.1.1 or later to ensure `store.get()` consistently returns `0` when no hits are recorded for a client.","message":"Prior to v4.1.1, the `store.get()` function would return `NaN` if no hits were stored for a client, instead of the expected `0`. This could cause issues in logic dependent on the return value.","severity":"gotcha","affected_versions":"<4.1.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure you call `await client.connect()` after creating your Redis client instance and before passing it to the `RedisStore` constructor.","cause":"The `node-redis` client (created with `createClient()`) requires an explicit `await client.connect()` call before it can be used to send commands.","error":"TypeError: client.connect is not a function"},{"error":"Error: require() of ES Module ... not supported."},{"fix":"For ES Modules, set `\"type\": \"module\"` in your `package.json` and use `import`. For CommonJS, ensure `\"type\": \"commonjs\"` (or no `type` field) and use `require()`. Ensure bundlers or TypeScript configurations handle module resolution correctly.","cause":"This error typically occurs when mixing CommonJS (`require`) and ES Module (`import`) syntax, or when an ES Module is imported in a CommonJS context without proper transpilation or configuration.","error":"SyntaxError: Cannot use import statement outside a module"},{"fix":"Adjust the `sendCommand` function's signature or cast its return value to `Promise<number>` or `number` to match the expected type. For `ioredis`, you might cast `client.call(...) as Promise<number>`.","cause":"When using TypeScript, the `sendCommand` function in `RedisStore` expects a return type of `Promise<number>` or `number`. If your Redis client's command function returns a different type (e.g., `Promise<RedisReply>` from `ioredis`'s `call` method), a type mismatch occurs.","error":"Argument of type '(command: string, ...args: string[]) => Promise<RedisReply>' is not assignable to parameter of type '(...args: string[]) => number | Promise<number>'"},{"fix":"Verify that your Redis client object is properly initialized and connected, and that the `sendCommand` function within `RedisStore`'s options correctly references a valid command sending method on that client (e.g., `client.sendCommand(args)` or `client.call(command, ...args)`).","cause":"The `sendCommand` function was not correctly provided or it's attempting to access a method on an uninitialized or incorrectly configured Redis client instance within the `RedisStore` options.","error":"TypeError: Cannot read properties of undefined (reading 'sendCommand')"}],"ecosystem":"npm","meta_description":null}