or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-connect-redis

Redis session store for Express.js applications using connect-redis middleware

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/connect-redis@9.0.x

To install, run

npx @tessl/cli install tessl/npm-connect-redis@9.0.0

index.mddocs/

Connect-Redis

Connect-Redis provides a Redis-based session store implementation for Express.js applications using the express-session middleware. It enables persistent session storage in Redis databases with support for both standalone Redis clients and Redis clusters, configurable serialization, TTL management, and seamless integration with Express.js applications.

Package Information

  • Package Name: connect-redis
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install redis connect-redis express-session

Core Imports

import { RedisStore } from "connect-redis";
import type { SessionData } from "express-session";

For CommonJS:

const { RedisStore } = require("connect-redis");

Basic Usage

import { RedisStore } from "connect-redis";
import session from "express-session";
import { createClient } from "redis";

// Initialize Redis client
const redisClient = createClient();
await redisClient.connect();

// Initialize RedisStore
const redisStore = new RedisStore({
  client: redisClient,
  prefix: "myapp:",
});

// Use with express-session
app.use(
  session({
    store: redisStore,
    resave: false,
    saveUninitialized: false,
    secret: "keyboard cat",
  })
);

Architecture

Connect-Redis implements the express-session Store interface, providing:

  • Redis Integration: Compatible with both single Redis instances and Redis clusters
  • Session Persistence: Stores session data in Redis with configurable key prefixes
  • TTL Management: Automatic session expiration based on cookie settings or custom TTL configuration
  • Serialization: Configurable session data serialization (defaults to JSON)
  • Bulk Operations: Efficient session management using Redis SCAN operations
  • Callback & Promise Support: All methods support both callback-style and Promise-based usage

Capabilities

RedisStore Constructor

Creates a new Redis session store instance with the specified configuration.

/**
 * Creates a new RedisStore instance
 * @param opts - Configuration options for the Redis store
 */
constructor(opts: RedisStoreOptions);

interface RedisStoreOptions {
  /** Redis client instance (RedisClientType or RedisClusterType) */
  client: any;
  /** Key prefix for session keys in Redis (default: "sess:") */
  prefix?: string;
  /** Count parameter for Redis SCAN operations (default: 100) */
  scanCount?: number;
  /** Custom serializer for session data (default: JSON) */
  serializer?: Serializer;
  /** TTL in seconds or function returning TTL (default: 86400) */
  ttl?: number | ((sess: SessionData) => number);
  /** Disable automatic key expiration (default: false) */
  disableTTL?: boolean;
  /** Disable TTL reset on session touch (default: false) */
  disableTouch?: boolean;
}

interface Serializer {
  /** Parse session data from string */
  parse(s: string): SessionData | Promise<SessionData>;
  /** Serialize session data to string */
  stringify(s: SessionData): string;
}

Usage Example:

import { RedisStore } from "connect-redis";
import { createClient } from "redis";

const redisClient = createClient({ url: "redis://localhost:6379" });
await redisClient.connect();

// Basic configuration
const store = new RedisStore({
  client: redisClient,
});

// Advanced configuration
const advancedStore = new RedisStore({
  client: redisClient,
  prefix: "myapp:sess:",
  ttl: 3600, // 1 hour
  scanCount: 200,
  disableTouch: true,
  serializer: {
    parse: JSON.parse,
    stringify: JSON.stringify,
  },
});

// Dynamic TTL based on session data
const dynamicTTLStore = new RedisStore({
  client: redisClient,
  ttl: (sess) => {
    // VIP users get longer sessions
    return sess.user?.type === 'vip' ? 7200 : 3600;
  },
});

Session Retrieval

Retrieves session data by session ID.

/**
 * Get session data by session ID
 * @param sid - Session ID
 * @param cb - Optional callback function
 * @returns Promise resolving to session data or null if not found
 */
async get(sid: string, cb?: (err?: unknown, data?: any) => any): Promise<any>;

Usage Example:

// Promise-based
const sessionData = await store.get("session123");
if (sessionData) {
  console.log("Session found:", sessionData);
}

// Callback-based
store.get("session123", (err, data) => {
  if (err) {
    console.error("Error retrieving session:", err);
  } else if (data) {
    console.log("Session found:", data);
  }
});

Session Storage

Stores session data with the specified session ID.

/**
 * Store session data with session ID
 * @param sid - Session ID
 * @param sess - Session data to store
 * @param cb - Optional callback function
 * @returns Promise resolving when storage is complete
 */
async set(sid: string, sess: SessionData, cb?: (err?: unknown, data?: any) => any): Promise<any>;

Usage Example:

const sessionData = {
  user: { id: 123, name: "Alice" },
  cart: ["item1", "item2"],
  cookie: { originalMaxAge: null },
};

// Promise-based
await store.set("session123", sessionData);

// Callback-based
store.set("session123", sessionData, (err) => {
  if (err) {
    console.error("Error storing session:", err);
  } else {
    console.log("Session stored successfully");
  }
});

Session Touch

