← Back to all tutorials

Creating an Express App

Set up a Node.js project with Express and serve an HTML page — the foundation for adding Socket.io in the next episode.

Creating an Express App

Before we add WebSockets, we need a web server to serve our HTML page and handle connections. In this episode you will create a basic Express application from scratch — this will be the foundation for our Socket.io integration.

Step 1: Initialize the Project

mkdir websocket-chat
cd websocket-chat
npm init -y

This creates a new directory and initializes a package.json file with default settings. The -y flag accepts all defaults automatically.

Step 2: Install Express

npm install express

Express is a minimal, flexible web framework for Node.js. It provides routing, middleware support, and easy HTTP server creation.

Step 3: Create the Server File

Create a file called index.js in the project root:

const express = require('express');
const app = express();

// Serve static files from the 'public' folder
app.use(express.static('public'));

// Start the server
const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

Understanding the Code

LineWhat It Does
require('express')Imports the Express library
express()Creates an Express application instance
express.static('public')Serves files from the public folder (HTML, CSS, JS)
app.listen(PORT)Starts the server on the specified port

Step 4: Create the HTML Page

Create a public folder and add an index.html file inside it:

mkdir public

Then create public/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket Chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: Arial, sans-serif;
            background: #1a1a2e;
            color: #eee;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        .chat-container {
            width: 400px;
            background: #16213e;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 10px 40px rgba(0,0,0,0.3);
        }
        .chat-header {
            background: #0f3460;
            padding: 16px 20px;
            font-size: 18px;
            font-weight: bold;
            text-align: center;
        }
        #chat-messages {
            height: 300px;
            overflow-y: auto;
            padding: 16px;
        }
        .chat-input-area {
            display: flex;
            padding: 12px;
            background: #0f3460;
        }
        #message-input {
            flex: 1;
            padding: 10px 14px;
            border: none;
            border-radius: 6px;
            font-size: 14px;
            outline: none;
        }
        #send-btn {
            margin-left: 8px;
            padding: 10px 20px;
            background: #e94560;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
        }
        #send-btn:hover {
            background: #c73e54;
        }
    </style>
</head>
<body>
    <div class="chat-container">
        <div class="chat-header">WebSocket Chat</div>
        <div id="chat-messages"></div>
        <div class="chat-input-area">
            <input type="text" id="message-input" placeholder="Type a message...">
            <button id="send-btn">Send</button>
        </div>
    </div>
</body>
</html>

Step 5: Run the Server

node index.js

Open your browser and navigate to http://localhost:3000. You should see the chat UI — a dark-themed container with a header, message area, and input field. The chat does not work yet because we have not added Socket.io, but the Express server is serving the HTML page correctly.

Why Use express.static?

The express.static middleware automatically serves any file inside the specified folder. When the browser requests /, Express looks for index.html inside the public folder. When the browser requests /style.css, it looks for public/style.css. There is no need to manually define routes for each file.

Adding a Route (Optional)

// You can also define explicit routes
app.get('/api/status', (req, res) => {
    res.json({ status: 'online', connections: 0 });
});

Express routes let you define API endpoints alongside your static files. This is useful for combining REST APIs with WebSocket communication — something many real-world apps do.

Project Structure So Far

websocket-chat/
├── node_modules/
├── public/
│   └── index.html
├── index.js
├── package.json
└── package-lock.json

Key Takeaways

  • npm init -y creates a new Node.js project with default settings
  • Express is installed with npm install express and imported with require('express')
  • express.static('public') serves static files (HTML, CSS, JS) from a folder without manual routing
  • app.listen(PORT) starts the HTTP server and listens for incoming connections
  • This Express server will be the foundation for adding Socket.io in the next episode