Building a Real-Time Chat Application with TypeScript and WebSockets

Learn how to create a simple real-time chat application using TypeScript and WebSockets. This beginner-friendly tutorial guides you through setting up a WebSocket server and client for instant messaging.

Real-time communication is essential for many modern applications, including chat apps, online gaming, and live notifications. WebSockets provide a full-duplex communication channel over a single TCP connection, enabling real-time data exchange between clients and servers. In this tutorial, you will learn how to build a simple chat application using TypeScript and WebSockets.

We will create a WebSocket server using the popular `ws` library and a browser client that connects to it. The server will broadcast messages from any one client to all connected clients, enabling real-time group chat.

Let's start by setting up our project. You'll need Node.js installed on your computer.

First, create a new folder for your project and initialize it with npm:

typescript
mkdir realtime-chat && cd realtime-chat
npm init -y

Next, install TypeScript and the `ws` WebSocket library:

typescript
npm install ws
npm install --save-dev typescript @types/ws

Create a `tsconfig.json` file to configure TypeScript:

typescript
{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "outDir": "dist",
    "strict": true
  },
  "include": ["src"]
}

Now, create the `src` folder and then the `server.ts` file inside it. This file will contain WebSocket server code:

typescript
import WebSocket, { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', (ws: WebSocket) => {
  console.log('New client connected');

  ws.on('message', (message: string) => {
    console.log(`Received: ${message}`);
    // Broadcast the message to all clients
    wss.clients.forEach(client => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });

  ws.on('close', () => {
    console.log('Client disconnected');
  });
});

console.log('WebSocket server is running on ws://localhost:8080');

This sets up a WebSocket server that listens on port 8080. When a client sends a message, the server broadcasts it to all other clients.

Next, let's create a simple client to connect to our server. Create an `index.html` file in the root folder with the following content:

typescript
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Real-Time Chat</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    #messages { border: 1px solid #ccc; height: 300px; overflow-y: scroll; padding: 10px; }
    input { width: 80%; padding: 10px; }
    button { padding: 10px; }
  </style>
</head>
<body>
  <h1>Real-Time Chat</h1>
  <div id="messages"></div>
  <input id="messageInput" type="text" placeholder="Type your message here..." />
  <button id="sendBtn">Send</button>

  <script>
    const ws = new WebSocket('ws://localhost:8080');
    const messagesDiv = document.getElementById('messages');
    const input = document.getElementById('messageInput');
    const sendBtn = document.getElementById('sendBtn');

    ws.onopen = () => {
      console.log('Connected to server');
    };

    ws.onmessage = (event) => {
      const message = document.createElement('div');
      message.textContent = event.data;
      messagesDiv.appendChild(message);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    };

    sendBtn.onclick = () => {
      if (input.value) {
        ws.send(input.value);
        const message = document.createElement('div');
        message.textContent = `You: ${input.value}`;
        message.style.fontWeight = 'bold';
        messagesDiv.appendChild(message);
        messagesDiv.scrollTop = messagesDiv.scrollHeight;
        input.value = '';
      }
    };

    input.addEventListener('keyup', (event) => {
      if (event.key === 'Enter') {
        sendBtn.click();
      }
    });
  </script>
</body>
</html>

This client connects to the WebSocket server, listens for incoming messages, and displays them in the `#messages` div. You can type a message and send it by clicking the button or pressing Enter.

To run your server, compile the TypeScript file and then start it with Node.js:

typescript
npx tsc
node dist/server.js

Open the `index.html` file in two different browser windows or tabs. Sending a message in one should instantly appear in the other, demonstrating real-time communication.

Congratulations! You have built a simple, real-time chat application with TypeScript and WebSockets. This foundation can be expanded with features like user names, message history, and private chats.

Happy coding!