# Setting Up Your First Node.js Application: A Step-by-Step Guide from Install to HTTP Server

# Setting Up Your First Node.js Application: A Step-by-Step Guide from Install to HTTP Server

**Audience:** This post is for developers who are new to Node.js but comfortable with basic JavaScript. No prior server-side experience required.

**TL;DR:** Install Node.js, verify it works in your terminal, explore the REPL, write a `.js` file, run it with the `node` command, and build a minimal HTTP server using only Node's built-in `http` module — no Express, no dependencies.

---

## Problem

Most Node.js tutorials start with `npm install express` before you understand what Node even is. That skips the foundation entirely. Before you use any framework, you need to know: How does Node run JavaScript? What happens when you execute a file? How does it handle an HTTP request at the lowest level?

This post fills that gap.

---

## Solution

We'll go step-by-step through the full setup process — from installing the runtime to serving HTTP responses — using only Node's standard library.

---

### Step 1: Install Node.js

Go to [https://nodejs.org](https://nodejs.org) and download the **LTS (Long Term Support)** version. As of 2025, that's Node.js 20.x or 22.x.

**Why LTS?** LTS releases are supported for 30 months with security and bug fixes. The Current release gets new features faster but isn't recommended for production or learning stability.

**OS-neutral options:**

- **Windows / macOS:** Use the official installer from nodejs.org
- **Linux (Ubuntu/Debian):**

```bash
# Using NodeSource repository for the latest LTS
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
```

- **All platforms (recommended for managing versions):** Use [nvm](https://github.com/nvm-sh/nvm)

```bash
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Restart your terminal, then install Node LTS
nvm install --lts
nvm use --lts
```

Using `nvm` is the best long-term choice because it lets you switch Node versions per project.

---

### Step 2: Verify the Installation

Open your terminal and run:

```bash
node --version
```

**Expected output:**
```
v20.11.1
```

Also verify `npm` (Node Package Manager) was installed alongside Node:

```bash
npm --version
```

**Expected output:**
```
10.2.4
```

If either command returns `command not found`, the installation didn't complete correctly. On Windows, restart your terminal or check that Node's install directory is in your `PATH` environment variable.

---

### Step 3: Understand and Use the Node REPL

**What is the REPL?**

REPL stands for **Read-Eval-Print Loop**. It's an interactive runtime session where Node reads your input, evaluates it as JavaScript, prints the result, and waits for the next input. Think of it as a JavaScript console that runs in your terminal instead of a browser.

It's useful for:
- Testing small expressions quickly
- Exploring built-in modules
- Debugging logic in isolation

**Start the REPL:**

```bash
node
```

Your prompt changes to `>`.

**Try these inside the REPL:**

```javascript
> 2 + 2
4

> const name = 'Node.js'
> `Hello from ${name}`
'Hello from Node.js'

> typeof process
'object'

> process.version
'v20.11.1'

> process.platform
'linux'   // or 'darwin' on macOS, 'win32' on Windows
```

The `process` object is global in Node — it gives you runtime information about the current Node process. You'll use it constantly.

To exit the REPL, press `Ctrl + C` twice or type `.exit`.

---

### Step 4: Create and Run Your First JavaScript File

Create a directory for your project:

```bash
mkdir node-fundamentals
cd node-fundamentals
```

Create a file called `greet.js`:

```javascript
// greet.js
const userName = 'Alice';
const currentHour = new Date().getHours();

let greeting;

if (currentHour < 12) {
  greeting = 'Good morning';
} else if (currentHour < 18) {
  greeting = 'Good afternoon';
} else {
  greeting = 'Good evening';
}

console.log(`${greeting}, ${userName}!`);
console.log(`Node.js version: ${process.version}`);
console.log(`Platform: ${process.platform}`);
```

Run it:

```bash
node greet.js
```

**Expected output (if run in the morning):**
```
Good morning, Alice!
Node.js version: v20.11.1
Platform: linux
```

**What just happened — the execution flow:**

```
greet.js (source file)
     |
     v
Node.js Runtime
     |
     |-- V8 Engine parses and compiles the JS
     |-- libuv handles I/O (not used here, but available)
     |-- process object injected into scope
     |
     v
stdout (your terminal)
Good morning, Alice!
```

Node reads the file as a string, passes it to the V8 JavaScript engine (the same engine Chrome uses), executes it synchronously top-to-bottom, writes to stdout via `console.log`, and exits. No browser, no DOM, no window object — just JavaScript running directly on your machine.

---

### Step 5: Write a Hello World HTTP Server

Node ships with a built-in `http` module. No installation required. This is the foundation that frameworks like Express are built on.

Create a file called `server.js`:

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

const HOST = '127.0.0.1';
const PORT = 3000;

const server = http.createServer((request, response) => {
  const { method, url } = request;

  console.log(`[${new Date().toISOString()}] ${method} ${url}`);

  // Set response headers
  response.setHeader('Content-Type', 'text/plain');

  // Route handling without a framework
  if (url === '/' && method === 'GET') {
    response.statusCode = 200;
    response.end('Hello, World!\n');
  } else if (url === '/health' && method === 'GET') {
    response.statusCode = 200;
    response.end('OK\n');
  } else {
    response.statusCode = 404;
    response.end('Not Found\n');
  }
});

server.listen(PORT, HOST, () => {
  console.log(`Server running at http://${HOST}:${PORT}/`);
  console.log('Press Ctrl+C to stop');
});
```

Run the server:

```bash
node server.js
```

**Terminal output:**
```
Server running at http://127.0.0.1:3000/
Press Ctrl+C to stop
```

Now test it. Open a **second terminal** and use `curl`:

```bash
curl http://127.0.0.1:3000/
```
**Output:**
```
Hello, World!
```

```bash
curl http://127.0.0.1:3000/health
```
**Output:**
```
OK
```

```bash
curl http://127.0.0.1:3000/missing
```
**Output:**
```
Not Found
```

Back in the first terminal, you'll see the request log:
```
[2025-01-15T08:32:11.042Z] GET /
[2025-01-15T08:32:14.318Z] GET /health
[2025-01-15T08:32:17.901Z] GET /missing
```

**What's happening under the hood:**

`http.createServer()` returns a `Server` object. The callback you pass is an **event listener** — Node registers it to fire every time an HTTP request arrives. Node's event loop keeps the process alive and calls this callback each time a new TCP connection completes an HTTP request. Without a framework, you manually check `request.url` and `request.method` to route requests.

`response.end()` writes the body and signals that the response is complete. Calling it is mandatory — if you don't, the client will hang waiting for more data.

---

## Results

At this point you have:
- Node.js installed and verified
- A working understanding of the REPL for quick testing
- A runnable `.js` script demonstrating Node's execution model
- A functioning HTTP server handling three routes with proper status codes and logging

All of this with zero external dependencies.

---

## Trade-offs

| What we did | The limitation |
|---|---|
| Used built-in `http` module | URL parsing, body parsing, and routing become verbose at scale. Use Express or Fastify for real applications. |
| Manual `url` string matching | Doesn't handle query parameters, dynamic segments, or method mismatch gracefully without extra code |
| Single file | Fine for learning; production apps need module separation, error handling middleware, and process management (e.g., PM2) |
| `require()` syntax | Modern Node supports ES Modules (`import/export`). `require` is CommonJS — still widely used, but be aware both exist |

This setup is intentionally minimal. Its value is teaching you what's underneath — not what to ship to production.

---

## Conclusion

You now have a concrete mental model of how Node.js works: it's a JavaScript runtime built on V8 and libuv, capable of running scripts and handling I/O (like HTTP) without a browser. The REPL is your scratchpad. `node filename.js` is how you execute code. The `http` module is the raw foundation of every Node web server.

The logical next step is to look at how Express wraps this `http` module — once you've seen the raw version, the abstractions will make sense instead of feeling like magic.

---

## Further Reading

- [Node.js Official Docs — Getting Started](https://nodejs.org/en/docs/guides/getting-started-guide)
- [Node.js `http` module reference](https://nodejs.org/api/http.html)
- [Understanding the Node.js Event Loop — Official Guide](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick)
- [nvm — Node Version Manager](https://github.com/nvm-sh/nvm)
- [Node.js Release Schedule (LTS vs Current)](https://nodejs.org/en/about/previous-releases)
