Build a Nodejs HTTP Server Without Frameworks

This article provides a step-by-step guide on how to create a functional HTTP server in Node.js using only its built-in modules. You will learn how to initialize the server, handle incoming client requests, send back appropriate plain text or JSON responses, and set up basic routing without relying on third-party frameworks like Express.

To build a native HTTP server, Node.js provides a built-in module called http. This eliminates the need to install any external dependencies, keeping your application lightweight and helping you understand the underlying mechanics of web servers.

Step 1: Import the HTTP Module

First, create a JavaScript file (e.g., server.js) and import the native http module.

const http = require('http');

Step 2: Create the Server

Use the createServer method provided by the http module. This method takes a callback function with two arguments: req (the incoming request object) and res (the outgoing response object).

const server = http.createServer((req, res) => {
    // Set the response HTTP header with HTTP status and Content-Type
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    
    // Send the response body
    res.end('Hello, World!\n');
});

Step 3: Define the Port and Start Listening

To make the server accessible, you must instruct it to listen on a specific port and hostname.

const PORT = 3000;
const HOST = 'localhost';

server.listen(PORT, HOST, () => {
    console.log(`Server is running at http://${HOST}:${PORT}/`);
});

Step 4: Adding Basic Routing

In a real-world scenario, your server needs to handle different URL paths and HTTP methods. You can achieve this by inspecting the req.url and req.method properties inside the server callback.

Here is a complete, runnable example showing how to route different endpoints and return both plain text and JSON:

const http = require('http');

const server = http.createServer((req, res) => {
    // Route: GET /
    if (req.url === '/' && req.method === 'GET') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Welcome to the Homepage!');
    } 
    // Route: GET /about
    else if (req.url === '/about' && req.method === 'GET') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('About Us Page');
    } 
    // Route: GET /api/data (JSON Response)
    else if (req.url === '/api/data' && req.method === 'GET') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ message: "Hello from the API", status: "success" }));
    } 
    // Fallback: 404 Not Found
    else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('404 Not Found');
    }
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

Step 5: Run the Server

To start your server, open your terminal, navigate to the directory containing your server.js file, and execute:

node server.js

Open your web browser or an API client and navigate to http://localhost:3000. You can test the different routes by visiting http://localhost:3000/about and http://localhost:3000/api/data.