Building a Server

A Node.js HTTP server is a long-running program created with http.createServer that listens on a port and runs a handler function for every incoming request, sending back a response you control.

Learn Building a Server in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In the last lesson you met the http module. Now you'll use it to build a real server: one that starts up, listens on a port, reads what the client asked for, and sends back exactly the status, headers, and body you choose.

What You'll Learn in This Lesson

1️⃣ The Simplest Possible Server

A working Node server is only a few lines. You give http.createServer a handler function , then call server.listen(port) to start it. The handler receives two objects every time a request arrives: req (what the client asked for) and res (the reply you build). Read every comment below, then run it.

Save that as server.js and start it. Unlike a normal script, it doesn't exit — it stays running, waiting for requests, until you stop it with Ctrl+C .

2️⃣ Setting the Status Code and Headers

Every response carries a status code (200 means OK, 404 means not found) and headers (metadata about the body). You can set both in one shot with res.writeHead(status, headers) , which must run before res.end .

Or set them one at a time with res.statusCode and res.setHeader(key, value) . To send JSON , turn your object into a string with JSON.stringify and set Content-Type to application/json so the client knows how to read it.

3️⃣ Reading the Incoming Request

So far we've ignored what the client actually asked for. The req object tells you: req.method is the verb ( GET , POST , …) and req.url is the path. A request body (sent with a POST) doesn't arrive all at once — it streams in as chunks, so you collect it on the 'data' event and act on it when 'end' fires.

Your turn. The handler below is almost done — fill in the three blanks marked ___ so it replies with the JSON object {message:'ok'} . Follow the 👉 hints, then run it and compare with the expected output.

Mini-Challenge: A Two-Route Server

No blanks this time — just a brief and an outline. Using only req.url and if statements (no router yet — that's the next lesson), build a server that answers two paths and 404s everything else. Write it yourself, run it, and check your output against the example in the comments.

Common Errors (and the fix)

Pro Tips

📋 Quick Reference — Node.js Servers

Concept

Node Syntax

Create a server

http.createServer(fn)

Start listening

server.listen(3000)

Status + headers

res.writeHead(200, headers)

Set one header

res.setHeader(k, v)

Send body + close

res.end(body)

Request method

req.method

Request path

req.url

Frequently Asked Questions

🎉 Lesson Complete!

Practice quiz

Which built-in module creates an HTTP server in Node?

  • http
  • fs
  • net-server
  • express

Answer: http. The built-in http module's createServer builds a server with no install needed.

How many handler functions does http.createServer take?

  • One handler, called for every request
  • One per route
  • Two: request and response handlers
  • None

Answer: One handler, called for every request. createServer takes a single handler that Node calls for every incoming request.

What starts the server actually listening for requests?

  • server.start()
  • server.open()
  • server.listen(port)
  • server.run()

Answer: server.listen(port). Nothing happens until server.listen(port) begins listening on a port.

What does res.end() do?

  • Restarts the server
  • Logs the request
  • Opens a new connection
  • Sends the body and closes the response

Answer: Sends the body and closes the response. res.end() sends the body and finishes the response; without it the request hangs.

Which call sets the status code and headers together, before res.end?

  • res.writeHead(status, headers)
  • res.send(status)
  • res.header(status)
  • res.status(headers)

Answer: res.writeHead(status, headers). res.writeHead(statusCode, headersObject) sets both at once and must run before res.end.

To send a JS object as JSON, what must you call first?

  • JSON.parse(obj)
  • JSON.stringify(obj)
  • obj.toJSON only
  • res.json(obj)

Answer: JSON.stringify(obj). res.end sends strings, so JSON.stringify converts the object into a JSON string.

Which property tells you the HTTP verb of the request?

  • req.url
  • req.verb
  • req.method
  • req.path

Answer: req.method. req.method holds the verb such as GET or POST; req.url holds the path.

How does a POST request body arrive in the raw http handler?

  • All at once on req.body
  • As chunks via 'data' events, finalized on 'end'
  • As a query string
  • In req.params

Answer: As chunks via 'data' events, finalized on 'end'. The body streams in as chunks you collect on 'data', then act on when 'end' fires.

What does the error 'EADDRINUSE :::3000' mean?

  • The handler crashed
  • JSON failed to parse
  • Another program already holds port 3000
  • The body was too large

Answer: Another program already holds port 3000. EADDRINUSE means the port is already in use, often by an old copy of the server.

What header tells the client a response body is JSON?

  • Content-Type: application/json
  • Accept: text/plain
  • Content-Length
  • X-JSON: true

Answer: Content-Type: application/json. Setting Content-Type to application/json tells clients to parse the body as JSON.

Continue this course