Building a Real-Time Chat App with Express and Socket.io: A Beginner's Guide
Tags: webdev, typescript, node, socketio
Published: 2023-09-19 14:15:47

**Introduction**

Imagine this: You're part of a dynamic team, scattered across different parts of the globe, working tirelessly on a collaborative project. Your colleague in Tokyo has an innovative idea, your partner in New York has a crucial update, and you're in London with a question. Traditional email exchanges won't cut it, and you can't wait for time zones to align. What you need is instant, real-time communication.

This is where real-time chat applications come into play, offering a lifeline for seamless, instant communication that transcends geographical boundaries. In today's fast-paced digital landscape, real-time chat is more than a convenience; it's a necessity.

In this beginner-friendly guide, we'll demystify the art of building a real-time chat application from scratch. No prior experience with Socket.io or real-time apps is needed—just a willingness to learn and experiment. By the end of this journey, you'll not only grasp the inner workings of real-time chat but also have your very own basic chat application powered by Express and Socket.io. Let's embark on this adventure together and unveil the world of real-time web development!

**Setting Up the Project**

Now let's jump into setting up your real-time chat project step by step:

**1. Create a New Node.js Project**:
Start by creating a new Node.js project directory. Open your terminal and navigate to the folder where you want to create your project. Then, run the following command to initialize a new Node.js project:
```bash
npm init -y
```
This command creates a `package.json` file, which will keep track of your project's dependencies and settings.

**2. Install Express and Socket.io**:
Express is a minimalist web framework for Node.js, and Socket.io is a library for enabling real-time communication. Install these dependencies by running the following commands in your project directory:
```bash
npm install express socket.io
```
This will download and install the required packages and add them to your `package.json` file.

**3. Project Directory Structure**:
Your project directory should now have a structure that looks something like this:
```
our-chat-app/
├── node_modules/        # Dependencies installed via npm
├── package.json         # Project configuration
├── server.js            # Main server file (you'll create this)
└── ...
```
- `node_modules`: This folder contains the installed dependencies.
- `package.json`: This file stores your project's metadata and lists its dependencies.
- `server.ts`: This will be your main server file, where you'll build and run the Express and Socket.io server.

Okay, in the next sections, we'll work on the process of building the server, creating the real-time communication layer, and crafting the chat interface. Let's get started!

**Creating the Server with Express**

Now that you have your project initialized and dependencies installed, let's dive into creating the server using Express:

**1. Set Up a Basic Server with Express**:
Begin by importing Express and creating an instance of it:
```javascript
const express = require('express');
const app = express();
```

**2. Listen on a Specific Port**:
To start your server and make it listen on a specific port (e.g., 8000), add the following code:
```javascript
const port = 8000;

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
```
app.listen() starts your Express server and specifies the port it should listen on. The console.log line is optional but helps you confirm that your server is running.

**3. Set Up a Basic Route**:
```javascript
app.get("/", (req, res) => {
    res.send("Hello World");
});
```

Now that you've set up your basic Express server, let's run it.

Open your terminal, navigate to your project directory, and run the server by executing the following command:
```bash
node server.js
```
You should see a message indicating that the server is running on the specified port (e.g., "Server is running on port 8000"). This confirms that your server is up and running.


**Create the HTML File**

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Real Time Chat With Socket.io</title>
    <!-- CSS styles go here -->
  </head>

  <body>
    <div class="container">
      <div class="chat-box">
        <ul class="message-list" id="messages"></ul>
        <form id="form" action="">
          <input
            class="message-input"
            id="input"
            autocomplete="off"
            placeholder="Type your message..."
          />
          <button class="send-button">Send</button>
        </form>
      </div>
    </div>

    <!-- JavaScript code goes here -->
  </body>
