Now that you understand Node.js fundamentals, let’s build your first web server from scratch using only the core http module.
1. Basic HTTP Server
Create a file named server.js with this minimal implementation:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World!\n');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
Key Components:
1. http.createServer() – Creates server instance
2. Request handler callback – Processes all incoming requests
3. res.writeHead() – Sets response headers
4. server.listen() – Starts the server
2. Understanding Request and Response
Request Object (req)
req.url– Request URL pathreq.method– HTTP method (GET, POST, etc.)req.headers– Request headers
Response Object (res)
res.writeHead()– Set status code and headersres.write()– Send response contentres.end()– End the response
3. Handling Different Routes
Expand your server to handle multiple routes:
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Home Page</h1>');
}
else if (req.url === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Us</h1>');
}
else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 Not Found</h1>');
}
});
server.listen(3000);
4. Serving Different Content Types
| Content Type | Header | Example |
|---|---|---|
| HTML | text/html | res.writeHead(200, {'Content-Type': 'text/html'}); |
| JSON | application/json | res.writeHead(200, {'Content-Type': 'application/json'}); |
| Plain Text | text/plain | res.writeHead(200, {'Content-Type': 'text/plain'}); |
5. Serving Static Files
Create a public folder and add this file handling:
const fs = require('fs');
const path = require('path');
// Inside request handler:
const filePath = path.join(__dirname, 'public', req.url);
fs.readFile(filePath, (err, content) => {
if (err) {
if (err.code === 'ENOENT') {
// File not found
res.writeHead(404);
res.end('File not found');
} else {
// Server error
res.writeHead(500);
res.end('Server error');
}
} else {
// Success - determine content type
const extname = path.extname(filePath);
let contentType = 'text/html';
switch(extname) {
case '.js': contentType = 'text/javascript'; break;
case '.css': contentType = 'text/css'; break;
case '.json': contentType = 'application/json'; break;
case '.png': contentType = 'image/png'; break;
}
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
}
});
6. Handling POST Data
Process form submissions or API requests:
if (req.method === 'POST' && req.url === '/submit') {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
console.log('Received data:', body);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'success', data: body }));
});
}
7. Complete Server Example
Combine all concepts into a robust server:
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const server = http.createServer((req, res) => {
console.log(`${req.method} request for ${req.url}`);
// API endpoint
if (req.url === '/api/users' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([{ id: 1, name: 'John' }]));
return;
}
// Static files
let filePath = path.join(__dirname, 'public',
req.url === '/' ? 'index.html' : req.url);
fs.readFile(filePath, (err, content) => {
if (err) {
if (err.code === 'ENOENT') {
res.writeHead(404);
res.end('404 Not Found');
} else {
res.writeHead(500);
res.end('Server Error');
}
} else {
res.writeHead(200);
res.end(content);
}
});
});
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Next: Asynchronous Programming in Node.js →
Server Checklist
- Handle different HTTP methods (GET, POST, etc.)
- Proper error handling (404, 500 responses)
- Correct content-type headers
- Environment variables for configuration
- Logging for debugging
