Node HTTP: Building a Node.js Server

Picture the http package in Node.js like a friendly post office that helps you deliver letters (requests) to the right house (server) and return letters (responses) back to the sender (client). Now that you’ve learned about how servers can send data to clients, it’s time to roll up your sleeves and create your own server.

In this tutorial, you’ll discover how to:

Creating a Server

In the Node.js realm, the http package is already built in—no need to install anything extra. It’s like having a personal mailroom inside your Node.js runtime. To set up a new “post office,” import the package and call the createServer method.

// server.js
const http = require('http');

const server = http.createServer((req, res) => {
  // This callback function is the 'mailroom' manager,
  // receiving requests (req) and preparing responses (res).
});

Right now, the server is just a blueprint—it exists, but it’s not “connected” to the network yet. It’s like renting a new building without unlocking the doors. Clients can’t send mail (requests) if they don’t know which door (port) to knock on.

Listening for Requests on a Port

To make your server accessible, you’ll need to pick a port number. Think of a port as a door number in a large apartment building. While a building has a street address (e.g., localhost), each apartment door (e.g., :3000) is distinct, letting the right tenants in. Common development ports include 3000, 5000, and 8000, but you can choose any available port.

// server.js
const http = require('http');

const server = http.createServer((req, res) => {
  // ...
});

const port = 5000;

server.listen(port, () => console.log('Server is listening on port', port));

Running node server.js in your terminal starts the server. If all goes well, you’ll see the log message: “Server is listening on port 5000”. This means your “front door” is open, and you can now receive requests on http://localhost:5000.

Even though the door is open, nobody gets a meaningful response yet. It’s like opening your café but not having any menu. Let’s explore how to serve something more interesting than “silence.”

Request Object

The Request object (req) is like the envelope of a letter the client sends your server. Inside, you’ll find:

If you log req in your server code, you’ll see a large object with plenty of properties and methods. Most of them you won’t touch initially. Instead, you’ll focus on a few core properties to figure out how to handle each incoming request.

const server = http.createServer((req, res) => {
  console.log(req);
  
  // Make any request to http://localhost:5000 and observe the terminal
});

This helps you inspect the “envelope” of information your server receives. If someone visits http://localhost:5000/hello-world, you’ll see /hello-world in req.url, and GET in req.method.

Response Object

The Response object (res) is your chance to craft the “letter” you’re sending back to the client. Some key tools include:

const server = http.createServer((req, res) => {
  console.log(res);
  
  // Make any request to http://localhost:5000 and observe the terminal
});

If you log res, you’ll see it’s also a large object, but you’ll typically only set headers, status codes, and the body. Everything else is for deeper Node.js magic.

Putting It All Together

Let’s write a simple example that sets the status code to 200 for “OK,” specifies a Content-Type of 'text/plain', and sends back the message, “Hello from Node!”

// server.js
const http = require('http');

const server = http.createServer((req, res) => {
  // We know the request has method, url, etc.
  // Let's build a response that says "Hello from Node!"

  res.statusCode = 200;                     // Indicate a successful response
  res.setHeader('Content-Type', 'text/plain');
  res.write('Hello from Node!\n');          // Add some text to the response body
  res.end();                                // Finalize and send the response
});

const port = 5000;
server.listen(port, () => {
  console.log('Server is listening on port', port);
});

Start this server using node server.js. Visit http://localhost:5000 in your browser or send a GET request using a tool like Postman. You should see the text, “Hello from Node!” returned—like receiving a short note in the mail.

Real-World Uses and Next Steps

In everyday development, your server might do something like:

Once you’ve mastered the basics of http, you might explore popular frameworks like Express. Express simplifies routing, error handling, and middleware for tasks like handling JSON body data or logging. It’s like having extra staff in your “mailroom” that know how to sort letters, attach stamps, and route messages with greater ease.

What You’ve Learned

In this article, you explored how to create a Node.js server using the built-in http package. You also learned how to connect your server to a specific port so it can accept requests from clients. Finally, you saw how the Request and Response objects are created by http whenever a request is sent to your server, and which properties and methods are essential for crafting responses.

Next, you’ll learn how to formulate and send more elaborate responses, including dynamic content or entire files. This is where your server can transform from a simple greeter into a fully functional hero that powers your application behind the scenes.