Context
ioredis is in maintenance mode — security fixes only, no new features — and the Redis team points to node-redis as the recommended client going forward.
That framing isn't mine: RomainLanz opened boringnode/bus#41 in October with exactly that rationale.
Why this lands on @adonisjs/redis specifically
Downstream packages can add node-redis support additively, and some are already trying:
But none of that reaches an AdonisJS app, because what the app hands those packages is redis.connection(name).ioConnection — an ioredis client by definition. So for as long as this package is ioredis-only, a node-redis driver downstream is unreachable from Adonis. This package is the constraint on the whole chain.
The ioredis version treadmill is already costing something
#77 is a concrete instance: 10.0.1 shipped ioredis 6 in a patch, which broke @adonisjs/cache through bentocache's cross-major instanceof check — silently connecting to 127.0.0.1:6379 instead of the configured server — and had to be reverted, with ioredis 6 re-shipped as the 11.0.0 major.
The knock-on is still live: @adonisjs/session, @adonisjs/limiter, @adonisjs/lock and @adonisjs/cache all still cap the peer at ^10, so no app can adopt @adonisjs/redis@11 without overrides.
(I've opened peer-range PRs for the first three — adonisjs/limiter#18, adonisjs/lock#4, adonisjs/session#103 — and the cache side needs Julien-R44/bentocache#123 and boringnode/bus#71 to land first. That's the short-term fix; this issue is about the longer-term direction.)
The known hard part
node-redis requires an awaited connect(), and constructors can't be async. That's what stalled the first attempt on the bus side (see elee1766's comment on boringnode/bus#41); niksy's PR works around it with lazily-created connection promises.
Whatever shape this takes here would need an answer for connection lifecycle inside a container/provider that resolves synchronously.
Proposal: additive, not a migration
Rather than replacing ioredis, add node-redis as a second connection implementation alongside it:
- existing
redis.connection() / .ioConnection behaviour untouched — no breaking change
- opt-in per connection in
config/redis.ts
- downstream packages that duck-type or accept a client instance can support both over time
- ioredis stays supported for as long as it needs to be
Questions
- Is this a direction the team would consider at all, or is staying on ioredis a deliberate call?
- If it is: an additive second implementation, or a longer-term replacement behind a compatibility layer?
.ioConnection is public API and widely consumed. Would a node-redis connection expose a parallel accessor, or is there appetite for a client-agnostic surface?
Happy to prototype if there's interest — I didn't want to show up with a large unsolicited PR on a core package.
Context
ioredisis in maintenance mode — security fixes only, no new features — and the Redis team points tonode-redisas the recommended client going forward.That framing isn't mine: RomainLanz opened boringnode/bus#41 in October with exactly that rationale.
Why this lands on
@adonisjs/redisspecificallyDownstream packages can add node-redis support additively, and some are already trying:
ioredistonode-redisboringnode/bus#41 — migration issue, and feat(redis): add node redis transport boringnode/bus#61 — an open PR adding a node-redis transport alongside the ioredis oneBut none of that reaches an AdonisJS app, because what the app hands those packages is
redis.connection(name).ioConnection— an ioredis client by definition. So for as long as this package is ioredis-only, a node-redis driver downstream is unreachable from Adonis. This package is the constraint on the whole chain.The ioredis version treadmill is already costing something
#77 is a concrete instance:
10.0.1shipped ioredis 6 in a patch, which broke@adonisjs/cachethrough bentocache's cross-majorinstanceofcheck — silently connecting to127.0.0.1:6379instead of the configured server — and had to be reverted, with ioredis 6 re-shipped as the11.0.0major.The knock-on is still live:
@adonisjs/session,@adonisjs/limiter,@adonisjs/lockand@adonisjs/cacheall still cap the peer at^10, so no app can adopt@adonisjs/redis@11without overrides.(I've opened peer-range PRs for the first three — adonisjs/limiter#18, adonisjs/lock#4, adonisjs/session#103 — and the cache side needs Julien-R44/bentocache#123 and boringnode/bus#71 to land first. That's the short-term fix; this issue is about the longer-term direction.)
The known hard part
node-redis requires an awaited
connect(), and constructors can't be async. That's what stalled the first attempt on the bus side (see elee1766's comment on boringnode/bus#41); niksy's PR works around it with lazily-created connection promises.Whatever shape this takes here would need an answer for connection lifecycle inside a container/provider that resolves synchronously.
Proposal: additive, not a migration
Rather than replacing ioredis, add node-redis as a second connection implementation alongside it:
redis.connection()/.ioConnectionbehaviour untouched — no breaking changeconfig/redis.tsQuestions
.ioConnectionis public API and widely consumed. Would a node-redis connection expose a parallel accessor, or is there appetite for a client-agnostic surface?Happy to prototype if there's interest — I didn't want to show up with a large unsolicited PR on a core package.