Manasa Jayasri

Blog

Building Real-Time Features with Node.js and Socket.IO

Build interactive, live experiences without wrestling with low-level networking details.

• Manasa Jayasri




Before the internet, communication looked like this: you’d write a letter, drop it in the mailbox, and wait days for a reply. Early websites weren’t that different. You sent a request, waited for the server, and refreshed to see what changed. The web used to be that simple. But today, users expect instant updates. Be it chat messages that appear in real-time, live notifications, dashboards that update without hitting refresh.

Then came AJAX in the early 2000s, and suddenly pages could fetch bits of data without reloading. That opened the door for features like live search suggestions and background updates.

But as users demanded more live chat, multiplayer games, collaborative tools, developers started to hack together “real-time” with long polling and other tricks. These worked, but they were clunky, unreliable, and hard to scale.

Enter WebSockets: a protocol that let browsers and servers keep a persistent two-way connection. Real-time communication was finally possible. And on top of WebSockets, libraries like Socket.IO emerged to smooth over the rough edges, handling fallbacks, reconnections, and cross-browser quirks so you could just focus on building.

Wireframe placeholder

What is Socket.IO?

Socket.IO is a JavaScript library that enables real-time, bidirectional communication between clients (usually browsers) and servers. It’s built on top of WebSockets but adds important features like:

With Node.js on the backend and Socket.IO handling connections, you can build highly interactive applications with just a few lines of code.

Setting Up the Project

First, let’s scaffold a Node.js app with Express and Socket.IO.

Wireframe placeholder

server.js:


const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('A user connected');

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

server.listen(3000, () => {
  console.log('http://localhost:3000');
});

index.html:


<ul id="messages"></ul>
<form id="form">
  <input id="input" autocomplete="off" /><button>Send</button>
</form>

<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io();
  const form = document.getElementById('form');
  const input = document.getElementById('input');
  const messages = document.getElementById('messages');

  form.addEventListener('submit', (e) => {
    e.preventDefault();
    if (input.value) {
      socket.emit('chat message', input.value);
      input.value = '';
    }
  });

  socket.on('chat message', (msg) => {
    const li = document.createElement('li');
    li.textContent = msg;
    messages.appendChild(li);
  });
</script>


Broadcast Messages

Alright, let’s make every message visible to all connected clients

Now update the server, replace the original io.on('connection', …) block (where you only logged A user connected) with this new one that listens for chat messages and broadcasts them to everyone:


  io.on('connection', (socket) => {
  console.log('A user connected');

  socket.on('chat message', (msg) => {
    // Broadcast to ALL connected clients
    io.emit('chat message', msg);
  });

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

        

Here's a demo of what we just built:

A quick demo of the real-time chat running locally.

Run the server with node server.js, open two browser tabs, and type. Each message appears instantly in both tabs. That’s broadcasting in action.

Moving Into Rooms

Broadcasting to everyone is fun, but real apps use rooms. Taking this up a notch, let's create a separate channels where only some users see messages. Think #general, #random, or private groups.

How It Works Behind the Scenes

Click here for source code.

Demo of rooms for targeted communication

Although we just built a chat with rooms, Socket.IO is much more versatile. Any situation where you need instant, event-driven updates is a good fit. Some examples:

  • Applications: From group messaging (Slack, WhatsApp Web, Discord) to 1-to-1 private chats, Socket.IO makes messages appear instantly without reloading.
  • Live Notifications: Think of social media alerts: a new like, a comment, or someone joining your meeting. With Socket.IO, the server pushes updates as they happen.
  • Collaboration Tools: Apps like Google Docs rely on real-time editing. Multiple people typing in the same document? That’s a combination of rooms (each document is a room) and instant event syncing.
  • Dashboards: Imagine a stock market ticker, a live sports scoreboard, or IoT device data streaming in. Socket.IO lets you push updates straight to dashboards the moment they change.
  • Online Games: Multiplayer games need fast, synchronized communication. Socket.IO helps players see each other’s moves in real time, often with each game lobby as its own room.
  • Support Systems: Real-time chat between users and support agents, with rooms separating different conversations.
  • We started with a simple broadcast system, then introduced rooms to create multiple channels. This is the foundation of nearly every interactive app you use today.

    What makes Socket.IO powerful is not just real-time messaging, but the flexibility: you can group users, separate features, and scale to handle thousands of concurrent connections.