cache-manager-redis-store
A Redis store adapter for node-cache-manager, built as a thin wrapper around node-redis v4.
Repository Health
Technical Analysis
cache-manager-redis-store plugs Redis into node-cache-manager as a storage backend. Rather than reinventing a Redis client, it wraps node-redis v4 directly and exposes the get/set/del/mset/mget/reset/keys/ttl surface that cache-manager’s Store interface expects, so existing node-cache-manager code can switch from an in-memory store to Redis with a one-line change.
It supports both Promise-based and callback-based call styles for every method, per-call and per-store TTLs, custom isCacheableValue validation, and multi-key batch operations (mset/mget/mdel) via Redis pipelining through node-redis’s multi(). It is also designed to compose cleanly with cache-manager’s multiCaching() helper for tiered (e.g. memory + Redis) caching setups.
What You Get
- A
redisStore(config)factory that creates and connects a node-redis v4 client and returns a ready-to-use cache-manager Store - Full get/set/del plus batch mset/mget/mdel operations, with mset/mget using Redis multi/pipelining under the hood
- Dual API support — every method works as a Promise or with a legacy Node-style
(err, result)callback - Per-key and per-store TTL support, including
redisCache.ttl(key)to read remaining time-to-live - Custom
isCacheableValueoverride so callers can decide which values are allowed to be cached (e.g. rejectingundefinedor specific sentinel strings) - Direct access to the underlying node-redis client via
getClient()for advanced usage like listening to connection error events
Common Use Cases
- Swapping an in-memory node-cache-manager store for a shared Redis-backed cache in a Node.js API or worker service
- Building tiered caching with
cacheManager.multiCaching([memoryCache, redisCache])so hot keys hit memory first and fall back to Redis - Caching expensive computed values (e.g. database query results) behind
redisCache.wrap(key, fn, { ttl })with automatic TTL expiry - Batch-populating or invalidating many cache keys at once with
mset/mdelto reduce round-trips to Redis
Under The Hood
Architecture
The package is a single ~200-line module (index.js) exporting one async factory, redisStore(config), which creates a node-redis v4 createClient(config) instance, awaits its connect(), and passes it into buildRedisStoreWithConfig. That inner function is a closure over the connected client that builds and returns the cache-manager Store object: a plain object literal whose methods (set, get, del, mset, mget, mdel, reset, keys, ttl) each wrap an internal async implementation with a small dispatcher that detects whether the caller passed a trailing callback (Node-style) or expects a Promise, using util.callbackify to bridge the two. There are no additional layers, no dependency injection, and no internal state beyond the single Redis client reference — the entire abstraction is a direct pass-through to node-redis’s own command methods, so a breaking change in node-redis’s client API (as happened between v3 and v4, documented in the project’s changelog as a rewrite) directly breaks this wrapper’s implementation.
Tech Stack
Written in plain JavaScript (ES2019+ syntax, node:util’s callbackify) with a single runtime dependency, redis (node-redis) pinned to ^4.3.1. The published dist/ build is produced via Rollup with a Babel plugin (@rollup/plugin-babel, @babel/preset-env, @babel/plugin-transform-runtime) to transpile for its supported Node.js range (>=16.18.0), and hand-written TypeScript declarations (dist/index.d.ts) are shipped alongside the compiled JS rather than generated from source. Tests run under Jest with babel-jest, and CI (GitHub Actions) runs the test suite across a Node 16/18 x Redis 4/5/6 matrix with coverage uploaded to Codecov.
Code Quality
A single test file (test/index.test.js, roughly 500 lines) exercises every store method in both Promise and callback form, along with TTL expiry, custom isCacheableValue behavior, and multi-key operations — coverage looks comprehensive for the package’s small surface area, and CI runs it against a real Redis instance across multiple Redis major versions rather than mocking the client. That said, the source is untyped plain JavaScript (the shipped .d.ts file is manually maintained and leans heavily on any for parameters), there is no linter or formatter configuration in the repository, and error handling is limited to a handful of explicit throw new Error(...) checks (e.g. for non-cacheable values) rather than a broader error-handling strategy.
What Makes It Unique The project deliberately avoids building its own Redis client or connection-pooling layer — its stated design goal, per the README, is to be “the most simple wrapper possible” around node-redis, delegating configuration and connection management entirely to the underlying client rather than adding an abstraction layer on top of it. This keeps the package extremely small and easy to reason about, at the cost of being tightly coupled to node-redis’s own API and versioning.
Used by 2 apps in this directory
Bigcapital
Invoicing Finance
Self-hostable double-entry accounting platform with invoicing, inventory, multi-currency, and real-time financial reporting for small and medium businesses.
Laudspeaker
Marketing · Automation
Open-source customer engagement platform for building visual, event-triggered messaging journeys across email, SMS, push, in-app, and webhooks.