Skip to main content

Command Palette

Search for a command to run...

Setting Up Your First Node.js Application Step-by-Step

Updated
7 min read
Setting Up Your First Node.js Application Step-by-Step

There is a very specific, unforgettable moment in every JavaScript developer's career.

For months, maybe years, you’ve been writing JavaScript inside the browser. You write a function, you refresh Chrome, a div changes color, and a button pops up. It feels great, but eventually, you realize something: you are locked inside a padded room.

The browser is a highly secure, heavily restricted walled garden. For your own safety, the browser absolutely refuses to let your JavaScript code touch the user's hard drive. It won't let you open raw network ports. It won't let you spin up a database.

And then, one day, you install Node.js.

You write a few lines of code, open your computer's raw terminal, hit Enter, and suddenly, the walls fall down. Your machine becomes a living, breathing web server. You aren't just reacting to button clicks anymore. You are intercepting raw HTTP network traffic.

Today, we are going to cross that threshold. We are going to install Node.js, look deeply under the hood at how it communicates with your computer's operating system, and write a raw, framework-free server from scratch.

Step 1: The Installation & The C++ Bridge

Unlike browser JavaScript, which just magically exists inside Chrome or Safari, Node.js is a heavyweight piece of software you have to physically install on your operating system.

But what actually is it?

At its core, Node.js is simply the Google Chrome V8 JavaScript engine, ripped out of the browser and bolted onto your operating system using C++. JavaScript natively has no idea what a "file system" or a "network socket" is. Node.js fixes this. It provides a set of C++ Bindings—a bridge that takes your JavaScript commands, translates them into C++, and hands them directly to your Windows, Mac, or Linux kernel.

How to get it: Regardless of your operating system, go to the official website (nodejs.org) and download the LTS (Long Term Support) installer.

Once it finishes, we need to perform a sanity check to prove that your computer’s terminal now natively understands JavaScript. Open your terminal (Command Prompt/PowerShell on Windows, or Terminal on Mac/Linux) and type:

node -v // eg: v20.20.2

If the installation worked, it won't throw an error. It will print back a version number, like v20.11.0. Congratulations. Your machine is officially a backend environment.

Step 2: The REPL (Your Terminal Playground)

Before we write a file, let's talk directly to the V8 engine.

If you just type node into your terminal and hit Enter, something weird happens. Your normal terminal prompt disappears, replaced by a single >.

You have just entered the REPL.

REPL stands for Read, Eval, Print, Loop. It is essentially the exact same thing as the Developer Console in your browser, but it lives directly inside your terminal.

  1. It Reads the JavaScript you type.

  2. It Evaluates (compiles and executes) the code in real-time.

  3. It Prints the result back to you.

  4. It Loops back and waits for your next command.

Try typing some standard JavaScript right there in the terminal:

> const name = "Backend Developer";
> console.log(`I am a ${name}!`);
I am a Backend Developer!
undefined

The REPL is a fantastic playground for quickly testing a math equation, checking how a specific Array.reduce method works, or debugging a tiny piece of logic without having to create a whole new file. To escape the REPL, type .exit and hit Enter, or press Ctrl + C twice.

Step 3: Writing Your First Script (And breaking the sandbox)

The REPL forgets everything as soon as you close it. To build real software, we need to write scripts.

Create a new, empty folder on your computer. Open that folder in your favorite code editor. Create a brand new file named app.js.

Inside app.js, write this code. Look closely at the second half:

// app.js
console.log("Hello from the other side of the browser.");

// We are pulling in a core Node.js C++ module!
const os = require('os');

const totalMemory = os.totalmem() / 1024 / 1024 / 1024;
console.log(`You are running this on a \({os.type()} machine with \){Math.round(totalMemory)} GB of RAM!`);

Here is the mind-bending part: JavaScript natively cannot read your computer's RAM. We just used require('os') to reach across the C++ bridge, ask the operating system for hardware specs, and pass it back to our JavaScript. You could never do that in a browser!

The Execution Flow: To run this file, open your terminal, ensure you are inside the folder where you saved app.js, and type:

node app.js

When you hit Enter, Node.js reads your file, compiles the text into raw machine code using V8, crosses the C++ bridge to fetch the memory stats, and executes the instructions. The text instantly prints in your terminal.

Step 4: The Milestone (Building a Raw HTTP Server)

Printing text to a terminal is cool, but we are web developers. We want to intercept network traffic.

Many tutorials immediately tell you to install a framework like Express.js. We aren't going to do that today. Frameworks use "magic" to hide the complex networking logic. We are going to build a server using nothing but the raw, built-in networking tools that Node.js provides.

Delete the code in app.js and replace it with this:

// 1. Import the built-in HTTP module (The network bridge)
const http = require('http');

// 2. Create the server
const server = http.createServer((request, response) => {

    // Every single time a browser pings this server, this callback fires!
    console.log(`Incoming network request for: ${request.url}`);

    // 3. Write the HTTP Headers (Status Code 200 = Everything is OK)
    // We are telling the browser: "I am about to send you plain text."
    response.writeHead(200, { 'Content-Type': 'text/plain' });

    // 4. Send the payload and physically close the network connection
    response.end("Hello World! I built this raw server from scratch.");
});

// 5. Tell the server to actively claim and listen to Port 3000
server.listen(3000, () => {
    console.log("The TCP connection is open! Listening on http://localhost:3000");
});

Let's look deeply at exactly what is happening under the hood:

  • require('http'): Underneath this module is a highly complex HTTP parser. Network traffic is just a stream of raw 1s and 0s. This module reads that stream and parses it into the readable request and response objects.

  • createServer: We are telling the operating system to allocate memory for a new server. We hand it a callback function. Note that request and response aren't just static objects; they are actually continuous Streams. Data can flow in and out of them over time.

  • listen(3000): What is a port? Think of your computer's IP address like the street address of an enormous apartment building. A "Port" is simply an apartment number. Your computer has exactly 65,535 ports. When we say listen(3000), we are telling the OS, "Lock the door to Apartment 3000. If anyone knocks on that specific door, route the message to my Node.js script."

Step 5: Going Live

Save the file. Go back to your terminal, and run the command again:

node app.js

This time, the script doesn't finish and drop you back into your empty terminal. It hangs. It stays open. You will see your message: The TCP connection is open! Listening on http://localhost:3000.

Your terminal is now actively holding open a network socket, listening for traffic.

Open your web browser (Chrome, Firefox, Safari) and type http://localhost:3000 into the address bar. Hit Enter.

Look at your browser. You will see: "Hello World! I built this raw server from scratch." Now look at your terminal. You will see: Incoming network request for: /

The Takeaway

Take a second to appreciate the gravity of what you just accomplished.

You didn't just write a script that changed the color of a button. You transformed your personal computer into an active piece of network infrastructure. When you typed localhost:3000 into your browser, Chrome packaged up a raw HTTP request, routed it through your computer's internal TCP/IP network stack, knocked on Port 3000, and your Node.js C++ bindings answered the door.

This is the exact same underlying mechanism that powers the largest APIs on earth. Whether you are building a simple "Hello World" site or a global e-commerce backend handling millions of requests per second, the architecture starts right here, with a single port and an HTTP listener.

Welcome to the backend.