A modern, high performance Redis client for Node.js with full TypeScript support and all Redis Stack modules
—
Complete implementation of all Redis commands with type-safe parameters and return values. The client provides over 700 Redis commands organized by data type and functionality, with both uppercase method names and lowercase aliases.
Basic string operations for storing and retrieving string values.
/**
* Get the value of a key
* @param key - The key to get
* @returns The value of the key, or null if key does not exist
*/
get(key: RedisArgument): Promise<BlobStringReply | null>;
GET(key: RedisArgument): Promise<BlobStringReply | null>;
/**
* Set the string value of a key
* @param key - The key to set
* @param value - The value to set
* @param options - Optional set options (expiration, conditions)
* @returns 'OK' if successful, null if condition not met
*/
set(key: RedisArgument, value: RedisArgument, options?: SetOptions): Promise<SimpleStringReply<'OK'> | null>;
SET(key: RedisArgument, value: RedisArgument, options?: SetOptions): Promise<SimpleStringReply<'OK'> | null>;
/**
* Increment the integer value of a key by one
* @param key - The key to increment
* @returns The new value after increment
*/
incr(key: RedisArgument): Promise<NumberReply>;
INCR(key: RedisArgument): Promise<NumberReply>;
/**
* Increment the integer value of a key by amount
* @param key - The key to increment
* @param increment - The amount to increment by
* @returns The new value after increment
*/
incrBy(key: RedisArgument, increment: number): Promise<NumberReply>;
INCRBY(key: RedisArgument, increment: number): Promise<NumberReply>;
/**
* Append a value to a key
* @param key - The key to append to
* @param value - The value to append
* @returns The length of the string after append
*/
append(key: RedisArgument, value: RedisArgument): Promise<NumberReply>;
APPEND(key: RedisArgument, value: RedisArgument): Promise<NumberReply>;
/**
* Get the length of the string value stored at key
* @param key - The key to measure
* @returns The length of the string, or 0 if key does not exist
*/
strlen(key: RedisArgument): Promise<NumberReply>;
STRLEN(key: RedisArgument): Promise<NumberReply>;
interface SetOptions {
/** Set expiration in seconds */
EX?: number;
/** Set expiration in milliseconds */
PX?: number;
/** Set expiration at Unix timestamp in seconds */
EXAT?: number;
/** Set expiration at Unix timestamp in milliseconds */
PXAT?: number;
/** Only set if key does not exist */
NX?: boolean;
/** Only set if key exists */
XX?: boolean;
/** Keep existing TTL */
KEEPTTL?: boolean;
/** Return previous value */
GET?: boolean;
}Usage Examples:
import { createClient } from "redis";
const client = createClient();
await client.connect();
// Basic string operations
await client.set("name", "John");
const name = await client.get("name"); // "John"
// Set with expiration
await client.set("session", "abc123", { EX: 3600 }); // Expires in 1 hour
// Conditional set
const result = await client.set("counter", "1", { NX: true }); // Only if not exists
// Increment operations
await client.set("visits", "10");
await client.incr("visits"); // 11
await client.incrBy("visits", 5); // 16
// String manipulation
await client.append("message", " world"); // Append to existing value
const length = await client.strlen("message"); // Get string lengthHash field operations for storing and manipulating hash tables.
/**
* Set the string value of a hash field
* @param key - The hash key
* @param field - The field name
* @param value - The value to set
* @returns 1 if new field, 0 if field was updated
*/
hSet(key: RedisArgument, field: RedisArgument, value: RedisArgument): Promise<NumberReply>;
HSET(key: RedisArgument, field: RedisArgument, value: RedisArgument): Promise<NumberReply>;
/**
* Get the value of a hash field
* @param key - The hash key
* @param field - The field name
* @returns The value of the field, or null if field does not exist
*/
hGet(key: RedisArgument, field: RedisArgument): Promise<BlobStringReply | null>;
HGET(key: RedisArgument, field: RedisArgument): Promise<BlobStringReply | null>;
/**
* Get all fields and values in a hash
* @param key - The hash key
* @returns Object with all hash fields and values
*/
hGetAll(key: RedisArgument): Promise<Record<string, BlobStringReply>>;
HGETALL(key: RedisArgument): Promise<Record<string, BlobStringReply>>;
/**
* Set multiple hash fields to multiple values
* @param key - The hash key
* @param hash - Object with field-value pairs
* @returns 'OK'
*/
hMSet(key: RedisArgument, hash: Record<string | number, RedisArgument>): Promise<SimpleStringReply<'OK'>>;
HMSET(key: RedisArgument, hash: Record<string | number, RedisArgument>): Promise<SimpleStringReply<'OK'>>;
/**
* Get the values of multiple hash fields
* @param key - The hash key
* @param fields - Array of field names
* @returns Array of field values (null for non-existent fields)
*/
hMGet(key: RedisArgument, fields: RedisArgument[]): Promise<ArrayReply<BlobStringReply | null>>;
HMGET(key: RedisArgument, fields: RedisArgument[]): Promise<ArrayReply<BlobStringReply | null>>;
/**
* Delete one or more hash fields
* @param key - The hash key
* @param fields - Field names to delete
* @returns Number of fields that were removed
*/
hDel(key: RedisArgument, ...fields: RedisArgument[]): Promise<NumberReply>;
HDEL(key: RedisArgument, ...fields: RedisArgument[]): Promise<NumberReply>;
/**
* Determine if a hash field exists
* @param key - The hash key
* @param field - The field name
* @returns 1 if field exists, 0 otherwise
*/
hExists(key: RedisArgument, field: RedisArgument): Promise<BooleanReply>;
HEXISTS(key: RedisArgument, field: RedisArgument): Promise<BooleanReply>;
/**
* Get the number of fields in a hash
* @param key - The hash key
* @returns Number of fields in the hash
*/
hLen(key: RedisArgument): Promise<NumberReply>;
HLEN(key: RedisArgument): Promise<NumberReply>;Usage Examples:
// Hash operations
await client.hSet("user:1", "name", "Alice");
await client.hSet("user:1", "email", "alice@example.com");
// Set multiple fields at once
await client.hMSet("user:2", {
name: "Bob",
email: "bob@example.com",
age: "30"
});
// Get single field
const name = await client.hGet("user:1", "name"); // "Alice"
// Get multiple fields
const fields = await client.hMGet("user:1", ["name", "email"]);
// Get all fields and values
const user = await client.hGetAll("user:1");
// { name: "Alice", email: "alice@example.com" }
// Check field existence
const exists = await client.hExists("user:1", "age"); // 0 (false)
// Get hash size
const size = await client.hLen("user:1"); // 2List operations for working with ordered collections.
/**
* Insert all specified values at the head of the list
* @param key - The list key
* @param elements - Elements to push
* @returns The length of the list after push
*/
lPush(key: RedisArgument, ...elements: RedisArgument[]): Promise<NumberReply>;
LPUSH(key: RedisArgument, ...elements: RedisArgument[]): Promise<NumberReply>;
/**
* Insert all specified values at the tail of the list
* @param key - The list key
* @param elements - Elements to push
* @returns The length of the list after push
*/
rPush(key: RedisArgument, ...elements: RedisArgument[]): Promise<NumberReply>;
RPUSH(key: RedisArgument, ...elements: RedisArgument[]): Promise<NumberReply>;
/**
* Remove and return the first element of the list
* @param key - The list key
* @returns The first element, or null if list is empty
*/
lPop(key: RedisArgument): Promise<BlobStringReply | null>;
LPOP(key: RedisArgument): Promise<BlobStringReply | null>;
/**
* Remove and return the last element of the list
* @param key - The list key
* @returns The last element, or null if list is empty
*/
rPop(key: RedisArgument): Promise<BlobStringReply | null>;
RPOP(key: RedisArgument): Promise<BlobStringReply | null>;
/**
* Get a range of elements from a list
* @param key - The list key
* @param start - Start index (0-based, can be negative)
* @param stop - Stop index (inclusive, can be negative)
* @returns Array of elements in the specified range
*/
lRange(key: RedisArgument, start: number, stop: number): Promise<ArrayReply<BlobStringReply>>;
LRANGE(key: RedisArgument, start: number, stop: number): Promise<ArrayReply<BlobStringReply>>;
/**
* Get the length of a list
* @param key - The list key
* @returns The length of the list
*/
lLen(key: RedisArgument): Promise<NumberReply>;
LLEN(key: RedisArgument): Promise<NumberReply>;
/**
* Blocking pop from multiple lists (left side)
* @param keys - List keys to pop from
* @param timeout - Timeout in seconds (0 = block indefinitely)
* @returns Array with key and popped element, or null if timeout
*/
blPop(keys: RedisArgument[], timeout: number): Promise<ArrayReply<BlobStringReply> | null>;
BLPOP(keys: RedisArgument[], timeout: number): Promise<ArrayReply<BlobStringReply> | null>;Usage Examples:
// List operations
await client.lPush("tasks", "task1", "task2", "task3");
await client.rPush("tasks", "task4"); // Add to end
// Get list contents
const tasks = await client.lRange("tasks", 0, -1); // All elements
// ["task3", "task2", "task1", "task4"] (newest first)
// Pop elements
const first = await client.lPop("tasks"); // "task3"
const last = await client.rPop("tasks"); // "task4"
// List length
const length = await client.lLen("tasks"); // 2
// Blocking pop with timeout
const result = await client.blPop(["queue1", "queue2"], 5); // Wait 5 seconds
if (result) {
const [key, value] = result;
console.log(`Popped "${value}" from "${key}"`);
}Set operations for working with unordered collections of unique elements.
/**
* Add one or more members to a set
* @param key - The set key
* @param members - Members to add
* @returns Number of elements added to the set
*/
sAdd(key: RedisArgument, ...members: RedisArgument[]): Promise<NumberReply>;
SADD(key: RedisArgument, ...members: RedisArgument[]): Promise<NumberReply>;
/**
* Get all members in a set
* @param key - The set key
* @returns Array of all members in the set
*/
sMembers(key: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
SMEMBERS(key: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
/**
* Determine if a member is in a set
* @param key - The set key
* @param member - The member to check
* @returns 1 if member exists, 0 otherwise
*/
sIsMember(key: RedisArgument, member: RedisArgument): Promise<BooleanReply>;
SISMEMBER(key: RedisArgument, member: RedisArgument): Promise<BooleanReply>;
/**
* Remove one or more members from a set
* @param key - The set key
* @param members - Members to remove
* @returns Number of members removed from the set
*/
sRem(key: RedisArgument, ...members: RedisArgument[]): Promise<NumberReply>;
SREM(key: RedisArgument, ...members: RedisArgument[]): Promise<NumberReply>;
/**
* Get the number of members in a set
* @param key - The set key
* @returns The cardinality of the set
*/
sCard(key: RedisArgument): Promise<NumberReply>;
SCARD(key: RedisArgument): Promise<NumberReply>;
/**
* Intersect multiple sets
* @param keys - Set keys to intersect
* @returns Array of members in the intersection
*/
sInter(keys: RedisArgument[]): Promise<ArrayReply<BlobStringReply>>;
SINTER(keys: RedisArgument[]): Promise<ArrayReply<BlobStringReply>>;
/**
* Union multiple sets
* @param keys - Set keys to union
* @returns Array of members in the union
*/
sUnion(keys: RedisArgument[]): Promise<ArrayReply<BlobStringReply>>;
SUNION(keys: RedisArgument[]): Promise<ArrayReply<BlobStringReply>>;Usage Examples:
// Set operations
await client.sAdd("fruits", "apple", "banana", "orange");
await client.sAdd("citrus", "orange", "lemon", "lime");
// Check membership
const hasApple = await client.sIsMember("fruits", "apple"); // 1 (true)
// Get all members
const fruits = await client.sMembers("fruits"); // ["apple", "banana", "orange"]
// Set operations
const intersection = await client.sInter(["fruits", "citrus"]); // ["orange"]
const union = await client.sUnion(["fruits", "citrus"]);
// ["apple", "banana", "orange", "lemon", "lime"]
// Set size
const count = await client.sCard("fruits"); // 3
// Remove members
await client.sRem("fruits", "banana");Sorted set operations for working with ordered collections with scores.
/**
* Add one or more members to a sorted set
* @param key - The sorted set key
* @param members - Array of score-member pairs
* @returns Number of elements added to the sorted set
*/
zAdd(key: RedisArgument, ...members: Array<{ score: number; value: RedisArgument }>): Promise<NumberReply>;
ZADD(key: RedisArgument, ...members: Array<{ score: number; value: RedisArgument }>): Promise<NumberReply>;
/**
* Get a range of members in a sorted set by index
* @param key - The sorted set key
* @param start - Start index
* @param stop - Stop index
* @param options - Optional parameters (WITHSCORES, REV)
* @returns Array of members (and scores if WITHSCORES)
*/
zRange(key: RedisArgument, start: number, stop: number, options?: ZRangeOptions): Promise<ArrayReply<BlobStringReply>>;
ZRANGE(key: RedisArgument, start: number, stop: number, options?: ZRangeOptions): Promise<ArrayReply<BlobStringReply>>;
/**
* Get the rank of a member in a sorted set
* @param key - The sorted set key
* @param member - The member
* @returns The rank (0-based index), or null if member doesn't exist
*/
zRank(key: RedisArgument, member: RedisArgument): Promise<NumberReply | null>;
ZRANK(key: RedisArgument, member: RedisArgument): Promise<NumberReply | null>;
/**
* Get the score of a member in a sorted set
* @param key - The sorted set key
* @param member - The member
* @returns The score, or null if member doesn't exist
*/
zScore(key: RedisArgument, member: RedisArgument): Promise<BlobStringReply | null>;
ZSCORE(key: RedisArgument, member: RedisArgument): Promise<BlobStringReply | null>;
/**
* Get the number of members in a sorted set
* @param key - The sorted set key
* @returns The cardinality of the sorted set
*/
zCard(key: RedisArgument): Promise<NumberReply>;
ZCARD(key: RedisArgument): Promise<NumberReply>;
interface ZRangeOptions {
/** Return scores along with members */
WITHSCORES?: boolean;
/** Reverse the ordering */
REV?: boolean;
/** Limit results (offset and count) */
LIMIT?: { offset: number; count: number };
}Usage Examples:
// Sorted set operations
await client.zAdd("leaderboard",
{ score: 100, value: "alice" },
{ score: 85, value: "bob" },
{ score: 92, value: "charlie" }
);
// Get top players (highest scores)
const top3 = await client.zRange("leaderboard", 0, 2, { REV: true });
// ["alice", "charlie", "bob"]
// Get with scores
const withScores = await client.zRange("leaderboard", 0, -1, { WITHSCORES: true });
// ["bob", "85", "charlie", "92", "alice", "100"]
// Get player rank (0-based, lowest score = rank 0)
const rank = await client.zRank("leaderboard", "alice"); // 2 (highest score)
// Get player score
const score = await client.zScore("leaderboard", "alice"); // "100"
// Get total players
const total = await client.zCard("leaderboard"); // 3Stream operations for working with Redis Streams.
/**
* Append an entry to a stream
* @param key - The stream key
* @param id - Entry ID ('*' for auto-generation)
* @param fields - Field-value pairs for the entry
* @returns The ID of the added entry
*/
xAdd(key: RedisArgument, id: string, fields: Record<string, RedisArgument>): Promise<BlobStringReply>;
XADD(key: RedisArgument, id: string, fields: Record<string, RedisArgument>): Promise<BlobStringReply>;
/**
* Read data from streams
* @param streams - Stream specifications with start IDs
* @param options - Optional parameters (COUNT, BLOCK)
* @returns Stream data grouped by stream key
*/
xRead(streams: Record<string, string>, options?: XReadOptions): Promise<ArrayReply<StreamEntry> | null>;
XREAD(streams: Record<string, string>, options?: XReadOptions): Promise<ArrayReply<StreamEntry> | null>;
/**
* Get stream length
* @param key - The stream key
* @returns Number of entries in the stream
*/
xLen(key: RedisArgument): Promise<NumberReply>;
XLEN(key: RedisArgument): Promise<NumberReply>;
interface XReadOptions {
/** Maximum number of entries to return per stream */
COUNT?: number;
/** Block for specified milliseconds if no entries available */
BLOCK?: number;
}
interface StreamEntry {
name: string;
messages: Array<{
id: string;
message: Record<string, BlobStringReply>;
}>;
}Usage Examples:
// Stream operations
const entryId = await client.xAdd("events", "*", {
type: "login",
user: "alice",
timestamp: Date.now().toString()
});
// Read from stream
const entries = await client.xRead({ "events": "0-0" }, { COUNT: 10 });
if (entries) {
for (const stream of entries) {
console.log(`Stream: ${stream.name}`);
for (const message of stream.messages) {
console.log(`ID: ${message.id}`, message.message);
}
}
}
// Stream length
const length = await client.xLen("events");General key operations that work across all data types.
/**
* Determine if a key exists
* @param keys - Keys to check
* @returns Number of existing keys
*/
exists(...keys: RedisArgument[]): Promise<NumberReply>;
EXISTS(...keys: RedisArgument[]): Promise<NumberReply>;
/**
* Delete one or more keys
* @param keys - Keys to delete
* @returns Number of keys deleted
*/
del(...keys: RedisArgument[]): Promise<NumberReply>;
DEL(...keys: RedisArgument[]): Promise<NumberReply>;
/**
* Set a key's time to live in seconds
* @param key - The key
* @param seconds - TTL in seconds
* @returns 1 if timeout was set, 0 if key doesn't exist
*/
expire(key: RedisArgument, seconds: number): Promise<BooleanReply>;
EXPIRE(key: RedisArgument, seconds: number): Promise<BooleanReply>;
/**
* Get the time to live for a key in seconds
* @param key - The key
* @returns TTL in seconds, -1 if no TTL, -2 if key doesn't exist
*/
ttl(key: RedisArgument): Promise<NumberReply>;
TTL(key: RedisArgument): Promise<NumberReply>;
/**
* Get the type of a key
* @param key - The key
* @returns The type of the key
*/
type(key: RedisArgument): Promise<BlobStringReply>;
TYPE(key: RedisArgument): Promise<BlobStringReply>;
/**
* Find all keys matching a pattern
* @param pattern - Glob-style pattern
* @returns Array of matching keys
*/
keys(pattern: string): Promise<ArrayReply<BlobStringReply>>;
KEYS(pattern: string): Promise<ArrayReply<BlobStringReply>>;Usage Examples:
// Key management
await client.set("temp:123", "value");
// Check existence
const exists = await client.exists("temp:123"); // 1
// Set expiration
await client.expire("temp:123", 3600); // Expire in 1 hour
// Check TTL
const ttl = await client.ttl("temp:123"); // ~3600
// Get key type
const type = await client.type("temp:123"); // "string"
// Find keys by pattern
const tempKeys = await client.keys("temp:*"); // ["temp:123"]
// Delete keys
const deleted = await client.del("temp:123"); // 1Transaction support with MULTI/EXEC and optimistic locking with WATCH.
/**
* Watch keys for changes during transaction
* @param keys - Keys to watch
* @returns 'OK'
*/
watch(...keys: RedisArgument[]): Promise<SimpleStringReply<'OK'>>;
WATCH(...keys: RedisArgument[]): Promise<SimpleStringReply<'OK'>>;
/**
* Unwatch all previously watched keys
* @returns 'OK'
*/
unwatch(): Promise<SimpleStringReply<'OK'>>;
UNWATCH(): Promise<SimpleStringReply<'OK'>>;
/**
* Start a transaction
* @returns Multi command interface
*/
multi(): RedisClientMultiCommandType;
MULTI(): RedisClientMultiCommandType;
interface RedisClientMultiCommandType {
/** Execute all queued commands */
exec(): Promise<ArrayReply<any> | null>;
/** Discard all queued commands */
discard(): Promise<SimpleStringReply<'OK'>>;
/** Queue commands for execution */
[key: string]: (...args: any[]) => RedisClientMultiCommandType;
}Usage Examples:
// Transaction with optimistic locking
await client.watch("balance:alice", "balance:bob");
const aliceBalance = parseInt(await client.get("balance:alice") || "0");
const bobBalance = parseInt(await client.get("balance:bob") || "0");
if (aliceBalance >= 100) {
const result = await client
.multi()
.decrBy("balance:alice", 100)
.incrBy("balance:bob", 100)
.exec();
if (result === null) {
console.log("Transaction aborted - balances were modified");
} else {
console.log("Transfer completed", result);
}
} else {
await client.unwatch();
console.log("Insufficient balance");
}/**
* Scan keys matching pattern
* @param options - Scan options (MATCH, COUNT, TYPE)
* @returns AsyncIterator of matching keys
*/
scanIterator(options?: ScanOptions): AsyncIterableIterator<BlobStringReply>;
/**
* Scan hash fields
* @param key - Hash key
* @param options - Scan options
* @returns AsyncIterator of field-value pairs
*/
hScanIterator(key: RedisArgument, options?: ScanOptions): AsyncIterableIterator<{ field: BlobStringReply; value: BlobStringReply }>;
/**
* Scan set members
* @param key - Set key
* @param options - Scan options
* @returns AsyncIterator of set members
*/
sScanIterator(key: RedisArgument, options?: ScanOptions): AsyncIterableIterator<BlobStringReply>;
/**
* Scan sorted set members
* @param key - Sorted set key
* @param options - Scan options
* @returns AsyncIterator of member-score pairs
*/
zScanIterator(key: RedisArgument, options?: ScanOptions): AsyncIterableIterator<{ value: BlobStringReply; score: number }>;
interface ScanOptions {
/** Pattern to match */
MATCH?: string;
/** Number of elements to return in each iteration */
COUNT?: number;
/** Type of keys to return */
TYPE?: string;
}Usage Examples:
// Iterate over all keys
for await (const key of client.scanIterator({ MATCH: "user:*" })) {
console.log("Key:", key);
}
// Iterate over hash fields
for await (const { field, value } of client.hScanIterator("user:123")) {
console.log(`${field}: ${value}`);
}
// Iterate over set members
for await (const member of client.sScanIterator("tags")) {
console.log("Member:", member);
}
// Iterate over sorted set with scores
for await (const { value, score } of client.zScanIterator("leaderboard")) {
console.log(`${value}: ${score}`);
}Publish/Subscribe messaging pattern for real-time communication between Redis clients.
/**
* Publish a message to a channel
* @param channel - The channel to publish to
* @param message - The message to publish
* @returns Number of subscribers that received the message
*/
publish(channel: RedisArgument, message: RedisArgument): Promise<NumberReply>;
PUBLISH(channel: RedisArgument, message: RedisArgument): Promise<NumberReply>;
/**
* Publish a message to a shard channel (Redis Cluster)
* @param channel - The shard channel to publish to
* @param message - The message to publish
* @returns Number of subscribers that received the message
*/
sPublish(channel: RedisArgument, message: RedisArgument): Promise<NumberReply>;
SPUBLISH(channel: RedisArgument, message: RedisArgument): Promise<NumberReply>;
/**
* Subscribe to one or more channels
* @param channels - Channel name(s) to subscribe to
* @param listener - Callback function for received messages
* @param bufferMode - Optional buffer mode flag
*/
subscribe<T extends boolean = false>(
channels: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
SUBSCRIBE<T extends boolean = false>(
channels: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Unsubscribe from channels
* @param channels - Optional channel name(s) to unsubscribe from
* @param listener - Optional specific listener to remove
* @param bufferMode - Optional buffer mode flag
*/
unsubscribe<T extends boolean = false>(
channels?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
UNSUBSCRIBE<T extends boolean = false>(
channels?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Subscribe to channels matching patterns
* @param patterns - Pattern(s) to subscribe to
* @param listener - Callback function for received messages
* @param bufferMode - Optional buffer mode flag
*/
pSubscribe<T extends boolean = false>(
patterns: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
PSUBSCRIBE<T extends boolean = false>(
patterns: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Unsubscribe from pattern subscriptions
* @param patterns - Optional pattern(s) to unsubscribe from
* @param listener - Optional specific listener to remove
* @param bufferMode - Optional buffer mode flag
*/
pUnsubscribe<T extends boolean = false>(
patterns?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
PUNSUBSCRIBE<T extends boolean = false>(
patterns?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Subscribe to shard channels (Redis Cluster)
* @param channels - Shard channel name(s) to subscribe to
* @param listener - Callback function for received messages
* @param bufferMode - Optional buffer mode flag
*/
sSubscribe<T extends boolean = false>(
channels: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
SSUBSCRIBE<T extends boolean = false>(
channels: string | Array<string>,
listener: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Unsubscribe from shard channels
* @param channels - Optional shard channel name(s) to unsubscribe from
* @param listener - Optional specific listener to remove
* @param bufferMode - Optional buffer mode flag
*/
sUnsubscribe<T extends boolean = false>(
channels?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
SUNSUBSCRIBE<T extends boolean = false>(
channels?: string | Array<string>,
listener?: PubSubListener<T>,
bufferMode?: T
): Promise<void>;
/**
* Get list of active channels
* @param pattern - Optional pattern to filter channels
* @returns List of active channels
*/
pubSubChannels(pattern?: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
PUBSUB_CHANNELS(pattern?: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
/**
* Get subscriber count for channels
* @param channels - Optional channel names to get subscription count for
* @returns Channel names mapped to subscriber counts
*/
pubSubNumSub(channels?: RedisVariadicArgument): Promise<Record<string, NumberReply>>;
PUBSUB_NUMSUB(channels?: RedisVariadicArgument): Promise<Record<string, NumberReply>>;
/**
* Get number of pattern subscriptions
* @returns Number of pattern subscriptions
*/
pubSubNumPat(): Promise<NumberReply>;
PUBSUB_NUMPAT(): Promise<NumberReply>;
/**
* Get list of active shard channels
* @param pattern - Optional pattern to filter shard channels
* @returns List of active shard channels
*/
pubSubShardChannels(pattern?: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
PUBSUB_SHARDCHANNELS(pattern?: RedisArgument): Promise<ArrayReply<BlobStringReply>>;
/**
* Get subscriber count for shard channels
* @param channels - Optional shard channel names to get subscription count for
* @returns Shard channel names mapped to subscriber counts
*/
pubSubShardNumSub(channels?: RedisVariadicArgument): Promise<Record<string, NumberReply>>;
PUBSUB_SHARDNUMSUB(channels?: RedisVariadicArgument): Promise<Record<string, NumberReply>>;
// Pub/Sub listener type
type PubSubListener<T extends boolean = false> = (
message: T extends true ? Buffer : string,
channel: T extends true ? Buffer : string
) => unknown;
// Variadic argument type
type RedisVariadicArgument = RedisArgument | Array<RedisArgument>;Usage Examples:
import { createClient } from "redis";
const client = createClient();
await client.connect();
// Publishing messages
const subscriberCount = await client.publish("news", "Breaking news!");
console.log(`Message sent to ${subscriberCount} subscribers`);
// Shard publishing (for Redis Cluster)
await client.sPublish("events", "New event occurred");
// Subscribing to channels
await client.subscribe("news", (message, channel) => {
console.log(`Received message on ${channel}: ${message}`);
});
// Subscribing to multiple channels
await client.subscribe(["news", "updates", "alerts"], (message, channel) => {
console.log(`Channel ${channel}: ${message}`);
});
// Pattern subscriptions
await client.pSubscribe("news:*", (message, channel) => {
console.log(`Pattern match - ${channel}: ${message}`);
});
// Shard subscriptions (Redis Cluster)
await client.sSubscribe("cluster-events", (message, channel) => {
console.log(`Shard channel ${channel}: ${message}`);
});
// Buffer mode for binary data
await client.subscribe("binary-data", (message, channel) => {
console.log(`Binary message length: ${message.length}`);
}, true); // bufferMode = true
// Introspection commands
const activeChannels = await client.pubSubChannels();
console.log("Active channels:", activeChannels);
const channelStats = await client.pubSubNumSub(["news", "updates"]);
console.log("Subscriber counts:", channelStats);
const patternCount = await client.pubSubNumPat();
console.log("Active pattern subscriptions:", patternCount);
// Unsubscribing
await client.unsubscribe("news");
await client.pUnsubscribe("news:*");
await client.sUnsubscribe("cluster-events");Install with Tessl CLI
npx tessl i tessl/npm-redis