Most Node.js tutorials jump straight to Express. But before you reach for a framework, it's worth understanding what's happening underneath — because once you do, everything else clicks.
In this tutorial, Deividas Strole walks you through building a simple HTTP server using only Node's built-in modules. No Express, no npm install, no dependencies of any kind. Just the runtime doing its thing.
By the end, you'll have a working local server that serves a static HTML file — and a much clearer mental model of how the web actually works.
What You'll Learn
- How the Node.js http module handles requests and responses
- How to read files from disk using the fs module
- How to serve a static HTML page
- How to handle 404 routes cleanly
- How to run everything locally in under a minute
Prerequisites
- Node.js installed (nodejs.org)
- Basic JavaScript knowledge
- A text editor (VS Code, Vim, anything works)
No package manager needed. We're going fully built-in.
Step 1: Create the HTML File
First, create index.html. This is what your server will send to the browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>My Node Server</title>
<style>
body {
font-family: monospace;
background: #0d1117;
color: #e6edf3;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
}
h1 { color: #3fb950; }
p { color: #8b949e; }
</style>
</head>
<body>
<div>
<h1>✓ Server is running</h1>
<p>Served by Node.js — no frameworks needed.</p>
</div>
</body>
</html>
Simple, clean, and it'll look great in the browser.
Step 2: Create the Server
Now create server.js. This is where the magic happens.
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const HTML_FILE = path.join(__dirname, 'index.html');
const server = http.createServer((req, res) => {
// Only serve the root route
if (req.url === '/' || req.url === '/index.html') {
fs.readFile(HTML_FILE, (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('500 Internal Server Error');
return;
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(data);
});
} else {
// Everything else gets a 404
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 Not Found');
}
});
server.listen(PORT, () => {
console.log(`✅ Server running at http://localhost:${PORT}`);
});
That's it. 30 lines. Let's break down what each part does.
Step 3: Run It
In your terminal, navigate to your project folder and run:
node server.js
Open your browser and go to http://localhost:3000. You'll see your HTML page served by your own server.
Try visiting http://localhost:3000/anything-else — you'll get the 404 response.
To stop the server, press Ctrl + C.
Full Source Code
The complete project is on GitHub:
👉 github.com/deividas-strole/node-js-server
Drop a ⭐ if you found it useful.
Top comments (0)