High-performance, SOLID-structured RESP client for Redis and other RESP-compatible servers
Overview β’
Benchmarks β’
Features β’
Installation β’
Usage β’
Configuration β’
Advanced
Extensions β’
Errors β’
Contributing β’
License
Solidis is a modern RESP client built with SOLID principles, zero dependencies, and enterprise-grade performance in mind. It supports both RESP2 and RESP3 protocols and is optimized for modern JavaScript/TypeScript applications.
The library is designed for minimal bundle size with maximum type safety and performance:
- Pure ESM/CJS - Support for both module systems
- Tree-shakable - Import only what you need
- Type-safe - Extensive TypeScript definitions for all commands
- Dependency-free - Absolutely zero runtime dependencies
1000 concurrent commands Γ 10 iterations, 1 KB random-string payload per request
Benchmark | Solidis | IoRedis | Speed Boost π |
---|---|---|---|
Hash HSET + HGET + HGETALL |
248.82ms | 446.03ms | 79% FASTER π₯π₯ |
Set Operations SADD + SISMEMBER + SREM |
257.35ms | 444.08ms | 73% FASTER π₯π₯ |
Expire SET + EXPIRE + TTL |
198.11ms | 339.78ms | 72% FASTER π₯π₯ |
Non-Transaction SET with EXPIRE + GET |
259.69ms | 394.34ms | 52% FASTER π₯ |
List LPUSH + RPUSH + LRANGE |
219.76ms | 345.48ms | 57% FASTER π₯ |
Counter INCR + DECR |
174.04ms | 258.71ms | 49% FASTER π₯ |
List operations LPUSH + RPUSH + LPOP + RPOP + LLEN |
396.67ms | 587.16ms | 48% FASTER π₯ |
Transaction + Non-Transaction SET + GET |
435.46ms | 574.26ms | 32% FASTER β‘οΈ |
Multi-key MSET + MGET |
393.87ms | 437.45ms | 11% FASTER β‘οΈ |
Transaction SET with EXPIRE + GET |
286.75ms | 328.00ms | 14% FASTER β‘οΈ |
Set SADD + SISMEMBER + SMEMBERS |
260.66ms | 275.27ms | 6% FASTER β‘οΈ |
Hash operations HMSET + HMGET + HDEL |
360.69ms | 377.32ms | 5% FASTER β‘οΈ |
Info/Config INFO + CONFIG GET |
371.48ms | 353.02ms | 5% slower |
Up to 79% faster than IoRedis! π
Solidis delivers blazing-fast performance with ZERO dependencies
-
Lightweight
- Zero dependencies
- Minimum bundle size < 30KB
- Full bundle size (with all commands) < 105KB
-
High Performance
- Efficient pipeline & batch processing
- Minimal memory footprint (custom optimized parser)
- Zero-copy buffer operations
- Intelligent buffer management
-
Protocol Support
- RESP2 & RESP3 protocols support
- Automatic protocol negotiation
- Binary-safe operations
- Full multi-byte character support
-
Advanced Features
- Transaction support (MULTI/EXEC)
- Pipeline operations
- Pub/Sub functionality
- Automatic reconnection
- Command timeout handling
-
Type Safety
- Robust TypeScript support
- Comprehensive type definitions
- Command-specific type guards
- Runtime reply type checking
-
Extensibility
- Easy to extend client with internal & external commands
- Customizable transaction handling
- Plugin architecture support
- Runtime: Node.js 14 or higher
- Development: Node.js 22 LTS recommended for optimal stability
# Using npm
npm install @vcms-io/solidis
# Using yarn
yarn add @vcms-io/solidis
# Using pnpm
pnpm add @vcms-io/solidis
Solidis offers two client implementations:
The basic client contains minimal functionality to reduce bundle size. You need to extend it with specific commands:
import { SolidisClient } from '@vcms-io/solidis';
import { get } from '@vcms-io/solidis/command/get';
import { set } from '@vcms-io/solidis/command/set';
import { multi } from '@vcms-io/solidis/command/multi';
import type { SolidisClientExtensions } from '@vcms-io/solidis';
// Define extensions with type safety
const extensions = {
get,
set,
multi
} satisfies SolidisClientExtensions;
// Initialize client with extensions
const client = new SolidisClient({
host: '127.0.0.1',
port: 6379
}).extend(extensions);
// Use commands
await client.set('key', 'value');
const value = await client.get('key');
A convenience client with all RESP commands pre-loaded:
import { SolidisFeaturedClient } from '@vcms-io/solidis/featured';
// All RESP commands are pre-loaded
const client = new SolidisFeaturedClient({
host: '127.0.0.1',
port: 6379
});
// Use any RESP command directly
await client.set('key', 'value');
await client.hset('hash', 'field', 'value');
await client.lpush('list', 'item-1', 'item-2');
// Create client (with lazy connect)
const client = new SolidisClient({
uri: 'redis://127.0.0.1:6379',
lazyConnect: true
}).extend({ get, set });
// Explicitly connect when needed
await client.connect();
// Handle connection events
client.on('connect', () => console.log('Connected to server'));
client.on('ready', () => console.log('Client is ready for commands'));
client.on('error', (err) => console.error('Error occurred:', err));
client.on('end', () => console.log('Connection closed'));
// Close connection when done
client.quit();
// Set a key
await client.set('key', 'value');
// Get a key
const value = await client.get('key');
console.log(value); // 'value'
// Delete a key
await client.del('key');
// Start a transaction
const transaction = client.multi();
// Queue commands (no await needed)
transaction.set('key', 'value');
transaction.incr('counter');
transaction.get('key');
// Execute transaction
const results = await transaction.exec();
console.log(results); // [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]
// Or discard a transaction if needed
const transaction = client.multi();
transaction.set('key', 'value');
transaction.discard(); // Cancel transaction
// Create commands for a pipeline
const commands = [
['set', 'pipeline', 'value'],
['incr', 'counter'],
['get', 'pipeline']
];
// Send commands as a pipeline
const results = await client.send(commands);
console.log(results); // [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]
// Subscribe to channels
client.on('message', (channel, message) => {
console.log(`Received ${message} from ${channel}`);
});
await client.subscribe('news');
// Publish from another client
await client.publish('news', 'Hello world!');
Solidis provides extensive configuration options:
const client = new SolidisClient({
// Connection
uri: 'redis://localhost:6379',
host: '127.0.0.1',
port: 6379,
useTLS: false,
lazyConnect: false,
// Authentication
authentication: {
username: 'user',
password: 'password'
},
database: 0,
// Protocol & Recovery
clientName: 'solidis',
protocol: 'RESP2', // 'RESP2' or 'RESP3'
autoReconnect: true,
enableReadyCheck: true,
maxConnectionRetries: 20,
connectionRetryDelay: 100,
autoRecovery: {
database: true, // Auto-select DB after reconnect
subscribe: true, // Auto-resubscribe to channels
ssubscribe: true, // Auto-resubscribe to shard channels
psubscribe: true, // Auto-resubscribe to patterns
},
// Timeouts (milliseconds)
commandTimeout: 5000,
connectionTimeout: 2000,
socketWriteTimeout: 1000,
readyCheckInterval: 100,
// Performance Tuning
maxCommandsPerPipeline: 300,
maxProcessRepliesPerChunk: 4 * 1024, // 4KB
maxSocketWriteSizePerOnce: 64 * 1024, // 64KB
rejectOnPartialPipelineError: false,
// Parser Configuration
parser: {
buffer: {
initial: 4 * 1024 * 1024, // 4MB
shiftThreshold: 2 * 1024 * 1024, // 2MB
},
},
// Event Listeners
maxEventListenersForClient: 10 * 1024,
maxEventListenersForSocket: 10 * 1024,
// Debug Options
debug: false,
debugMaxEntries: 10 * 1024,
});