# Setting Up Your First Node.js Application

If you’ve spent your JavaScript career strictly in the browser, opening the terminal to run server-side code feels like stepping out of a sandbox and into a machine shop.

In the browser, a lot of decisions are made for you. The HTML file loads the script, the DOM is just *there*, and the application stops when the user closes the tab. On the server, you have to build the machine yourself. You decide when it starts, what port it listens to, and how it responds to the outside world.

Today, we are going to set up that machine. We won’t use any frameworks like Express or NestJS. Frameworks are incredibly useful, but they hide the mechanics of how Node.js actually communicates with the operating system. Before we abstract the details away, we need to understand what the metal looks like.

Let’s build your first Node.js application, step by step.

* * *

### Step 1: Acquiring the Engine

To run JavaScript outside the browser, you need to install the Node.js runtime on your computer.

Regardless of whether you are on macOS, Windows, or Linux, the easiest starting point is to go to the official website ([nodejs.org](https://nodejs.org)) and download the installer.

You will usually see two versions: **Current** (the latest features) and **LTS** (Long Term Support). Always grab the LTS version. It is stable, heavily tested, and the standard for production environments.

Once the installer finishes, open your terminal (or Command Prompt / PowerShell on Windows). We need to verify that your operating system now recognizes Node as a valid command.

```bash
node -v
```

If it prints a version number (like `v20.11.0`), you are ready to go.

### Step 2: The Sandbox in the Terminal (REPL)

Before we write any files, let’s talk directly to the Node engine. In your terminal, just type `node` and hit Enter.

```bash
node
Welcome to Node.js v20.11.0.
Type ".help" for more information.
> 
```

You are now inside the **REPL**. This stands for **R**ead, **E**val, **P**rint, **L**oop.

It is the exact equivalent of opening the Developer Tools console in your browser. Node **reads** what you type, **evaluates** the JavaScript, **prints** the result, and **loops** back to wait for your next command.

Try it out:

```javascript
> const greeting = "Hello from the terminal!";
undefined
> greeting.toUpperCase();
'HELLO FROM THE TERMINAL!'
> Math.random() * 100;
42.8719320
```

The REPL is fantastic for quick tests, debugging logic, or checking how a specific JavaScript method works without needing to spin up a whole project.

But it’s entirely temporary. When you leave, the memory is wiped. To exit the REPL, type `.exit` and hit Enter, or press `Ctrl + C` twice.

### Step 3: Writing Your First Node Script

Real applications live in files. Create a new directory for your project, open it in your code editor, and create a file named `app.js`.

Let's write a simple script that grabs some basic information about the operating system running the code. Node gives us a built-in module called `os` for this exact purpose.

```javascript
// app.js

// Import the built-in operating system module
const os = require('os');

console.log("System Information Check:");
console.log(`Platform: ${os.platform()}`);
console.log(`CPU Architecture: ${os.arch()}`);
console.log(`Total Memory: ${os.totalmem() / 1024 / 1024 / 1024} GB`);
```

To execute this file, go back to your terminal, ensure you are in the same folder as `app.js`, and run the `node` command followed by the filename:

```bash
node app.js
```

You should see your system's specs printed out.

Notice what happened: Node read the file top-to-bottom, executed the synchronous commands, and then immediately exited back to the terminal prompt. The process died naturally because there was no more code to run.

But a web server isn't supposed to die. It’s supposed to run forever, waiting for users.

* * *

### Step 4: Building a Raw HTTP Server

Let’s build an actual web server. Create a new file called `server.js`.

To do this, we need to use another built-in Node module: `http`. This module gives Node the ability to open a network port on your machine and listen for incoming HTTP traffic.

Here is the complete, raw code for a functioning web server:

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

// 1. Define the port and the host
const PORT = 3000;
const HOST = '127.0.0.1'; // This means "localhost" (your own machine)

// 2. Create the server
const server = http.createServer((req, res) => {
    // This callback runs EVERY time a browser requests this server

    // Log the request method and URL to our terminal
    console.log(`Incoming Request: ${req.method} ${req.url}`);

    // Set the HTTP response status code to 200 (OK)
    res.statusCode = 200;
    
    // Tell the browser what type of data we are sending back
    res.setHeader('Content-Type', 'text/plain');
    
    // Send the data and end the response
    res.end('Hello from the raw Node.js backend!\n');
});

// 3. Tell the server to start listening
server.listen(PORT, HOST, () => {
    console.log(`Server is up and running at http://${HOST}:${PORT}`);
    console.log('Press Ctrl+C to stop it.');
});
```

### Breaking Down the Mechanics

There are three critical concepts happening in this code:

1.  **The Callback Engine:** The function we pass into `http.createServer()` doesn't execute immediately. It is an event listener. It just sits there, waiting. When someone navigates to your server, Node triggers this callback, passing in two objects: `req` (the incoming request data) and `res` (the outgoing response toolkit).
    
2.  **The Headers (**`res.setHeader`**):** Browsers are dumb; they need to be told exactly what they are looking at. By setting the `Content-Type` to `text/plain`, we are explicitly telling the browser not to try to render HTML, just display text.
    
3.  **Closing the Loop (**`res.end`**):** If you forget to call `res.end()`, the browser will just spin forever, waiting for the server to finish talking. You must explicitly end the connection.
    

### Step 5: Booting It Up

Go to your terminal and run the server file:

```bash
node server.js
```

Unlike our `app.js` script, the terminal prompt will not return. The process hangs. Your Node application is now actively monitoring Port 3000 on your network interface.

Open your web browser and navigate to: `http://localhost:3000`

You will see your "Hello from the raw Node.js backend!" message.

Look back at your terminal. You should see a log of the incoming request:

```text
Server is up and running at http://127.0.0.1:3000
Incoming Request: GET /
Incoming Request: GET /favicon.ico
```

*(Notice that the browser automatically asked for a favicon, which triggered our callback a second time!)*

To shut the server down and get your terminal back, press `Ctrl + C`.

### The Takeaway

Congratulations. You just built a backend.

If you look at the `server.js` code, you might notice that routing different URLs (like `/users` or `/about`) would quickly become a messy series of `if/else` statements inspecting `req.url`. Handling JSON parsing, file uploads, and security headers manually using the raw `http` module is tedious and error-prone.

That is exactly why frameworks like Express exist. They wrap this raw `http.createServer` logic in a much friendlier, cleaner API.

But Express is just a wrapper. Underneath the hood, every single request on a Node.js server flows through the exact `req` and `res` objects you just learned how to manipulate. By starting here, you don't just know how to type commands—you actually know how the machine works.
