Express.js - How to Create a Real-Time Chat App Using Socket.IO in NodeJS
A real-time chat application can be efficiently built using Express.js for backend routing and Socket.IO for enabling real-time, bidirectional communication between clients and the server.
What is Socket.IO ?
Socket.IO is a JavaScript library that enables real-time, bidirectional communication between the client and server. It allows you to send and receive messages instantly, without needing to refresh the page — perfect for chat apps, live notifications, etc.
1. Getting started:
1.1 Create and Navigate into a New Directory
mkdir my-app cd my-app
1.2 Initialize a New Node.js Project
npm init -y
The -y flag automatically fills in default values (you can change them later)
1.3 Install Required Packages
npm install express socket.io
2. Creating the Server (Socket.IO + Express):
Create a file named index.js in your project folder (my-app/) and paste this code:
index.js
const express = require("express");
const http = require("http");
const { Server } = require("socket.io");
const app = express();
const server = http.createServer(app);
//Initialize Socket.IO server with CORS enabled
const io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
credentials: true,
},
});
// Local store for chat messages
let chatMessages = [];
// Create a custom namespace for chat
const chatNamespace = io.of("/chat");
chatNamespace.on("connection", (socket) => {
console.log("User connected to /chat namespace");
// Send all previous messages to the newly connected client
socket.emit("messages", chatMessages);
// Listen for incoming chat messages from the client
socket.on("chat", (msg) => {
// Add the new message to the chat history array
chatMessages.push(msg);
// Broadcast the new message to all connected clients
chatNamespace.emit("message", msg);
});
//Log when the user disconnects
socket.on("disconnect", () => {
console.log("User disconnected from /chat");
});
});
server.listen(3000, () => {
console.log("Server running at http://localhost:3000");
});
3. How to Run:
In your terminal (inside the my-app/ directory), run:
node index.js
4. Frontend (Client):
You can choose react or plain js as the frontend.In this example we choose plain js as the frontend. Create index.html and place the following code in it.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Chat App</title> <style> body { height: 100vh; display: flex; justify-content: center; align-items: center; } #loginArea { width: 500px; display: flex; } #loginArea input[type='text'] { flex: 1; padding: 10px; } .hide { display: none !important; } #chatArea { border: 1px solid rgb(221, 220, 220); padding: 10px; } #chatList { list-style-type: none; width: 500px; padding: 0; } #chatList li { margin-bottom: 5px; border-bottom: 1px solid rgb(221, 220, 220); padding: 10px; } #chatBox { width: 100%; display: flex; } #chatBox input[type='text'] { flex: 1; padding: 10px; } </style> </head> <body> <!-- Login Area --> <div id="loginArea" class="box"> <input type="text" placeholder="Enter your name to contine chat..." id="user_name"> <input type="button" value="Start" onclick="login()"> </div> <!-- Chat Area --> <div id="chatArea" class="hide"> <!-- Show all chats --> <ul id="chatList"> <li></li> </ul> <!-- Chat Box --> <div id="chatBox"> <input type="text" id="messageInput" placeholder="Message here..."> <input type="button" value="Send" onclick="sendMessage()"> </div> </div> <!-- Socket.IO Script --> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.8.1/socket.io.min.js"></script> <script> const chatList = document.querySelector("#chatList"); const messageInput = document.querySelector("#messageInput"); const user_name = document.querySelector("#user_name"); const loginArea = document.querySelector("#loginArea"); const chatArea = document.querySelector("#chatArea"); let chatUserName = ""; // Login Handling - Hide the login box after entering the name. function login() { if (user_name.value != "") { chatUserName = user_name.value; //Hide Login Area loginArea.classList.add("hide"); //Show Chat Area chatArea.classList.remove("hide"); } } //Connect to Socket.IO const socket = io('http://localhost:3000/chat'); // Receive All Previous Messages socket.on("messages", (messages) => { chatList.innerHTML = ""; messages.forEach(message => { const li = document.createElement("li"); li.innerText = `${message.user} : ${message.message}`; //Aligns to the right if the message was sent by you if (message.user == chatUserName) { li.style.textAlign = 'right'; } chatList.appendChild(li); }); }); // Receive a Single New Message & Adds the new message to the list. socket.on("message", (message) => { const li = document.createElement("li"); li.innerText = `${message.user} : ${message.message}`; if (message.user == chatUserName) { li.style.textAlign = 'right'; } chatList.appendChild(li); }); //Send a Message function sendMessage() { const msgObj = { user: chatUserName, message: messageInput.value } //Sends an event to the server socket.emit("chat", msgObj); //Clear message input messageInput.value = ""; } </script> </body> </html>
5. Run Client:
Run index.html via any local web server such as Apache, Live Server, or Node.
Output 1 - Login Screen

Output 2 - Chat Screen
