This episode introduces Socket.IO: event-based messaging, automatic reconnection, fallback to long polling, rooms and namespaces, and a comparison with native WebSocket to decide when to use which.

After building a pure ws server in episode 5, you might ask: why bother building broadcast and reconnection by hand? The answer is Socket.IO.
Socket.IO is a library that layers WebSocket with convenience: event-based messaging, automatic reconnection, fallback when WebSocket is blocked, rooms, and namespaces. In this episode you will see why Socket.IO is so popular — and also when it is better to stick with pure ws.
Socket.IO is not a replacement for WebSocket, but an enhancement:
chat:pesan, not raw strings.npm install socket.io socket.io-clientnpm install socket.io socket.io-client installs two packages: the server for Node.js and the client for the browser.
Socket.IO uses its own protocol that runs on top of WebSocket or polling. As a result, Socket.IO clients cannot talk to a pure ws server — and vice versa. For applications that need pure protocol interoperability, ws remains the primary choice.
const { Server } = require("socket.io");
const http = require("http");
const server = http.createServer();
const io = new Server(server);
io.on("connection", (socket) => {
console.log("klien terhubung:", socket.id);
socket.on("chat:kirim", (pesan) => {
io.emit("chat:terima", pesan);
});
});
server.listen(8080);new Server(server) attaches Socket.IO to the HTTP server. The connection event gives you a socket object with a unique socket.id per client. io.emit broadcasts to all clients.
Communication works in two directions:
socket.emit("pesan", "dari server");
socket.on("event-klien", (data) => {
console.log("klien mengirim:", data);
});socket.emit sends to a single client, while io.emit sends to everyone. Episode 9 adds the to(room) and except(socketId) variants.
Socket.IO supports middleware that runs before events are processed:
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (token === "rahasia") {
next();
} else {
next(new Error("unauthorized"));
}
});io.use((socket, next) => {...}) lets you reject a connection before the client gets in. This is the entrance to authentication, which we will dissect fully in episode 8.
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on("chat:terima", (pesan) => {
console.log("diterima:", pesan);
});
socket.emit("chat:kirim", "halo semua");
</script>const socket = io() connects the client to the same server automatically. socket.on and socket.emit are the mirror image of the server side.
The client can be configured with various options:
const socket = io("https://server.example.com", {
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
reconnectionAttempts: Infinity,
timeout: 10000,
});The options above enable reconnection with backoff. We will cover these configuration details more deeply in episode 12.
Choose Socket.IO when:
Choose ws when:
Warning
Socket.IO wraps messages in its own protocol. If your application must talk directly to IoT devices that only understand pure WebSocket, Socket.IO will not fit without an additional layer.
Some features you will use frequently throughout the series:
socket.emit("tanya", data, (jawaban) => {...}) enables a reply callback.io.emit to everyone, socket.broadcast.emit to everyone except the sender.Episode 6 introduced Socket.IO as a convenience layer on top of WebSocket: event-based messaging, automatic reconnection, fallback, middleware, and connection options. You can now also decide when to use Socket.IO and when to stay loyal to pure ws.
Key takeaways:
In the next episode we combine all the capabilities: building your first real-time application — a simple chat with a server, UI, join and leave notifications, an online user list, and debugging via DevTools.