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
Easy to extend client with internal & external commands
Customizable transaction handling
Plugin architecture support
Lightweight
Zero dependencies
Minimum bundle size < 30KB
Full bundle size (with all commands) < 105KB
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:
1. Basic Client (SolidisClient)
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';importtype{SolidisClientExtensions}from'@vcms-io/solidis';// Define extensions with type safetyconstextensions={
get,
set,
multi
}satisfiesSolidisClientExtensions;// Initialize client with extensionsconstclient=newSolidisClient({host: '127.0.0.1',port: 6379}).extend(extensions);// Use commandsawaitclient.set('key','value');constvalue=awaitclient.get('key');
2. Featured Client (SolidisFeaturedClient)
A convenience client with all RESP commands pre-loaded:
import{SolidisFeaturedClient}from'@vcms-io/solidis/featured';// All RESP commands are pre-loadedconstclient=newSolidisFeaturedClient({host: '127.0.0.1',port: 6379});// Use any RESP command directlyawaitclient.set('key','value');awaitclient.hset('hash','field','value');awaitclient.lpush('list','item-1','item-2');
// Create client (with lazy connect)constclient=newSolidisClient({host: '127.0.0.1',port: 6379,lazyConnect: true}).extend({ get, set });// Explicitly connect when neededawaitclient.connect();// Handle connection eventsclient.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 doneclient.quit();
// Set a keyawaitclient.set('key','value');// Get a keyconstvalue=awaitclient.get('key');console.log(value);// 'value'// Delete a keyawaitclient.del('key');
// Start a transactionconsttransaction=client.multi();// Queue commands (no await needed)transaction.set('key','value');transaction.incr('counter');transaction.get('key');// Execute transactionconstresults=awaittransaction.exec();console.log(results);// [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]// Or discard a transaction if neededconsttransaction=client.multi();transaction.set('key','value');transaction.discard();// Cancel transaction
// Create commands for a pipelineconstcommands=[['set','pipeline','value'],['incr','counter'],['get','pipeline']];// Send commands as a pipelineconstresults=awaitclient.send(commands);console.log(results);// [[ 'OK' ], [ 1 ], [ <Buffer 76 61 6c 75 65> ]]
// Subscribe to channelsclient.on('message',(channel,message)=>{console.log(`Received ${message} from ${channel}`);});awaitclient.subscribe('news');// Publish from another clientawaitclient.publish('news','Hello world!');
Solidis provides detailed error classes for different failure modes:
import{SolidisClientError,SolidisConnectionError,SolidisParserError,SolidisPubSubError,SolidisRequesterError,unwrapSolidisError,}from'@vcms-io/solidis';try{awaitclient.set('key','value');}catch(error){// Get the root cause with stack traceconsole.error(unwrapSolidisError(error));// Handle specific error typesif(errorinstanceofSolidisConnectionError){console.error('Connection error:',error.message);}elseif(errorinstanceofSolidisParserError){console.error('Parser error:',error.message);}elseif(errorinstanceofSolidisClientError){console.error('Client error:',error.message);}}
The Solidis structure follows a clear component separation:
SolidisClient: Core entry point that creates and coordinates all components
Debug Memory: Created in the client and injected into other components
Connection: Manages TCP/TLS socket connections, reconnection and recovery
Requester: Handles command pipelining & request states
Parser: Processes RESP2/RESP3 protocol with optimized buffer handling
PubSub: Maintains subscription state and is used by Requester for pub/sub events
Solidis emits the following events:
// Connection eventsclient.on('connect',()=>console.log('Connected to server'));client.on('ready',()=>console.log('Client is ready'));client.on('end',()=>console.log('Connection closed'));client.on('error',(err)=>console.error('Error:',err));// Pub/Sub eventsclient.on('message',(channel,message)=>console.log(`${channel}: ${message}`));client.on('pmessage',(pattern,channel,message)=>console.log(`${pattern}${channel}: ${message}`));client.on('subscribe',(channel,count)=>console.log(`Subscribed to ${channel}`));client.on('unsubscribe',(channel,count)=>console.log(`Unsubscribed from ${channel}`));// Debug eventsclient.on('debug',(entry)=>console.log(`[${entry.type}] ${entry.message}`));
Solidis is an open-source project and we welcome contributions from the community. Here's how you can contribute:
# Clone the repository
git clone https://github.com/vcms-io/solidis.git
cd solidis
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
Fork the Repository: Start by forking the repository and then clone your fork.
Create a Branch: Create a branch for your feature or bugfix:
git checkout -b feature/your-feature-name
Follow Code Style:
Use TypeScript strict mode
Follow existing patterns and naming conventions
Submit Pull Request: Push your changes to your fork and submit a pull request.
Provide a clear description of the changes
Reference any related issues
Add appropriate documentation
TypeScript: Use strict typing and avoid any types and as cast where possible
Dependencies: Avoid adding new dependencies unless absolutely necessary
Performance: Consider performance implications of your changes
Bundle Size: Keep the bundle size minimal
Solidis follows semantic versioning (SemVer):
Patch (0.0.x): Bug fixes and minor changes that don't affect the API
Minor (0.x.0): New features added in a backward compatible manner
Major (x.0.0): Breaking changes to the public API
Licensed under the MIT. See LICENSE for more informations.