---
title: Build a Real‑Time Chat App with WebSockets and Node.js
siteUrl: https://logzly.com/codecraft
author: codecraft (CodeCraft)
date: 2026-06-23T01:05:39.334319
tags: [coding, nodejs, websockets]
url: https://logzly.com/codecraft/build-a-realtime-chat-app-with-websockets-and-node-js
---


Ever wanted a simple chat window that works instantly, without refreshing the page?  Almost every web app needs some kind of live update – think notifications, live scores, or a quick team chat.  This post on **CodeCraft** shows you how to get a real‑time chat up and running using WebSockets and Node.js.  No fancy frameworks, just plain JavaScript and a few npm packages.  By the end you’ll have a working app you can run on your laptop and share with a friend.

## Why WebSockets?

When you open a normal web page, the browser asks the server for data, gets a response, and then it’s done.  If you need new data later you have to ask again – that’s called polling.  Polling works, but it’s wasteful: the server gets a lot of empty requests, and the user sees a tiny delay.

WebSockets solve that.  They open a single, two‑way connection that stays open.  The server can push messages to the client instantly, and the client can send messages back just as fast.  Think of it like a telephone line instead of sending letters back and forth.

## What You’ll Need

- **Node.js** (v18 or newer) – the runtime that will host our server.
- **npm** – comes with Node, used to install packages.
- A text editor – VS Code works fine.
- A terminal – any will do.

We’ll use two npm packages:

1. **express** – a tiny web server to serve our HTML page.
2. **ws** – a lightweight WebSocket library for Node.

Both are tiny, well‑maintained, and perfect for a learning project.

## Step 1: Set Up the Project Folder

Open a terminal and run:

```bash
mkdir codecraft-chat
cd codecraft-chat
npm init -y
npm install express ws
```

`npm init -y` creates a default `package.json`.  The `express` and `ws` packages are added to the dependencies list.

## Step 2: Write the Server (server.js)

Create a file called `server.js` and paste the following code:

```js
// server.js
const express = require('express')
const http = require('http')
const WebSocket = require('ws')

// Create an Express app
const app = express()
app.use(express.static('public')) // serve static files from /public

// Create an HTTP server and attach Express
const server = http.createServer(app)

// Create a WebSocket server on top of the HTTP server
const wss = new WebSocket.Server({ server })

// Broadcast a message to all connected clients
function broadcast(data, wsSender) {
  wss.clients.forEach(client => {
    // Only send to clients that are still open and not the sender
    if (client !== wsSender && client.readyState === WebSocket.OPEN) {
      client.send(data)
    }
  })
}

// When a new client connects
wss.on('connection', ws => {
  console.log('New client connected')

  // When this client sends a message
  ws.on('message', message => {
    console.log('Received:', message)
    // Send the message to everyone else
    broadcast(message, ws)
  })

  // When the client disconnects
  ws.on('close', () => {
    console.log('Client left')
  })
})

// Start the server
const PORT = process.env.PORT || 3000
server.listen(PORT, () => {
  console.log(`CodeCraft server listening on http://localhost:${PORT}`)
})
```

A quick walk‑through:

- We serve static files from a folder called `public`.  That’s where our HTML, CSS, and client‑side JavaScript will live.
- The `ws` library creates a WebSocket server (`wss`) that shares the same port as the HTTP server.
- When a client sends a message, we call `broadcast` to forward it to every other client.  This keeps the chat in sync.

## Step 3: Build the Front End

Create a folder named `public` next to `server.js`.  Inside `public` add three files: `index.html`, `style.css`, and `chat.js`.

### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>CodeCraft Real‑Time Chat</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>CodeCraft Chat</h1>
  <div id="chat-box"></div>
  <form id="chat-form">
    <input id="msg-input" type="text" placeholder="Type a message…" autocomplete="off" required />
    <button type="submit">Send</button>
  </form>

  <script src="chat.js"></script>
</body>
</html>
```