Updates session TTL without changing session data, used to keep sessions alive.

/**
 * Update session TTL without changing data
 * @param sid - Session ID
 * @param sess - Session data (used for TTL calculation)
 * @param cb - Optional callback function
 * @returns Promise resolving when touch is complete
 */
async touch(sid: string, sess: SessionData, cb?: (err?: unknown, data?: any) => any): Promise<any>;

Session Destruction

Deletes a session by session ID.

/**
 * Delete session by session ID
 * @param sid - Session ID to delete
 * @param cb - Optional callback function
 * @returns Promise resolving when deletion is complete
 */
async destroy(sid: string, cb?: (err?: unknown, data?: any) => any): Promise<any>;

Usage Example:

// Promise-based
await store.destroy("session123");

// Callback-based
store.destroy("session123", (err) => {
  if (err) {
    console.error("Error destroying session:", err);
  } else {
    console.log("Session destroyed");
  }
});

Bulk Session Operations

Clear All Sessions

Removes all sessions with the configured prefix.

/**
 * Remove all sessions with matching prefix
 * @param cb - Optional callback function
 * @returns Promise resolving when clearing is complete
 */
async clear(cb?: (err?: unknown, data?: any) => any): Promise<any>;

Get Session Count

Returns the count of sessions with the configured prefix.

/**
 * Get count of sessions with matching prefix
 * @param cb - Optional callback function
 * @returns Promise resolving to the number of sessions
 */
async length(cb?: (err?: unknown, data?: any) => any): Promise<any>;

Get Session IDs

Returns an array of session IDs (without prefix).

/**
 * Get array of session IDs (without prefix)
 * @param cb - Optional callback function
 * @returns Promise resolving to array of session IDs
 */
async ids(cb?: (err?: unknown, data?: any) => any): Promise<any>;

Get All Sessions

Returns all session data with their IDs.

/**
 * Get all session data with IDs
 * @param cb - Optional callback function
 * @returns Promise resolving to array of session objects with IDs
 */
async all(cb?: (err?: unknown, data?: any) => any): Promise<any>;

Bulk Operations Usage Example:

// Get session statistics
const sessionCount = await store.length();
console.log(`Total sessions: ${sessionCount}`);

// Get all session IDs
const sessionIds = await store.ids();
console.log("Session IDs:", sessionIds);

// Get all session data
const allSessions = await store.all();
allSessions.forEach(session => {
  console.log(`Session ${session.id}:`, session);
});

// Clear all sessions (use with caution)
await store.clear();

Types

interface RedisStoreOptions {
  client: any;
  prefix?: string;
  scanCount?: number;
  serializer?: Serializer;
  ttl?: number | ((sess: SessionData) => number);
  disableTTL?: boolean;
  disableTouch?: boolean;
}

interface Serializer {
  parse(s: string): SessionData | Promise<SessionData>;
  stringify(s: SessionData): string;
}

interface SessionData {
  /** Session cookie configuration */
  cookie: {
    /** Original max age in milliseconds */
    originalMaxAge: number | null;
    /** Optional expiration date */
    expires?: Date | string;
    /** Additional cookie properties */
    [key: string]: any;
  };
  /** User-defined session properties */
  [key: string]: any;
}

type Callback = (err?: unknown, data?: any) => any;

Error Handling

All methods handle Redis connection errors and serialization errors gracefully. When using callbacks, errors are passed as the first parameter. When using Promises, errors are thrown and should be caught:

// Promise-based error handling
try {
  const sessionData = await store.get("session123");
} catch (error) {
  console.error("Redis error:", error);
}

// Callback-based error handling
store.get("session123", (err, data) => {
  if (err) {
    console.error("Redis error:", err);
    return;
  }
  // Handle data
});

Configuration Best Practices

TTL Configuration

// Static TTL (1 hour)
const store = new RedisStore({
  client: redisClient,
  ttl: 3600,
});

// Dynamic TTL based on session data
const store = new RedisStore({
  client: redisClient,
  ttl: (sess) => {
    if (sess.user?.premium) return 86400; // 24 hours for premium users
    return 3600; // 1 hour for regular users
  },
});

// Disable TTL for manual management
const store = new RedisStore({
  client: redisClient,
  disableTTL: true,
});

Custom Serialization

import { RedisStore } from "connect-redis";

// Custom serializer for compressed sessions
const store = new RedisStore({
  client: redisClient,
  serializer: {
    stringify: (obj) => {
      return Buffer.from(JSON.stringify(obj)).toString('base64');
    },
    parse: (str) => {
      return JSON.parse(Buffer.from(str, 'base64').toString());
    },
  },
});

Redis Cluster Support

import { createCluster } from "redis";

// Redis cluster configuration
const cluster = createCluster({
  rootNodes: [
    { url: "redis://localhost:7000" },
    { url: "redis://localhost:7001" },
    { url: "redis://localhost:7002" },
  ],
});

await cluster.connect();

const store = new RedisStore({
  client: cluster,
  prefix: "sessions:",
});