Skip to main content

Command Palette

Search for a command to run...

What is Node.js? JavaScript on the Server Explained

Updated
11 min read
What is Node.js? JavaScript on the Server Explained
H
CS undergrad | Tech enthusiast | Focusing on Web Dev • DSA • ML | Building skills for real-world impact

Node.js lets you run JavaScript outside the browser—on servers, databases, and beyond. Instead of learning a new language for the backend, you write the same JavaScript everywhere.

This is about understanding what Node.js is and why it changed how we build web applications.


What is Node.js?

Node.js is a runtime environment that executes JavaScript code outside the browser.

The Simple Definition

Runtime = An environment where code runs. JavaScript runtime = A place where JavaScript code executes.

Before Node.js, only browsers could run JavaScript. Node.js made it possible to run JavaScript on servers too.

Real Example

Before Node.js:

Frontend: JavaScript (in browser)
Backend: PHP, Python, Java (on server)
You had to learn multiple languages

After Node.js:

Frontend: JavaScript (in browser)
Backend: JavaScript (on server)
One language everywhere

Why This Matters

Most developers already knew JavaScript for the browser. Node.js meant they could write backend code without learning a new language.


Why Was JavaScript Browser-Only?

JavaScript was literally created for browsers.

The Origin Story (1995)

Brendan Eich created JavaScript in 10 days for Netscape Navigator. It was designed to:

  • Run in web browsers
  • Manipulate HTML and CSS
  • Respond to user interactions
  • Validate forms

There was no concept of "server-side JavaScript" in 1995.

Browser Capabilities

Browsers had everything JavaScript needed:

// Browser JavaScript
document.getElementById("button").addEventListener("click", () => {
  alert("Button clicked!");
});

The browser provided document, window, DOM APIs, etc. These only existed in browsers.

No Server Features

JavaScript had no way to:

  • Read/write files on disk
  • Connect to databases
  • Listen for incoming network requests
  • Run as a long-lived process

It was perfectly designed for browsers. Just not for servers.


How Node.js Changed Everything

The Breakthrough (2009)

Ryan Dahl created Node.js with a radical idea: take the JavaScript engine from Chrome and let it run on servers.

Instead of creating a new language or runtime, he reused existing JavaScript technology.

What Node.js Added

Node.js removed browser APIs and added server APIs:

// Browser (Node.js can't do this)
document.getElementById("button");  // No document
window.alert("Hi");                 // No window

// Server (Node.js can do this)
const fs = require("fs");           // Read files
const http = require("http");       // Create servers
const net = require("net");         // Network sockets

The JavaScript Runtime Difference

