WebSocket libraries for Node.js: from a simple chat to high-load real-time systems
WebSocket is a protocol that provides a persistent two-way connection between a client and a server. Unlike HTTP, where the request-response is initiated by the client, WebSocket allows the server to send data at any time. For Node.js, which is famous for its asynchrony and event-driven architecture, WebSocket has become a natural choice for creating chats, online games, trading terminals and streaming data.
In this article, we will look at three main libraries: ws (lightweight and fast), Socket.IO (convenient with fallback mechanisms) and uWebSockets.js (record performance). You will learn which one to choose for your task and how to write a simple chat on each of them.
1. ws library — minimalism and speed
ws is the most popular WebSocket library for Node.js. It implements the pure RFC 6455 protocol without unnecessary add-ons. Main advantages:
- Maximum performance — up to 200,000+ messages/sec on a single core.
- Zero dependencies — only pure JavaScript.
- Full control over the connection: handshake, frames, ping/pong.
- Support for Node.js Buffer and Streams for binary data.
Disadvantages: no automatic reconnection, no rooms, no fallback to HTTP long-polling. Everything needs to be implemented manually or through additional packages.
Example: simple echo server on ws
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (ws) => { console.log('Client connected');
ws.on('message', (message) => { console.log('Received:', message.toString()); // Send back (echo) ws.send(`Echo: ${message}`); });
ws.on('close', () => { console.log('Client disconnected'); });
// Send greeting on connection ws.send('Welcome to the WebSocket server!');});
console.log('Server running on ws://localhost:8080');When to choose ws? — for microservices, high-load games (where every frame matters), for embedding into your own HTTP server (via server.on('upgrade')).
2. Socket.IO — convenience and reliability for production
Socket.IO is not just WebSocket, but a whole real-time platform. It uses WebSocket as the main transport, but automatically switches to HTTP long-polling if WebSocket is not supported (proxies, firewalls, old browsers).
- Rooms — grouping clients for broadcast messages.
- Namespaces — logical separation of the application (e.g., /chat and /game).
- Automatic reconnection with exponential backoff.
- Event support — you work with events, not raw messages.
- Built-in serialization — passing JSON objects without manual parsing.
Disadvantages: protocol overhead (additional packets with metadata), more dependencies, slightly slower than pure ws.
Example: chat with rooms on Socket.IO (server)
const http = require('http');const { Server } = require('socket.io');
const server = http.createServer();const io = new Server(server, { cors: { origin: '*' } // for development});
io.on('connection', (socket) => { console.log('New client:', socket.id);
// Join a room socket.on('join_room', (roomName) => { socket.join(roomName); socket.emit('message', `You joined room ${roomName}`); socket.to(roomName).emit('message', `User ${socket.id} entered the room`); });
// Send message to ro