Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions content/develop/clients/nodejs/migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
categories:
- docs
- develop
- stack
- oss
- rs
- rc
- oss
- kubernetes
- clients
description: Learn the differences between `ioredis` and `node-redis`
linkTitle: Migrate from ioredis
title: Migrate from ioredis
weight: 6
---

Redis previously recommended the [`ioredis`](https://github.com/redis/ioredis)
client library for development with [Node.js](https://nodejs.org/en),
but this library is now deprecated in favor of
[`node-redis`]({{< relref "/develop/clients/nodejs" >}}). This guide
outlines the main similarities and differences between the two libraries.
You may find this information useful if you are an `ioredis` user and you want to
start a new Node.js project or migrate an existing `ioredis` project to `node-redis`

The table below summarizes how `ioredis` and `node-redis` implement some
key features of Redis. See the following sections for more information about
each feature.

| Feature | `ioredis` | `node-redis` |
| :-- | :-- | :-- |
| [Command case](#command-case) | Lowercase only (eg, `hset`) | Uppercase or camel case (eg, `HSET` or `hSet`) |
| [Command argument handling](#command-argument-handling) | Argument objects flattened and items passed directly | Argument objects parsed to generate correct argument list |
| [Asynchronous command result handling](#async-result) | Callbacks and Promises | Promises only |
| [Pipelining](#pipelining) | Automatic, or with `pipeline()` command | Automatic, or with `multi()` command |

## Command case

Command methods in `ioredis` are always lowercase. With `node-redis`, you can
use uppercase or camel case versions of the method names.

```js
// ioredis
redis.hset("key", "field", "value");

// node-redis
redis.HSET("key", "field", "value");

// ...or
redis.hSet("key", "field", "value");
```

## Command argument handling

`ioredis` parses command arguments to strings and then passes them to
the server, in a similar way to [`redis-cli`]({{< relref "/develop/tools/cli" >}}).

```js
// Equivalent to the command line `SET key 100 EX 10`.
redis.set("key", 100, "EX", 10);
```

Arrays passed as arguments are flattened into individual elements and
objects are flattened into sequential key-value pairs:

```js
// These commands are all equivalent.
redis.hset("user" {
name: "Bob",
age: 20,
description: "I am a programmer",
});

redis.hset("user", ["name", "Bob", "age", 20, "description", "I am a programmer"]);

redis.hset("user", "name", "Bob", "age", 20, "description", "I am a programmer");
```

`node-redis` uses predefined formats for command arguments. These include specific
classes for commmand options that generally don't correspond to the syntax
of the CLI command. Internally, `node-redis` constructs the correct command using
the method arguments you pass:

```js
// Equivalent to the command line `SET key 100 EX 10`.
redis.set("bike:5", "bike", {EX: 10});
```

## Asynchronous command result handling {#async-result}

All commands for both `ioredis` and `node-redis` are executed
asynchronously. `ioredis` supports both callbacks and
[`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
return values to respond to command results:

```js
// Callback
redis.get("mykey", (err, result) => {
if (err) {
console.error(err);
} else {
console.log(result);
}
});

// Promise
redis.get("mykey").then(
(result) => {
console.log(result);
},
(err) => {
console.error(err);
}
);
```

`node-redis` supports only `Promise` objects for results, so
you must always use a `then()` handler or the
[`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)
operator to receive them.
Copy link
Collaborator

@dwdougherty dwdougherty Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if await should be used for examples that return promises. Not a JavaScript guy (but I play one at work), so just thinking out loud.


## Pipelining

Both `ioredis` and `node-redis` will pipeline commands automatically if
they are executed in the same "tick" of the
[event loop](https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#what-is-the-event-loop)
(see
[Pipelines and transactions]({{< relref "/develop/clients/nodejs/transpipe" >}})
for more information).

You can also create a pipeline with explicit commands in both clients.
For `ioredis`, you use the `pipeline()` command with a chain of
commands, ending with `exec()` to run the pipeline:

```js
// ioredis example
redis
.pipeline()
.set("foo", "1")
.get("foo")
.set("foo", "2")
.incr("foo")
.get("foo")
.exec(function (err, results) {
// Handle results or errors.
});
```

For `node-redis`, the approach is similar, except that you call the `multi()`
command to start the pipeline and `execAsPipeline()` to run it:

```js
redis.multi()
.set('seat:3', '#3')
.set('seat:4', '#4')
.set('seat:5', '#5')
.execAsPipeline()
.then((results) => {
// Handle array of results.
},
(err) => {
// Handle errors.
});
```
6 changes: 4 additions & 2 deletions content/develop/clients/nodejs/transpipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ There are two types of batch that you can use:

## Execute a pipeline

There are two ways to execute commands in a pipeline. The first is
to include the commands in a
There are two ways to execute commands in a pipeline. Firstly, `node-redis` will
automatically pipeline commands that execute within the same "tick" of the
[event loop](https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#what-is-the-event-loop).
You can ensure that commands happen in the same tick very easily by including them in a
[`Promise.all()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)
call, as shown in the following example. The chained `then(...)` callback is optional
and you can often omit it for commands that write data and only return a
Expand Down