NodeJSHello World in Node.js

Hello World in Node.js

Time to write real programs. We will build three "hello worlds" of increasing usefulness: a console log, a script with logic, and an actual HTTP server — the thing that makes Node.js a backend platform. By the end you will understand not just how to run each, but why the server keeps running while the script exits.

1. The classic console log

hello.js

JS
console.log('Hello, World!')

Bash
node hello.js
Hello, World!
It runs, then exits
Node executes the file top to bottom, finds the event loop has nothing pending, and exits with code 0. The whole thing takes milliseconds. Remember this — the server in step 3 behaves completely differently.
2. A script that does something

greet.js

JS
const hour = new Date().getHours()
const greeting =
  hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening'

const name = process.argv[2] || 'World'
console.log(`${greeting}, ${name}!`)

Bash
node greet.js Sam
Good afternoon, Sam!
3. Your first web server

This is the moment Node.js becomes a server. Using the built-in http module, you can answer real HTTP requests in a handful of lines — no framework, no install:

server.js

JS
import http from 'node:http'

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' })
  res.end('Hello, World from a Node.js server!\n')
})

const PORT = 3000
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`)
})

Bash
node server.js
Server running at http://localhost:3000

Open http://localhost:3000 in a browser — you will see your message. Or test it from another terminal with curl:

Bash
curl http://localhost:3000
Hello, World from a Node.js server!

Press Ctrl + C in the terminal to stop the server.

Why does the server keep running?
An active handle keeps the loop alive
Unlike `hello.js`, the server does not exit. Calling `server.listen()` registers an **active handle** with the [event loop](/nodejs/event-loop) — a listening socket. As long as a ref'd handle exists, the loop has "work" and Node stays alive, parked waiting for connections. Stopping the server (or `server.close()`) removes the handle, the loop drains, and the process exits.
The request handler runs per request

The function you passed to createServer is a callback invoked once for every incoming request, with a fresh req (readable stream of the request) and res (writable stream for your response). Because it all runs on the single thread, the golden rule applies: keep the handler fast and never block it.

A common first mistake: forgetting res.end()
Every response **must** be finished with `res.end()` (or a method that ends it). If you only `res.write()` and never end, the browser hangs forever waiting for more data, and the connection stays open consuming a socket. Always end the response on every code path.
What you just learned

Concept

Where it showed up

Running files

node file.js

Reading input

process.argv[2]

Core modules

import http from 'node:http' — no install

Script vs server lifetime

The loop exits when empty, stays alive with a listener

Request/response streams

The (req, res) handler

Next
You have completed setup. Before the Node-specific deep dives, brush up the language with [JavaScript Essentials for Node](/nodejs/js-essentials).