The Ultimate Multi-Session WhatsApp Management Library for Node.js
Manage multiple WhatsApp sessions with ease β no browser automation, no Selenium, just pure WebSocket + session management.
Built for developers who want to manage WhatsApp multi-session programmatically using Baileys.
βοΈ Smart Session Protection | π₯ Auto-Reconnection | π¬ Event Forwarding | π§ Built for Bots, API & Automation
ShardManager supports nearly all Baileys features β designed for both simple and advanced use cases
- β Lightweight β No browser automation or Puppeteer, pure WebSocket communication
- β Multi-Session β Manage hundreds of WhatsApp sessions in single application
- β Smart Protection β Registered sessions are protected from auto-cleanup
- β Auto-Recovery β Automatic reconnection on disconnect with retry mechanism
- π§ Session Validation β Automatically detect corrupt or invalid sessions
- π₯ QR & Pairing Code β Support both authentication methods
- π Event Forwarding β Forward all Baileys events with shard identification
- π€ Connection State β Real-time connection status tracking for each shard
- π Session Info β Check registered, valid status and error reasons
- π€ Shard Management β Create, stop, recreate, and load multiple shards
- π§ Error Handling β Comprehensive error codes and handling
- πΌοΈ Event Isolation β Listen to events from specific shard or globally
- π¨ TypeScript Support β Fully typed with JSDoc for better intellisense
- Getting Started
- Install - How to Install ShardManager Library
- Basic Usage - Basic Usage for single session
- Advanced Usage - Advanced Usage for multi-session
- Core Function List
- constructor - Initialize ShardManager with config
- createShard - Create new shard or reuse existing registered session
- recreateShard - Recreate existing shard with session protection
- loadAllShards - Load all existing sessions from directory
- Session Management
- getSessionInfo - Check session status from specific shard
- checkSessionStatus - Low-level session validation
- validateAndCleanSession - Validate and cleanup session if needed
- cleanupCorruptSessions - Auto cleanup all corrupt sessions
- Shard Control
- Information & Monitoring
- getShardInfo - Get runtime information from specific shard
- getAllShardInfo - Get runtime information of all shards
- Event System
- Event Forwarding - How event forwarding system works
- Connection Events - Handle connection state changes
- Message Events - Handle message events from shards
- Error Events - Handle error events with error codes
- Issues
To install ShardManager, you can use
- using NPM (Node Package Manager)
npm install baileys-shard - Using Yarn
yarn add baileys-shard
- CommonJS
const { ShardManager } = require("baileys-shard"); (async function() { const manager = new ShardManager({ session: "./sessions" // directory for session storage }); // Create shard for single bot const { id, sock } = await manager.createShard({ id: "main-bot", phoneNumber: "6281234567890" // optional for pairing code }); console.log(`Shard ${id} created successfully!`); })()
- TypeScript/ESM
import { ShardManager } from "baileys-shard"; const manager = new ShardManager({ session: "./sessions" }); // Listen connection updates manager.on("login.update", ({ shardId, state, type, code, image }) => { if (type === "pairing") { console.log(`Pairing code for ${shardId}: ${code}`); } else if (state === "connected") { console.log(`${shardId} successfully connected!`); } }); // Create multiple shards const { id: bot1 } = await manager.createShard({ id: "bot-1", phoneNumber: "6281234567890" }); const { id: bot2 } = await manager.createShard({ id: "bot-2", phoneNumber: "6281234567891" });
Multi-session management with auto-load and event handling:
import { ShardManager } from "baileys-shard";
const manager = new ShardManager({ session: "./sessions" });
// Load all existing sessions on startup
const existingShards = await manager.loadAllShards();
console.log("Loaded existing shards:", existingShards);
// Handle messages from all shards
manager.on("messages.upsert", async ({ shardId, sock, data }) => {
for (const msg of data.messages) {
if (!msg.key.fromMe && msg.message?.conversation) {
await sock.sendMessage(msg.key.remoteJid, {
text: `Hello from ${shardId}! You said: ${msg.message.conversation}`
});
}
}
});
// Handle errors with retry logic
manager.on("shard.error", async ({ shardId, error }) => {
console.error(`Error on ${shardId}:`, error.message);
if (error.code === "RECREATE_FAILED") {
// Implement custom retry logic
setTimeout(() => {
manager.recreateShard({ id: shardId, clearSession: true });
}, 10000);
}
});
// Create bot farm
for (let i = 1; i <= 10; i++) {
await manager.createShard({
id: `bot-${i}`,
phoneNumber: `62812345678${i.toString().padStart(2, '0')}`
});
}Main functions for managing shard lifecycle and session management.
-
Initialize ShardManager with session directory configuration.
const manager = new ShardManager({ session: "./my-sessions" // default: "./sessions" });
Param Require Type Description config falseShardConfigConfiguration object with session directory property config.session falsestringPath to directory for storing session files (default: "./sessions") -
Create new shard or reuse existing registered session with smart session protection.
// Basic create const { id, sock } = await manager.createShard(); // With custom ID and phone number const { id, sock } = await manager.createShard({ id: "my-custom-bot", phoneNumber: "6281234567890", socket: { printQRInTerminal: true, // other baileys socket options } });
Param Require Type Description options falseShardOptionsConfiguration for shard creation options.id falsestringCustom shard ID, auto-generated if not provided options.phoneNumber falsestringPhone number for pairing code authentication options.socket falseobjectAdditional Baileys socket configuration Return:
Promise<{ id: string, sock: WASocket }>- Shard ID and Baileys socket instance -
Recreate existing shard with option to force clear session. This function has built-in protection for registered sessions.
// Recreate without clearing session (protect registered session) await manager.recreateShard({ id: "my-bot" }); // Force recreate with session clear await manager.recreateShard({ id: "my-bot", clearSession: true, forceRecreate: true });
Param Require Type Description options trueobjectRecreate options options.id truestringShard ID to recreate options.clearSession falsebooleanForce clear session files (default: false) options.forceRecreate falsebooleanForce recreate even if session is valid (default: false) options.retryCount falsenumberInternal retry counter (don't set manually) Return:
Promise<{ id: string, sock: WASocket }>- New shard instance -
Load all existing sessions from session directory and create shard for each.
const shardIds = await manager.loadAllShards(); console.log("Successfully loaded shards:", shardIds); // Output: ["bot-1", "bot-2", "main-session"]
Param Require Type Description none falsenull- Return:
Promise<string[]>- Array of loaded shard IDs
Functions for managing session validation, cleanup, and protection.
-
Check session status from specific shard with detailed information.
const info = await manager.getSessionInfo("my-bot"); console.log(info); // Output: { exists: true, registered: true, valid: true } // If there's an issue // Output: { exists: true, registered: false, valid: false, reason: "Missing required fields" }
Param Require Type Description id truestringShard ID to check session Return:
Promise<{ exists: boolean, registered: boolean, valid: boolean, reason?: string }>- Session status information -
Low-level function to validate session files directly.
const status = await manager.checkSessionStatus("./sessions/my-bot"); if (status.valid && status.registered) { console.log("Session is good to use"); } else { console.log("Session issue:", status.reason); }
Param Require Type Description sessionDirectory truestringFull path to session directory Return:
Promise<{ exists: boolean, registered: boolean, valid: boolean, reason?: string }>- Detailed session status -
Validate session and auto-cleanup if corrupt, but protect registered sessions.
// Will only clean if session is corrupt or not registered await manager.validateAndCleanSession("./sessions/my-bot");
Param Require Type Description sessionDirectory truestringFull path to session directory for validation Return:
Promise<void>- No return value -
Auto cleanup all corrupt sessions from session directory on startup.
// Usually called automatically in constructor await manager.cleanupCorruptSessions(); console.log("Cleanup completed");
Param Require Type Description none falsenull- Return:
Promise<void>- No return value
Functions for controlling shard lifecycle and accessing shard instances.
-
Connect to existing shard or recreate if not exists.
const { id, sock } = await manager.connect("my-bot"); console.log(`Connected to shard: ${id}`);
Param Require Type Description id truestringShard ID to connect Return:
Promise<{ id: string, sock: WASocket }>- Shard connection info -
Stop specific shard and cleanup resources.
const success = await manager.stopShard("my-bot"); if (success) { console.log("Shard stopped successfully"); }
Param Require Type Description id truestringShard ID to stop Return:
Promise<boolean>- Success status -
Get Baileys socket instance from specific shard for direct interaction.
const sock = manager.socket("my-bot"); if (sock) { await sock.sendMessage("6281234567890@s.whatsapp.net", { text: "Hello from direct socket access!" }); }
Param Require Type Description id truestringShard ID Return:
WASocket | undefined- Baileys socket instance or undefined if not exists -
Get EventEmitter to listen events from specific shard only.
const shardEmitter = manager.shard("my-bot"); if (shardEmitter) { shardEmitter.on("messages.upsert", ({ data }) => { console.log("Message only from my-bot:", data.messages); }); }
Param Require Type Description id truestringShard ID Return:
EventEmitter | null- EventEmitter instance or null if shard doesn't exist
Functions for monitoring shard status and runtime information.
-
Get runtime information from specific shard like status, index, and metadata.
const info = manager.getShardInfo("my-bot"); console.log(info); // Output: { id: "my-bot", index: 1, total: 5, phoneNumber: "6281234567890", status: "connected" }
Param Require Type Description id truestringShard ID Return:
ShardInfo | null- Runtime shard information or null if not exists -
Get runtime information from all active shards.
const allInfo = manager.getAllShardInfo(); console.log(`Total active shards: ${allInfo.length}`); allInfo.forEach(info => { console.log(`${info.id}: ${info.status}`); });
Param Require Type Description none falsenull- Return:
ShardInfo[]- Array of all shard runtime information
Comprehensive event handling system with shard identification and error management.
ShardManager automatically forwards all Baileys events with additional shardId for identification.
Handle connection state changes for each shard:
manager.on("login.update", ({ shardId, state, type, code, image }) => {
switch (state) {
case "connecting":
if (type === "qr") {
console.log(`QR Code ready for ${shardId}`);
// `image` contains QR code buffer
fs.writeFileSync(`./qr-${shardId}.png`, image);
} else if (type === "pairing") {
console.log(`Pairing code for ${shardId}: ${code}`);
}
break;
case "connected":
console.log(`β
${shardId} successfully connected`);
break;
case "disconnected":
console.log(`β οΈ ${shardId} disconnected, will reconnect...`);
break;
case "logged_out":
console.log(`β ${shardId} logged out, session cleared`);
break;
case "creds_saved":
console.log(`πΎ Credentials ${shardId} saved`);
break;
}
});| Property | Type | Description |
|---|---|---|
| shardId | string |
ID of shard experiencing update |
| state | string |
Connection state: "connecting", "connected", "disconnected", "logged_out", "creds_saved" |
| type | string |
Auth type: "qr" or "pairing" (only when connecting) |
| code | string |
Pairing code (only when type: "pairing") |
| image | Buffer |
QR code image buffer (only when type: "qr") |
Handle message events from all shards with shard identification:
manager.on("messages.upsert", async ({ shardId, sock, data }) => {
console.log(`π¨ New messages from ${shardId}`);
for (const msg of data.messages) {
if (!msg.key.fromMe && msg.message?.conversation) {
// Reply using sock from event
await sock.sendMessage(msg.key.remoteJid, {
text: `Auto reply from ${shardId}: ${msg.message.conversation}`
});
}
}
});
// Message update events
manager.on("messages.update", ({ shardId, data }) => {
console.log(`π Message updates from ${shardId}:`, data);
});
// Message delete events
manager.on("messages.delete", ({ shardId, data }) => {
console.log(`ποΈ Message deleted in ${shardId}:`, data);
});| Property | Type | Description |
|---|---|---|
| shardId | string |
ID of shard sending event |
| sock | WASocket |
Baileys socket instance for reply/interaction |
| data | object |
Original Baileys event data |
Handle errors with comprehensive error codes:
manager.on("shard.error", ({ shardId, error }) => {
console.error(`β Error on ${shardId}:`, error.message);
// Handle based on error code
switch (error.code) {
case "CREATE_FAILED":
console.log("Failed to create shard, check session directory");
break;
case "RECREATE_FAILED":
console.log("Failed to recreate shard, implementing retry...");
setTimeout(() => {
manager.recreateShard({ id: shardId, clearSession: true });
}, 10000);
break;
case "CREDS_SAVE_FAILED":
console.log("Failed to save credentials, check file permissions");
break;
case "PAIRING_FAILED":
console.log("Pairing failed, check phone number format");
break;
case "SHARD_NOT_FOUND":
console.log("Shard not found, creating new one...");
manager.createShard({ id: shardId });
break;
case "CONNECT_FAILED":
case "STOP_FAILED":
case "LOAD_FAILED":
default:
console.log("General error, check logs for details");
}
});Available Error Codes:
CREATE_FAILED- Failed when creating shardRECREATE_FAILED- Failed when recreating shardCREDS_SAVE_FAILED- Failed to save credentialsPAIRING_FAILED- Failed pairing processSHARD_NOT_FOUND- Shard not foundCONNECT_FAILED- Failed to connect to shardSTOP_FAILED- Failed to stop shardLOAD_FAILED- Failed to load sessionsNO_SESSIONS- No sessions found
All other Baileys events are also forwarded with the same format:
// Chat events
manager.on("chats.upsert", ({ shardId, data }) => {
console.log(`New chats in ${shardId}:`, data.length);
});
manager.on("chats.update", ({ shardId, data }) => {
console.log(`Chat updates in ${shardId}:`, data.length);
});
// Contact events
manager.on("contacts.upsert", ({ shardId, data }) => {
console.log(`New contacts in ${shardId}:`, data.length);
});
// Group events
manager.on("groups.upsert", ({ shardId, data }) => {
console.log(`New groups in ${shardId}:`, data.length);
});
manager.on("group-participants.update", ({ shardId, data }) => {
console.log(`Group participant update in ${shardId}:`, data);
});
// Presence events
manager.on("presence.update", ({ shardId, data }) => {
console.log(`Presence update in ${shardId}:`, data);
});
// Call events
manager.on("call", ({ shardId, data }) => {
console.log(`Incoming call in ${shardId}:`, data);
});Complete Event List:
messages.upsert- New messages receivedmessages.update- Message status updatesmessages.delete- Messages deletedmessages.reaction- Message reactionsmessage-receipt.update- Read receiptsmessaging-history.set- Message history loadedchats.upsert- New chatschats.update- Chat updateschats.delete- Chats deletedcontacts.upsert- New contactscontacts.update- Contact updatesgroups.upsert- New groupsgroups.update- Group updatesgroup-participants.update- Group member changespresence.update- Online/offline statuscall- Incoming callsblocklist.set- Blocklist loadedblocklist.update- Blocklist updatescreds.update- Credentials updated
Feel free to open an issue, I hope this documentation can help you maximally and make it easier for you to use this package.
If you would like to contribute to this package, I would really appreciate it. You can see the contribution guidelines here to contribute in the best way possible.