A robust, performance-focused and full-featured Redis client for Node.js with TypeScript support, clustering, sentinel management, and comprehensive Redis command coverage.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
ioredis provides complete Redis command support through the RedisCommander interface. All Redis commands are available as methods with proper TypeScript typing, promise-based returns, and optional callback support.
All Redis commands are available as methods on Redis and Cluster instances with consistent patterns.
// Generic command execution
call(command: string, ...args: any[]): Promise<unknown>;
// Example command signatures
get(key: RedisKey): Promise<string | null>;
set(key: RedisKey, value: RedisValue): Promise<"OK">;
set(key: RedisKey, value: RedisValue, expiryMode: "EX", time: number): Promise<"OK">;
set(key: RedisKey, value: RedisValue, expiryMode: "PX", time: number): Promise<"OK">;
set(key: RedisKey, value: RedisValue, mode: "NX"): Promise<"OK" | null>;
set(key: RedisKey, value: RedisValue, mode: "XX"): Promise<"OK" | null>;
// All commands also support callback pattern
get(key: RedisKey, callback: Callback<string | null>): void;
set(key: RedisKey, value: RedisValue, callback: Callback<"OK">): void;Usage Examples:
import Redis from "ioredis";
const redis = new Redis();
// Promise-based usage
const value = await redis.get("key");
await redis.set("key", "value");
// Callback usage
redis.get("key", (err, result) => {
if (err) console.error(err);
else console.log(result);
});
// Complex command with options
await redis.set("session:123", "data", "EX", 3600, "NX");
// Generic command execution
const result = await redis.call("CUSTOM_COMMAND", "arg1", "arg2");All Redis commands have corresponding buffer variants that work with binary data and return Buffer objects instead of strings.
// Every command has a Buffer variant
getBuffer(key: RedisKey): Promise<Buffer | null>;
setBuffer(key: RedisKey, value: RedisValue): Promise<Buffer>;
hgetBuffer(key: RedisKey, field: string): Promise<Buffer | null>;
lrangeBuffer(key: RedisKey, start: number, stop: number): Promise<Buffer[]>;
// Generic buffer command execution
callBuffer(command: string, ...args: any[]): Promise<Buffer>;Usage Examples:
// Working with binary data
const binaryData = Buffer.from("hello world", "utf8");
await redis.setBuffer("binary:key", binaryData);
const result = await redis.getBuffer("binary:key"); // Returns Buffer
console.log(result.toString()); // "hello world"
// Hash operations with buffers
await redis.hsetBuffer("hash:key", "field", Buffer.from("value"));
const hashValue = await redis.hgetBuffer("hash:key", "field"); // Returns Buffer
// List operations with buffers
await redis.lpushBuffer("list:key", Buffer.from("item1"), Buffer.from("item2"));
const items = await redis.lrangeBuffer("list:key", 0, -1); // Returns Buffer[]Operations on Redis string data type (binary-safe).
// Basic string operations
get(key: RedisKey): Promise<string | null>;
set(key: RedisKey, value: RedisValue): Promise<"OK">;
getset(key: RedisKey, value: RedisValue): Promise<string | null>;
append(key: RedisKey, value: RedisValue): Promise<number>;
strlen(key: RedisKey): Promise<number>;
// Multi-key operations
mget(...keys: RedisKey[]): Promise<Array<string | null>>;
mset(...args: Array<RedisKey | RedisValue>): Promise<"OK">;
msetnx(...args: Array<RedisKey | RedisValue>): Promise<number>;
// Numeric operations
incr(key: RedisKey): Promise<number>;
incrby(key: RedisKey, increment: number): Promise<number>;
incrbyfloat(key: RedisKey, increment: number): Promise<string>;
decr(key: RedisKey): Promise<number>;
decrby(key: RedisKey, decrement: number): Promise<number>;
// Substring operations
getrange(key: RedisKey, start: number, end: number): Promise<string>;
setrange(key: RedisKey, offset: number, value: RedisValue): Promise<number>;
// Bit operations
getbit(key: RedisKey, offset: number): Promise<number>;
setbit(key: RedisKey, offset: number, value: number): Promise<number>;
bitcount(key: RedisKey): Promise<number>;
bitcount(key: RedisKey, start: number, end: number): Promise<number>;Usage Examples:
// Basic string operations
await redis.set("user:name", "Alice");
const name = await redis.get("user:name");
// Expiration
await redis.set("session", "abc123", "EX", 3600); // Expire in 1 hour
// Multi-key operations
await redis.mset("key1", "value1", "key2", "value2");
const values = await redis.mget("key1", "key2");
// Numeric operations
await redis.set("counter", "0");
const count = await redis.incr("counter");
await redis.incrby("counter", 10);
// Conditional operations
const wasSet = await redis.set("lock", "value", "NX", "EX", 30);
if (wasSet) console.log("Lock acquired");Operations on Redis hash data type (field-value maps).
// Basic hash operations
hget(key: RedisKey, field: string): Promise<string | null>;
hset(key: RedisKey, field: string, value: RedisValue): Promise<number>;
hset(key: RedisKey, object: Record<string, RedisValue>): Promise<number>;
hdel(key: RedisKey, ...fields: string[]): Promise<number>;
hexists(key: RedisKey, field: string): Promise<number>;
hlen(key: RedisKey): Promise<number>;
// Multi-field operations
hmget(key: RedisKey, ...fields: string[]): Promise<Array<string | null>>;
hmset(key: RedisKey, ...args: Array<string | RedisValue>): Promise<"OK">;
hgetall(key: RedisKey): Promise<Record<string, string>>;
hkeys(key: RedisKey): Promise<string[]>;
hvals(key: RedisKey): Promise<string[]>;
// Numeric operations
hincrby(key: RedisKey, field: string, increment: number): Promise<number>;
hincrbyfloat(key: RedisKey, field: string, increment: number): Promise<string>;
// Conditional operations
hsetnx(key: RedisKey, field: string, value: RedisValue): Promise<number>;Usage Examples:
// Basic hash operations
await redis.hset("user:123", "name", "Alice");
await redis.hset("user:123", "email", "alice@example.com");
const name = await redis.hget("user:123", "name");
// Object-style setting
await redis.hset("user:456", {
name: "Bob",
email: "bob@example.com",
age: "25"
});
// Get all hash data
const user = await redis.hgetall("user:123");
console.log(user); // { name: "Alice", email: "alice@example.com" }
// Multi-field operations
const [name2, email] = await redis.hmget("user:123", "name", "email");
// Numeric operations
await redis.hincrby("stats:views", "page1", 1);Operations on Redis list data type (linked lists).
// Push operations
lpush(key: RedisKey, ...values: RedisValue[]): Promise<number>;
rpush(key: RedisKey, ...values: RedisValue[]): Promise<number>;
lpushx(key: RedisKey, ...values: RedisValue[]): Promise<number>;
rpushx(key: RedisKey, ...values: RedisValue[]): Promise<number>;
// Pop operations
lpop(key: RedisKey): Promise<string | null>;
rpop(key: RedisKey): Promise<string | null>;
blpop(...args: [...keys: RedisKey[], timeout: number]): Promise<[string, string] | null>;
brpop(...args: [...keys: RedisKey[], timeout: number]): Promise<[string, string] | null>;
// Range operations
lrange(key: RedisKey, start: number, stop: number): Promise<string[]>;
ltrim(key: RedisKey, start: number, stop: number): Promise<"OK">;
// Index operations
lindex(key: RedisKey, index: number): Promise<string | null>;
lset(key: RedisKey, index: number, value: RedisValue): Promise<"OK">;
linsert(key: RedisKey, direction: "BEFORE" | "AFTER", pivot: RedisValue, value: RedisValue): Promise<number>;
// List information
llen(key: RedisKey): Promise<number>;
lrem(key: RedisKey, count: number, value: RedisValue): Promise<number>;
// Blocking operations
brpoplpush(source: RedisKey, destination: RedisKey, timeout: number): Promise<string | null>;Usage Examples:
// Queue operations (FIFO)
await redis.lpush("queue", "job1", "job2", "job3");
const job = await redis.rpop("queue");
// Stack operations (LIFO)
await redis.lpush("stack", "item1", "item2");
const item = await redis.lpop("stack");
// Blocking operations
const result = await redis.blpop("queue", 10); // Wait 10 seconds
if (result) {
const [queueName, value] = result;
console.log(`Got ${value} from ${queueName}`);
}
// Range operations
await redis.rpush("messages", "msg1", "msg2", "msg3");
const messages = await redis.lrange("messages", 0, -1); // Get all
const recent = await redis.lrange("messages", -5, -1); // Last 5Operations on Redis set data type (unordered collections).
// Basic set operations
sadd(key: RedisKey, ...members: RedisValue[]): Promise<number>;
srem(key: RedisKey, ...members: RedisValue[]): Promise<number>;
smembers(key: RedisKey): Promise<string[]>;
scard(key: RedisKey): Promise<number>;
sismember(key: RedisKey, member: RedisValue): Promise<number>;
// Random operations
spop(key: RedisKey): Promise<string | null>;
spop(key: RedisKey, count: number): Promise<string[]>;
srandmember(key: RedisKey): Promise<string | null>;
srandmember(key: RedisKey, count: number): Promise<string[]>;
// Set operations
sinter(...keys: RedisKey[]): Promise<string[]>;
sunion(...keys: RedisKey[]): Promise<string[]>;
sdiff(...keys: RedisKey[]): Promise<string[]>;
sinterstore(destination: RedisKey, ...keys: RedisKey[]): Promise<number>;
sunionstore(destination: RedisKey, ...keys: RedisKey[]): Promise<number>;
sdiffstore(destination: RedisKey, ...keys: RedisKey[]): Promise<number>;
// Move operations
smove(source: RedisKey, destination: RedisKey, member: RedisValue): Promise<number>;Usage Examples:
// Basic set operations
await redis.sadd("tags", "redis", "database", "cache");
const tags = await redis.smembers("tags");
const hasRedis = await redis.sismember("tags", "redis");
// Set operations
await redis.sadd("user:123:tags", "redis", "javascript");
await redis.sadd("user:456:tags", "redis", "python");
// Find common tags
const commonTags = await redis.sinter("user:123:tags", "user:456:tags");
console.log(commonTags); // ["redis"]
// Random selection
const randomTag = await redis.srandmember("tags");
const randomTags = await redis.srandmember("tags", 2);Operations on Redis sorted set data type (scored collections).
// Basic sorted set operations
zadd(key: RedisKey, ...args: Array<number | string>): Promise<number>;
zrem(key: RedisKey, ...members: RedisValue[]): Promise<number>;
zcard(key: RedisKey): Promise<number>;
zcount(key: RedisKey, min: string, max: string): Promise<number>;
// Range operations
zrange(key: RedisKey, start: number, stop: number): Promise<string[]>;
zrange(key: RedisKey, start: number, stop: number, withScores: "WITHSCORES"): Promise<string[]>;
zrevrange(key: RedisKey, start: number, stop: number): Promise<string[]>;
zrangebyscore(key: RedisKey, min: string, max: string): Promise<string[]>;
zrevrangebyscore(key: RedisKey, max: string, min: string): Promise<string[]>;
// Score operations
zscore(key: RedisKey, member: RedisValue): Promise<string | null>;
zincrby(key: RedisKey, increment: number, member: RedisValue): Promise<string>;
zrank(key: RedisKey, member: RedisValue): Promise<number | null>;
zrevrank(key: RedisKey, member: RedisValue): Promise<number | null>;
// Lexicographical operations
zrangebylex(key: RedisKey, min: string, max: string): Promise<string[]>;
zrevrangebylex(key: RedisKey, max: string, min: string): Promise<string[]>;
zlexcount(key: RedisKey, min: string, max: string): Promise<number>;Usage Examples:
// Leaderboard example
await redis.zadd("leaderboard", 100, "alice", 85, "bob", 120, "charlie");
// Get top players
const topPlayers = await redis.zrevrange("leaderboard", 0, 2, "WITHSCORES");
console.log(topPlayers); // ["charlie", "120", "alice", "100", "bob", "85"]
// Get player rank (0-based)
const aliceRank = await redis.zrevrank("leaderboard", "alice");
console.log(`Alice is rank ${aliceRank + 1}`);
// Update score
await redis.zincrby("leaderboard", 10, "bob");
// Range by score
const highScorers = await redis.zrangebyscore("leaderboard", "90", "+inf");Operations on Redis keys (metadata and lifecycle).
// Key existence and information
exists(...keys: RedisKey[]): Promise<number>;
type(key: RedisKey): Promise<string>;
ttl(key: RedisKey): Promise<number>;
pttl(key: RedisKey): Promise<number>;
// Key expiration
expire(key: RedisKey, seconds: number): Promise<number>;
pexpire(key: RedisKey, milliseconds: number): Promise<number>;
expireat(key: RedisKey, timestamp: number): Promise<number>;
pexpireat(key: RedisKey, millisecondsTimestamp: number): Promise<number>;
persist(key: RedisKey): Promise<number>;
// Key operations
del(...keys: RedisKey[]): Promise<number>;
unlink(...keys: RedisKey[]): Promise<number>;
rename(key: RedisKey, newkey: RedisKey): Promise<"OK">;
renamenx(key: RedisKey, newkey: RedisKey): Promise<number>;
move(key: RedisKey, db: number): Promise<number>;
// Key scanning
keys(pattern: string): Promise<string[]>;
scan(cursor: string): Promise<[string, string[]]>;
scan(cursor: string, matchPattern: string): Promise<[string, string[]]>;
scan(cursor: string, countOption: "COUNT", count: number): Promise<[string, string[]]>;Usage Examples:
// Check key existence
const exists = await redis.exists("user:123");
if (exists) {
const type = await redis.type("user:123");
console.log(`Key exists and is of type: ${type}`);
}
// Set expiration
await redis.set("session:abc", "data");
await redis.expire("session:abc", 3600); // Expire in 1 hour
// Check TTL
const ttl = await redis.ttl("session:abc");
console.log(`Key expires in ${ttl} seconds`);
// Delete keys
await redis.del("old_key1", "old_key2");
// Pattern matching (use with caution on large datasets)
const userKeys = await redis.keys("user:*");
// Safer scanning for large datasets
let cursor = "0";
do {
const [nextCursor, keys] = await redis.scan(cursor, "MATCH", "user:*", "COUNT", 100);
cursor = nextCursor;
console.log("Found keys:", keys);
} while (cursor !== "0");type RedisKey = string | Buffer;
type RedisValue = string | Buffer | number;
type Callback<T> = (err?: Error | null, result?: T) => void;