Browser Runtime (JavaScript)
├─ JavaScript language (same)
├─ DOM API (document, element)
├─ Window API (localStorage, fetch)
├─ Event system (click, scroll)
└─ Security sandbox (can't access disk)

Node.js Runtime (JavaScript)
├─ JavaScript language (same)
├─ File System (fs module)
├─ HTTP Server (http module)
├─ OS utilities (os, path modules)
└─ Full disk/network access

Same language. Different APIs.


Browser JS vs Server JS: The Analogy

Browser JavaScript

Think of browser JavaScript as a theater actor:

  • Performs on stage (the browser window)
  • Interacts with the audience (user clicks, scrolls)
  • Props and scenery are provided (DOM, document)
  • Can't leave the theater
  • Limited to what the stage allows
// Browser: responding to user
button.addEventListener("click", () => {
  console.log("User clicked");
});

Server JavaScript (Node.js)

Think of server JavaScript as a factory manager:

  • Runs operations behind the scenes
  • Doesn't interact with users directly
  • Controls machinery (databases, files, networks)
  • Runs 24/7
  • Manages resources and processes
// Server: listening for requests
server.listen(3000, () => {
  console.log("Server running");
});

Different roles. Same skill (JavaScript).


The V8 Engine: Under the Hood

What is V8?

V8 is Google's JavaScript engine. It's what makes JavaScript fast.

JavaScript vs Runtime

JavaScript (language)
  ↓
V8 Engine (converts to machine code)
  ↓
Computer (executes)

V8 takes JavaScript code and compiles it to machine code so computers can run it blazingly fast.

Why V8 Matters

Before V8 (early 2000s):

  • JavaScript was interpreted line-by-line
  • Slow

V8 (2008+):

  • Compiles JavaScript to machine code
  • ~1000x faster

Node.js uses V8, which is why JavaScript on servers can be performant.

You Don't Need to Know the Details

For this article, just remember:

Browser: runs V8 engine
Node.js: also runs V8 engine
Both execute the same JavaScript differently

The engine is the same. The environment is different.


Event-Driven Architecture

What is Event-Driven?

Instead of waiting for things to happen, Node.js listens for events and responds.

The Analogy

Synchronous (traditional servers):

A waiter takes your order, goes to the kitchen, waits for the food, comes back, goes to the next customer.

Event-Driven (Node.js):

A waiter takes your order, puts it in a queue, serves other customers, and comes back when your food is ready.

More efficient.

Example: Reading a File

Traditional approach (blocking):

// This makes the server WAIT
const data = fs.readFileSync("large-file.txt");
console.log(data);
// Server is blocked until file is read

Node.js approach (event-driven):

// This doesn't block the server
fs.readFile("large-file.txt", (err, data) => {
  console.log(data);
});
// Server continues handling other requests

Node.js doesn't wait. It does other things and comes back when the file is ready.

Why This Matters

One Node.js server can handle thousands of requests without blocking, because it doesn't wait for operations to finish.

Traditional Server (PHP/Java)
Request 1 → ⏳ waiting for database → Response
Request 2 → queued behind request 1
Request 3 → queued behind request 2

Node.js Server
Request 1 → database query (no wait)
Request 2 → database query (no wait)
Request 3 → database query (no wait)
Responses come back as each finishes

Much more efficient.


Node.js Runtime Architecture Overview

Node.js Runtime
  |
  ├─ V8 Engine
  |   └─ Executes JavaScript code
  |
  ├─ libuv (Library)
  |   ├─ Event loop
  |   ├─ Thread pool
  |   └─ Async I/O
  |
  ├─ Core Modules
  |   ├─ fs (files)
  |   ├─ http (server)
  |   ├─ os (system)
  |   └─ path (routing)
  |
  └─ npm (Package Manager)
      └─ Access to millions of libraries

The key: V8 executes your code, libuv handles async operations.


Real-World Use Cases of Node.js

1. Web Servers

const http = require("http");

const server = http.createServer((req, res) => {
  res.write("Hello World");
  res.end();
});

server.listen(3000);

Build APIs and websites. Simple and fast.

2. Real-Time Applications

Companies like Slack, Discord, Trello use Node.js for real-time features.

// WebSocket: real-time communication
socket.on("message", (data) => {
  broadcast(data);  // Send to all users instantly
});

Event-driven architecture is perfect for real-time.

3. Building CLI Tools

Create command-line tools for developers:

// npm, ESLint, Webpack, Prettier are all Node.js tools
const args = process.argv;
console.log("Arguments:", args);

4. Data Processing & Streaming

Process large files without loading everything into memory:

const fs = require("fs");

fs.createReadStream("huge-file.csv")
  .pipe(processStream)
  .pipe(fs.createWriteStream("output.csv"));

Handle terabytes of data efficiently.

5. IoT & Embedded Systems

Node.js runs on Raspberry Pi and IoT devices.

// Read sensor data
const sensorData = getSensorReading();
sendToCloud(sensorData);

6. Building Microservices

Netflix, LinkedIn, and Uber use Node.js for microservices.

// Small, focused services
app.post("/users", createUser);
app.get("/users/:id", getUser);
app.delete("/users/:id", deleteUser);

Each service is independent. Easy to scale.


Node.js vs Traditional Backend Languages

JavaScript (Node.js)

Pros: One language for frontend and backend, event-driven and non-blocking, fast to write, perfect for real-time apps.

Cons: Single-threaded (traditionally), less suitable for CPU-intensive tasks.

PHP

Pros: Easy to learn, great for beginners.

Cons: Blocks per request (slower), no real-time support, poor for modern apps.

Java

Pros: Fast compiled language, mature ecosystem, good for enterprise.

Cons: Verbose and slow to write, requires more resources, steeper learning curve.

Python

Pros: Easy to read, great for AI and data science, large ecosystem.

Cons: Slow (interpreted), not ideal for real-time, multiple competing frameworks.

Node.js Sweet Spot

Real-Time Apps     ← Node.js wins
APIs & Servers     ← Node.js wins
CLI Tools          ← Node.js wins
Microservices      ← Node.js wins
Data Processing    ← Node.js strong

CPU-Intensive Work ← Java/Python better
Enterprise Systems ← Java better

Node.js excels at I/O-intensive applications (network, database, file operations). It's less ideal for CPU-intensive work (heavy calculations, image processing).


Why Developers Adopted Node.js

The Three Reasons

1. One Language Everywhere

// Frontend
const user = { name: "Alice" };
document.getElementById("name").textContent = user.name;

// Backend (same JavaScript!)
const user = { name: "Alice" };
res.json(user);

Frontend developers could now write backend code without learning Java or PHP.

2. Non-Blocking, Event-Driven

One Node.js server can handle more requests than one PHP server because it doesn't block on I/O operations.

3. Perfect for Modern Apps

  • Real-time features (chat, notifications)
  • Microservices architecture
  • Mobile APIs
  • WebSockets
  • Streaming data

Node.js was designed for these use cases.

The Tipping Point (2012-2015)

npm grew. Libraries exploded. Companies started using Node.js in production.

Today, Node.js powers thousands of companies.


Browser JS vs Server JS: Execution Comparison

Browser Execution
  |
  ├─ User opens website
  ├─ Browser downloads HTML + JavaScript
  ├─ V8 engine parses JavaScript
  ├─ DOM is built
  ├─ User interacts (click, type)
  ├─ JavaScript responds to events
  └─ Page updates, render

Node.js Execution
  |
  ├─ Developer starts server
  ├─ Node.js loads JavaScript files
  ├─ V8 engine parses JavaScript
  ├─ Server starts listening for requests
  ├─ Client sends HTTP request
  ├─ JavaScript handles request
  ├─ Database query runs (non-blocking)
  ├─ Response is sent back
  └─ Server continues listening

Same engine (V8). Different triggers and APIs.


Simple Node.js Server Example

const http = require("http");

// Create server
const server = http.createServer((req, res) => {
  // req = incoming request
  // res = response to send
  
  if (req.url === "/") {
    res.writeHead(200);
    res.write("Welcome to Node.js!");
    res.end();
  } else if (req.url === "/about") {
    res.writeHead(200);
    res.write("This is the about page");
    res.end();
  } else {
    res.writeHead(404);
    res.write("Page not found");
    res.end();
  }
});

// Listen on port 3000
server.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

Run it:

node server.js
# Server running on http://localhost:3000

Visit http://localhost:3000 in your browser. You'll see "Welcome to Node.js!"


Key Differences Summarized

Aspect Browser JS Node.js
Engine V8 (same) V8 (same)
APIs DOM, document, window fs, http, os
Use Case User interaction Server operations
Lifespan Page load to close Runs indefinitely
Access Can't touch disk Full disk/network access
Blocking Some (user doesn't mind) Should be non-blocking
Modules script tags require() / import

Practice Assignment

1. Understand the difference:

// Why does this work in Browser but NOT in Node.js?
document.getElementById("button");

// Why does this work in Node.js but NOT in Browser?
fs.readFileSync("/etc/passwd");

2. Create a simple server:

// Create an http server
// Listen on port 3000
// Respond with "Hello Node.js"
// Test with curl or browser

3. Explore the event-driven model:

// Use fs.readFile (async, non-blocking)
// Use a callback function
// Console.log the file contents
// Understand why it doesn't block

4. Build a multi-route server:

// Create routes for:
// GET / → "Home"
// GET /about → "About page"
// GET /users → "Users list"
// GET /404 → "Not found"
// Test each route

Quick Recap

  • Node.js is a runtime that executes JavaScript outside the browser.
  • JavaScript was browser-only because it was designed for user interactions and DOM manipulation.
  • Node.js uses the same V8 engine as Chrome but with different APIs for server tasks.
  • Runtime is the environment where code runs; programming language is the syntax.
  • Node.js has no DOM, document, or window objects because it runs on servers, not browsers.
  • V8 is Google's JavaScript engine that compiles JS to machine code.
  • Node.js uses event-driven, non-blocking I/O to handle thousands of concurrent requests efficiently.
  • libuv handles the event loop and async operations behind the scenes.
  • Node.js excels at I/O-intensive applications: APIs, real-time apps, microservices, CLI tools.
  • Node.js is not ideal for CPU-intensive work (use Python or Java instead).
  • Browser JS responds to user events (clicks); Server JS responds to network events (requests).
  • One language for frontend and backend is Node.js's killer feature.

Node.js turned JavaScript into a full-stack language.


If you enjoyed this article, check out my other blogs on this profile. Connect with me: LinkedIn | GitHub | X (Twitter)