# ioredis

ioredis is a robust, performance-focused, and full-featured Redis client for Node.js written in TypeScript. It provides complete Redis command support, clustering capabilities, sentinel management, and advanced features like pipelining, pub/sub, and Lua scripting with strong type safety.

## Package Information

- **Package Name**: ioredis
- **Package Type**: npm
- **Language**: TypeScript
- **Installation**: `npm install ioredis`

## Core Imports

```typescript
import Redis from "ioredis";
import { Cluster } from "ioredis";
```

For CommonJS:

```javascript
const Redis = require("ioredis");
const { Cluster } = Redis;
```

## Basic Usage

```typescript
import Redis from "ioredis";

// Connect to Redis
const redis = new Redis(); // defaults to localhost:6379

// Basic operations
await redis.set("key", "value");
const value = await redis.get("key");

// Using with configuration
const redis2 = new Redis({
  host: "redis.example.com",
  port: 6380,
  password: "secret",
  db: 1,
});

// Redis Cluster
import { Cluster } from "ioredis";

const cluster = new Cluster([
  { host: "127.0.0.1", port: 7000 },
  { host: "127.0.0.1", port: 7001 },
]);

await cluster.set("key", "value");
```

## Architecture

ioredis is built around several key components:

- **Redis Client**: Main client class supporting standalone Redis and Sentinel configurations
- **Cluster Client**: Specialized client for Redis Cluster deployments with automatic slot management
- **Command System**: Comprehensive Redis command interface with TypeScript typing
- **Connection Management**: Robust connection handling with reconnection, retries, and pooling
- **Pipeline System**: Command batching for performance optimization
- **Pub/Sub System**: Full publish/subscribe support including pattern subscriptions
- **Event System**: EventEmitter-based architecture for connection lifecycle management

## Capabilities

### Redis Client

Core Redis client for connecting to standalone Redis servers or Sentinel-managed deployments. Supports all Redis commands with full TypeScript typing.

```typescript { .api }
class Redis extends EventEmitter {
  constructor();
  constructor(port: number);
  constructor(path: string);
  constructor(options: RedisOptions);
  constructor(port: number, options: RedisOptions);
  constructor(port: number, host: string);
  constructor(port: number, host: string, options: RedisOptions);
  constructor(path: string, options: RedisOptions);
  
  connect(callback?: Callback<void>): Promise<void>;
  quit(callback?: Callback<"OK">): Promise<"OK">;
  duplicate(override?: Partial<RedisOptions>): Redis;
}
```

[Redis Client](./redis-client.md)

### Cluster Client

Redis Cluster client with automatic slot management, node discovery, and failover handling.

```typescript { .api }
class Cluster extends EventEmitter {
  constructor(startupNodes: ClusterNode[], options?: ClusterOptions);
  
  connect(): Promise<void>;
  quit(callback?: Callback<"OK">): Promise<"OK">;
  nodes(role?: NodeRole): Redis[];
  refreshSlotsCache(callback?: Callback<void>): void;
}

type ClusterNode = string | number | {
  host?: string;
  port?: number;
};
```

[Cluster Operations](./cluster.md)

### Configuration Options

Comprehensive configuration interfaces for Redis connections including network settings, behavior options, and advanced features.

```typescript { .api }
interface RedisOptions {
  host?: string;
  port?: number;
  password?: string;
  db?: number;
  retryStrategy?: (times: number) => number | void | null;
  enableAutoPipelining?: boolean;
  maxRetriesPerRequest?: number | null;
  // ... extensive additional options
}

interface ClusterOptions extends Partial<RedisOptions> {
  clusterRetryStrategy?: (times: number, reason?: Error) => number | void | null;
  scaleReads?: NodeRole | Function;
  maxRedirections?: number;
  // ... additional cluster-specific options
}
```

[Configuration](./configuration.md)

### Command Execution

Complete Redis command interface with promise-based returns, callback support, and proper TypeScript typing for all Redis operations.

```typescript { .api }
// String operations
get(key: RedisKey): Promise<string | null>;
set(key: RedisKey, value: RedisValue): Promise<"OK">;
set(key: RedisKey, value: RedisValue, expiryMode: "EX", time: number): Promise<"OK">;

// Hash operations  
hget(key: RedisKey, field: string): Promise<string | null>;
hset(key: RedisKey, field: string, value: RedisValue): Promise<number>;

// List operations
lpush(key: RedisKey, ...values: RedisValue[]): Promise<number>;
lrange(key: RedisKey, start: number, stop: number): Promise<string[]>;
```