A tiny page: a heading, a box to show messages, and a form to type new ones.

### style.css

```css
body {
  font-family: Arial, sans-serif;
  margin: 2rem;
  background: #f9f9f9;
}
h1 {
  color: #333;
}
#chat-box {
  border: 1px solid #ccc;
  height: 300px;
  overflow-y: auto;
  padding: 0.5rem;
  background: #fff;
}
.message {
  margin: 0.3rem 0;
}
.message.me {
  text-align: right;
  color: #0066cc;
}
form {
  margin-top: 1rem;
  display: flex;
}
input {
  flex: 1;
  padding: 0.5rem;
}
button {
  padding: 0.5rem 1rem;
}
```

Nothing fancy – just enough to make the chat readable.

### chat.js

```js
// chat.js
const ws = new WebSocket(`ws://${location.host}`)

const chatBox = document.getElementById('chat-box')
const form = document.getElementById('chat-form')
const input = document.getElementById('msg-input')

// Show a new message in the chat box
function addMessage(text, isMe) {
  const msgEl = document.createElement('div')
  msgEl.className = 'message' + (isMe ? ' me' : '')
  msgEl.textContent = text
  chatBox.appendChild(msgEl)
  chatBox.scrollTop = chatBox.scrollHeight
}

// When the server sends a message
ws.addEventListener('message', event => {
  addMessage(event.data, false)
})

// When the form is submitted
form.addEventListener('submit', e => {
  e.preventDefault()
  const text = input.value.trim()
  if (!text) return

  // Show our own message instantly
  addMessage(text, true)

  // Send it to the server
  ws.send(text)

  // Clear the input
  input.value = ''
})
```

Key points:

- We open a WebSocket connection to the same host (`ws://${location.host}`) – that works whether you run locally or deploy later.
- Incoming messages are displayed as “other” messages.  Our own messages get a different style (`me` class) so they line up on the right.
- The form’s default submit behavior is prevented; we send the text over the socket instead.

## Step 4: Run It

Back in the terminal, start the server:

```bash
node server.js
```

You should see:

```
CodeCraft server listening on http://localhost:3000
```

Open a browser and go to `http://localhost:3000`.  You’ll see the **CodeCraft** chat page.  Open another tab or another browser on the same address, type a message in one window, and watch it appear instantly in the other.  That’s real‑time!

## A Few Tips from CodeCraft

- **Error handling** – In a production app you’d want to catch errors on the WebSocket (`ws.onerror`) and maybe try to reconnect if the connection drops.
- **User names** – Right now every message is just plain text.  You can prepend a name before sending, or send a JSON object like `{user:"Alice",msg:"Hi"}` and render it nicely.
- **Security** – When you move to HTTPS you’ll need `wss://` (WebSocket Secure) instead of `ws://`.  The `ws` library works the same; just pass the HTTPS server to it.
- **Scaling** – A single Node process works for a few users, but for many concurrent connections you’d look at a message broker (Redis, RabbitMQ) or a cloud service that handles WebSocket scaling.

If you want to stretch your skills beyond this chat demo, try making your **[first open‑source contribution](/codecraft/your-first-open-source-contribution-fork-fix-and-submit-a-pull-request-to-a-popular-react-library)** to a JavaScript library.

## Wrap‑Up

That’s it – a complete, working real‑time chat built with just Node.js, Express, and the `ws` library.  The whole thing is under 100 lines of code, and you can see exactly how data moves from one browser to another.  On **CodeCraft** I love showing how a small piece of code can do something that feels “big”.  Play around: add emojis, store chat history in a file, or turn it into a simple support widget for a personal site.

When you're ready to give back, learn how to **[contribute to a popular open‑source project](/codecraft/contribute-to-a-popular-opensource-project-a-practical-stepbystep-guide-for-developers)** and grow your developer profile.

Happy coding, and enjoy the instant chat vibes!