← Back to Examples
HTTP Module
Build HTTP servers using Node.js built-in http module - no Express needed!
1. Basic HTTP Server
const http = require('http');
const server = http.createServer((req, res) => {
console.log(`${req.method} ${req.url}`);
res.writeHead(200, {
'Content-Type': 'text/html',
'X-Custom-Header': 'MyServer'
});
res.write('<!DOCTYPE html>');
res.write('<html><body>');
res.write('<h1>Hello from Node.js!</h1>');
res.write(`<p>You requested: ${req.url}</p>`);
res.write(`<p>Method: ${req.method}</p>`);
res.write(`<p>Time: ${new Date().toLocaleString()}</p>`);
res.write('</body></html>');
res.end();
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
console.log('Press Ctrl+C to stop');
});
$ node basic-server.js
Server running at http://localhost:3000
2. Responding with Different Content Types
const http = require('http');
const server = http.createServer((req, res) => {
switch (req.url) {
case '/':
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<h1>Content Type Demo</h1>
<ul>
<li><a href="/html">HTML Response</a></li>
<li><a href="/json">JSON Response</a></li>
<li><a href="/text">Text Response</a></li>
<li><a href="/xml">XML Response</a></li>
</ul>
`);
break;
case '/html':
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>This is HTML!</h1><p>With markup.</p>');
break;
case '/json':
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: 'This is JSON!',
timestamp: new Date().toISOString(),
data: [1, 2, 3]
}, null, 2));
break;
case '/text':
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('This is plain text. No formatting.');
break;
case '/xml':
res.writeHead(200, { 'Content-Type': 'application/xml' });
res.end(`<?xml version="1.0"?>
<message>
<text>This is XML!</text>
<time>${new Date().toISOString()}</time>
</message>`);
break;
default:
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 - Not Found</h1>');
}
});
server.listen(3000, () => {
console.log('Content-type demo at http://localhost:3000');
});
3. Request Details
const http = require('http');
const server = http.createServer((req, res) => {
console.log('--- New Request ---');
console.log('Method:', req.method);
console.log('URL:', req.url);
console.log('HTTP Version:', req.httpVersion);
console.log('Headers:');
for (const [key, value] of Object.entries(req.headers)) {
console.log(` ${key}: ${value}`);
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
method: req.method,
url: req.url,
httpVersion: req.httpVersion,
headers: req.headers,
remoteAddress: req.socket.remoteAddress
}, null, 2));
});
server.listen(3000, () => {
console.log('Request inspector at http://localhost:3000');
});
4. Handling POST Requests
const http = require('http');
function getBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
if (body.length > 1e6) {
req.destroy();
reject(new Error('Body too large'));
}
});
req.on('end', () => resolve(body));
req.on('error', reject);
});
}
const server = http.createServer(async (req, res) => {
if (req.method === 'GET' && req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<!DOCTYPE html>
<html>
<head><title>POST Demo</title></head>
<body>
<h1>Submit Data</h1>
<form method="POST" action="/submit">
<label>Name: <input name="name" required></label><br><br>
<label>Email: <input name="email" type="email" required></label><br><br>
<button type="submit">Submit</button>
</form>
<h2>Or send JSON:</h2>
<pre>curl -X POST http://localhost:3000/api/data \\
-H "Content-Type: application/json" \\
-d '{"name":"Alice","email":"alice@example.com"}'</pre>
</body>
</html>
`);
return;
}
if (req.method === 'POST' && req.url === '/submit') {
const body = await getBody(req);
const params = new URLSearchParams(body);
const data = Object.fromEntries(params);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<h1>Form Received!</h1>
<p>Name: ${data.name}</p>
<p>Email: ${data.email}</p>
<a href="/">Back</a>
`);
return;
}
if (req.method === 'POST' && req.url === '/api/data') {
try {
const body = await getBody(req);
const data = JSON.parse(body);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: 'Data received!',
received: data,
timestamp: new Date().toISOString()
}, null, 2));
} catch (err) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid JSON' }));
}
return;
}
res.writeHead(404);
res.end('Not Found');
});
server.listen(3000, () => {
console.log('POST demo at http://localhost:3000');
});
5. Server Events
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello!');
});
server.on('listening', () => {
const addr = server.address();
console.log(`Server listening on ${addr.address}:${addr.port}`);
});
server.on('connection', (socket) => {
console.log('New connection from:', socket.remoteAddress);
});
server.on('close', () => {
console.log('Server closed');
});
server.on('error', (err) => {
if (err.code === 'EADDRINUSE') {
console.error(`Port ${err.port} is already in use!`);
console.error('Try a different port or kill the other process.');
} else {
console.error('Server error:', err);
}
});
process.on('SIGINT', () => {
console.log('\nShutting down gracefully...');
server.close(() => {
console.log('Server closed. Goodbye!');
process.exit(0);
});
});
server.listen(3000);
Comparing http module vs Express.js: Express is built on top of the http module. It adds routing, middleware, template engines, and many convenience methods. For production apps, use Express. Understanding the http module helps you understand what Express does under the hood.
← Back to Examples