[Redis Commands](./commands.md)

### Pipelining & Transactions

Efficient command batching and atomic transaction support with MULTI/EXEC operations.

```typescript { .api }
pipeline(commands?: unknown[][]): ChainableCommander;
multi(options?: { pipeline?: boolean }): ChainableCommander | Promise<"OK">;

interface ChainableCommander {
  exec(callback?: Callback): Promise<Array<[Error | null, any]>>;
  // All Redis commands available for chaining
}
```

[Pipelining & Transactions](./pipelining.md)

### Pub/Sub Messaging

Complete publish/subscribe support including pattern subscriptions and message handling.

```typescript { .api }
subscribe(...channels: string[]): Promise<number>;
unsubscribe(...channels: string[]): Promise<number>;
psubscribe(...patterns: string[]): Promise<number>;
publish(channel: string, message: string): Promise<number>;

// Event handlers
on(event: 'message', listener: (channel: string, message: string) => void): this;
on(event: 'pmessage', listener: (pattern: string, channel: string, message: string) => void): this;
```

[Pub/Sub Messaging](./pubsub.md)

### Streaming Operations

Readable streams for efficient scanning of large datasets using Redis SCAN operations.

```typescript { .api }
scanStream(options?: ScanStreamOptions): ScanStream;
sscanStream(key: string, options?: ScanStreamOptions): ScanStream;
hscanStream(key: string, options?: ScanStreamOptions): ScanStream;
zscanStream(key: string, options?: ScanStreamOptions): ScanStream;

interface ScanStreamOptions {
  match?: string;
  count?: number;
  type?: string;
}

class ScanStream extends Readable {
  close(): void;
}
```

[Streaming](./streaming.md)

### Lua Scripting

Define custom Redis commands using Lua scripts with automatic script caching and EVAL/EVALSHA optimization.

```typescript { .api }
defineCommand(
  name: string,
  definition: {
    lua: string;
    numberOfKeys?: number;
    readOnly?: boolean;
  }
): void;

// Built-in scripting commands
eval(script: string, numKeys: number, ...keysAndArgs: any[]): Promise<any>;
evalsha(sha: string, numKeys: number, ...keysAndArgs: any[]): Promise<any>;
script(subcommand: "LOAD" | "EXISTS" | "FLUSH" | "KILL", ...args: any[]): Promise<any>;
```

**Usage Examples:**

```typescript
import Redis from "ioredis";

const redis = new Redis();

// Define a custom command
redis.defineCommand("myecho", {
  numberOfKeys: 1,
  lua: "return KEYS[1] .. ARGV[1]",
});

// Use the custom command (TypeScript will provide typing)
const result = await redis.myecho("key", "value"); // Returns "keyvalue"

// Define command via constructor options (see Configuration docs)
const redis2 = new Redis({
  scripts: {
    increment: {
      lua: `
        local key = KEYS[1]
        local limit = tonumber(ARGV[1])
        local current = redis.call('GET', key) or 0
        if tonumber(current) < limit then
          return redis.call('INCR', key)
        else
          return current
        end
      `,
      numberOfKeys: 1,
    }
  }
});
```

[Configuration](./configuration.md)

## Core Types

```typescript { .api }
type RedisKey = string | Buffer;
type RedisValue = string | Buffer | number;
type NodeRole = "master" | "slave" | "all";
type Callback<T> = (err?: Error | null, result?: T) => void;

interface SentinelAddress {
  host: string;
  port: number;
}

interface ClusterNode {
  host?: string;
  port?: number;
}

type NatMapFunction = (key: string) => { host: string; port: number } | null;
type NatMap = {
  [key: string]: { host: string; port: number };
} | NatMapFunction;

type DNSLookupFunction = (
  hostname: string,
  callback: (err: NodeJS.ErrnoException | null | undefined, address: string, family?: number) => void
) => void;

type DNSResolveSrvFunction = (
  hostname: string,
  callback: (err: NodeJS.ErrnoException | null | undefined, records?: any[]) => void
) => void;

// Utility function for debugging Redis responses
function print(err: Error | null, reply?: any): void;

// ReplyError is imported from redis-errors package
const ReplyError: typeof import("redis-errors").ReplyError;
```