</html>
```

**Serve the HTML File Using Express**

To serve this HTML file when users access the root URL ("/"), update the root URL method in your `server.js` file like this:

```javascript
// Serve the HTML file
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});
```

This code uses `res.sendFile()` to send the HTML file when users access the root URL ("/"). The `__dirname` variable represents the current directory.

With the server running and your HTML file being served, you've laid the foundation for building your real-time chat application. In the upcoming sections, we'll integrate Socket.io to enable real-time communication, allowing users to exchange messages instantly.

**Creating the Real-Time Communication Layer with Socket.io**

Now, let's delve into the integration of Socket.io for real-time communication:

**Set Up a Socket.io Server**

To set up a Socket.io server, first, import the Socket.io library and attach it to your Express server:

```javascript
const http = require('http').createServer(app);
const io = require('socket.io')(http);
```

- `http` is created by passing your Express application (`app`) to `http.createServer()`.
- `io` is the Socket.io server instance created by passing `http`.

**Set Up Socket.io Events**

In a real-time chat application, events are crucial for handling actions like new connections, sending and receiving messages, and user disconnections.

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

  // Handle chat messages
  socket.on("chat message", (msg) => {
    console.log("Message: " + msg);
    io.emit("chat message", msg); // Broadcast the message to all connected users
  });

  // Handle disconnections
  socket.on("disconnect", () => {
    console.log("User disconnected");
  });
});
```

- `io.on("connection")` listens for new socket connections and executes a callback when a new user connects.
- The `socket.on("chat message")` event handles incoming chat messages and broadcasts them to all connected clients using `io.emit()`.
- The `socket.on("disconnect")` event logs when a user disconnects.

**Building the Frontend**

Now that we've set up the server and real-time communication with Socket.io, let's dive into building the frontend of our chat application.

**Include the Socket.io Client-side Library**

To enable real-time communication on the client side, include the Socket.io client library in your HTML. Add the following script tag before the closing `</body>` tag in your HTML file:

```html
<script src="/socket.io/socket.io.js"></script>
```

This script tag loads the Socket.io client library.

**Handling User Interactions**

JavaScript is the heart of your chat application, handling user interactions and real-time messaging. Here's an overview of the JavaScript code that handles these interactions:

```javascript
var socket = io(); // Initialize a Socket.io connection

var messages = document.getElementById("messages");
var form = document.getElementById("form");
var input = document.getElementById("input");

// Handle submitting messages
form.addEventListener("submit", function (e) {
  e.preventDefault();
  if (input.value) {
    socket.emit("chat message", input.value); // Send the message to the server
    input.value = "";
  }
});

// Listen for chat messages broadcasted from the server
socket.on("chat message", function (msg) {
  var item = document.createElement("li");
  item.textContent = msg;
  messages.appendChild(item);

  // Scroll to the latest message
  messages.scrollTop = messages.scrollHeight;
});
```

Let's break down the main functions in the JavaScript code:

- **Initializing Socket.io Connection** (`var socket = io();`):
  - This line initializes a connection to the Socket.io server. It sets up a communication channel between the client (browser) and the server, enabling real-time messaging.

- **Handling Message Submission** (Event Listener):
  - The code listens for the form's submit event (`form.addEventListener("submit", function (e) {...}`).
  - When a user submits a message by clicking "Send," the function is triggered.
  - It prevents the default form submission action (`e.preventDefault();`) to avoid page refresh.
  - If the input field is not empty (`if (input.value)`), it emits a "chat message" event to the server with the user's message (`socket.emit("chat message", input.value);`

).
  - After sending the message, it clears the input field (`input.value = "";`).

- **Listening for Incoming Messages** (Socket.io Event):
  - The code listens for the "chat message" event sent by the server (`socket.on("chat message", function (msg) {...}`).
  - When a message is received from the server, it creates a new list item (`var item = document.createElement("li");`) to display the message.
  - It sets the text content of the list item to the received message (`item.textContent = msg;`).
  - The list item is appended to the message list (`messages.appendChild(item);`), displaying the message in the chat interface.
  - Additionally, it ensures that the chat interface scrolls to display the latest message at the bottom (`messages.scrollTop = messages.scrollHeight;`).

**Conclusion**

In this blog post, we've embarked on the journey of building a real-time chat application using Express and Socket.io. Here are the key takeaways:

- Real-time communication is vital in modern web development, enabling instant interactions between users.

Share your thoughts, questions, or feedback in the comments section below.

Spread the knowledge by sharing this post on social media.

**Acknowledgments**

Thanks to the open-source Socket.io library for powering our real-time chat. [Socket.io](https://socket.io/) and this article by Socket.io are very helpful: [Socket.io article](https://socket.io/docs/v4/tutorial/introduction).

**Author Bio**

I'm passionate about web development and creating engaging, real-time experiences. Connect with me on [Twitter](https://twitter.com/ishaksebsib) or [LinkedIn](https://www.linkedin.com/in/ishaksebsib).

**References**

- [Socket.io Documentation](https://socket.io/docs/v4/tutorial/introduction)
- [Express.js Documentation](https://expressjs.com/)