Web Development Tutorial

Node.js Introduction: What Is Node.js, How It Works And Your First Program (2026-27)

By Pramod Behera  ·  Updated: July 2026  ·  18 min read
✅ In this Web Technologies Tutorial - Node.js Introduction: What Node.js Is, How It Works And Your First Program

Today we are going to discuss Node.js. If you've already worked through our JavaScript Tutorial series, this is the natural next step: taking the same language you use in the browser and running it directly on a server or your local machine. In this guide we cover what Node.js actually is, the event loop and non-blocking architecture that make it fast, how it compares to traditional server-side technologies, npm and the module system, streams, real-world use cases, and a practical best-practices checklist. This tutorial finishes with an interactive code playground, a quiz, and an FAQ.

📋 Table of Contents

  1. What Is Node.js?
  2. History and Origin of Node.js
  3. Node.js Architecture Explained
  4. Understanding the Event Loop
  5. Blocking vs. Non-Blocking Code
  6. Key Features of Node.js
  7. Node.js vs. Traditional Server-Side Technologies
  8. Installing Node.js
  9. Your First Node.js Program
  10. Understanding npm
  11. Node.js Modules Explained
  12. Streams and the EventEmitter Pattern
  13. Real-World Use Cases
  14. Node.js and SAP
  15. Best Practices Checklist
  16. Quick Reference Table
  17. Try It Yourself: Code Playground
  18. Practice Quiz
  19. Frequently Asked Questions (FAQ)

✅ What Is Node.js?

Node.js is an open-source, cross-platform JavaScript runtime environment that allows developers to run JavaScript code outside of a web browser. Before Node.js existed, JavaScript was almost exclusively a browser language - it lived inside <script> tags, manipulated web pages, and had no real way to talk to a file system, a database, or a network socket directly. Node.js changed that completely by taking Google Chrome's V8 JavaScript engine and embedding it inside a standalone program that can run on a server, a desktop, or even a Raspberry Pi.

In simple terms, Node.js lets you use the same language - JavaScript - to build both the front end of a website (what runs in the browser) and the back end (what runs on the server). This single fact is one of the biggest reasons Node.js became so popular: a JavaScript developer no longer needs to learn a completely separate language like Java, PHP, or C# just to build server-side logic.

ℹ️ Quick definition: Node.js is not a framework and not a programming language. It is a runtime environment - a program that provides the engine and supporting libraries needed to execute JavaScript code on a machine that doesn't have a web browser.

Node.js is built on three core pillars:

⚙️ V8 Engine

Google's high-performance JavaScript and WebAssembly engine, originally built for Chrome, which compiles JavaScript directly into machine code rather than interpreting it line by line.

🔗 libuv

A C library that gives Node.js access to the underlying operating system's file system, networking, and concurrency features, and provides the event loop itself.

📦 Core Modules

A set of built-in JavaScript modules - like http, fs, and path - that provide ready-to-use functionality without needing any external installation.

It's worth being clear about what Node.js is not, since this trips up a lot of newcomers. Node.js is not a web framework - frameworks like Express, Fastify, or NestJS are built on top of Node.js to make certain tasks, like routing HTTP requests, easier. Node.js is also not a database, and not a replacement for the browser; it simply provides the environment and low-level building blocks that these higher-level tools rely on.

✅ History and Origin of Node.js

Node.js was created by Ryan Dahl and first released in 2009. At the time, most web servers handled concurrent users using a thread-per-connection or process-per-connection model - Apache, for example, would often spin up a new thread for every incoming request. This worked, but it did not scale well when thousands of users tried to connect at once, because each thread consumes memory and CPU time even when it is simply waiting for a slow database query or file read to finish.

Dahl's key insight was that most of the time a web server spends handling a request is actually spent waiting - waiting for a database, waiting for a file, waiting for another network service to respond. Instead of creating a new thread for every connection, a single thread could juggle thousands of connections by switching to other work whenever one operation was waiting on I/O (input/output), and coming back to it only when the result was ready.

💡 Key idea: JavaScript turned out to be a perfect fit for this model because it already had strong support for callback functions and an event-driven programming style from years of running in web browsers, reacting to clicks, timers, and network responses.

Since then, Node.js has grown enormously. It is now maintained by the OpenJS Foundation, has millions of published packages available through npm, and is used by companies including Netflix, PayPal, LinkedIn, Uber, and Walmart for parts of their production infrastructure.

✅ Node.js Architecture Explained

To really understand Node.js, it helps to compare it with a traditional multi-threaded server. In a traditional model, every request typically gets its own thread. If you have 10,000 simultaneous connections, you might end up with 10,000 threads, each consuming its own stack memory, with the operating system spending significant effort switching between them.

Node.js instead uses a single-threaded event loop for executing your JavaScript code, combined with a background thread pool (managed by libuv) for operations that are genuinely expensive, like reading large files or certain cryptographic calculations. Here is the general flow:

This design means a single Node.js process can comfortably handle thousands of concurrent connections without creating thousands of threads, as long as the workload is I/O-heavy (network calls, file access, database queries) rather than CPU-heavy (complex mathematical computation, image processing, video encoding).

✅ Understanding the Event Loop

The event loop is the heart of Node.js and is often the most confusing concept for beginners. Think of it as a continuously spinning manager that asks one question over and over: "Is there anything ready to be executed right now?"

The event loop moves through several phases on every cycle (often called a "tick"):

PhaseWhat Happens
TimersExecutes callbacks scheduled by setTimeout() and setInterval() whose time has elapsed.
Pending CallbacksExecutes I/O callbacks deferred from the previous cycle.
PollRetrieves new I/O events and executes their callbacks; most of the work happens here.
CheckExecutes callbacks scheduled with setImmediate().
Close CallbacksHandles cleanup events, like a closed socket.

What makes this powerful is that your JavaScript code never has to manually manage threads, locks, or synchronization. You simply write functions that say "when this operation finishes, do this," and the event loop guarantees they will run at the right time, on the same thread, one at a time, without race conditions between your own JavaScript callbacks.

⚠️ Important nuance: Node.js is single-threaded for your JavaScript, but it is not single-threaded overall. Behind the scenes, libuv maintains a thread pool (four threads by default) for operations such as file system access, DNS lookups, and some cryptography functions, so heavy I/O work does not block the main thread.

✅ Blocking vs. Non-Blocking Code

The difference between blocking and non-blocking code is easiest to understand by comparing two versions of the same task: reading a file from disk. In a blocking (synchronous) approach, the program stops everything else until the read finishes:

// Blocking (synchronous) file read
const fs = require('fs');
const data = fs.readFileSync('notes.txt', 'utf8');
console.log(data);
console.log('This line waits until the file is fully read.');

Now compare it with the non-blocking (asynchronous) version, which is the style Node.js encourages:

// Non-blocking (asynchronous) file read
const fs = require('fs');
fs.readFile('notes.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});
console.log('This line runs immediately, without waiting for the file.');

In the second example, the final console.log statement will almost always print before the file contents, because Node.js does not pause execution while the disk read happens in the background. Once the file read finishes, the callback function you supplied is placed into the event loop's queue and executed as soon as the main thread is free.

Modern Node.js code often expresses this same idea using Promises and async/await, which reads almost like synchronous code while still being fully non-blocking underneath:

const fs = require('fs/promises');

async function readNotes() {
  const data = await fs.readFile('notes.txt', 'utf8');
  console.log(data);
}

readNotes();
console.log('Still runs first, just like before.');

async/await does not change how Node.js actually executes code behind the scenes; it simply gives developers a cleaner, more readable way to write asynchronous logic without deeply nested callback functions - a pattern earlier Node.js code was often criticized for and that developers nicknamed "callback hell."

✅ Key Features of Node.js

Async & Non-Blocking
Almost every core API is asynchronous by default, so slow operations never freeze the whole app.
🧩
One Language End-to-End
The same JavaScript runs on the browser and the server, so code and logic can be shared.
🚀
Fast via V8
JavaScript is compiled to native machine code, giving strong performance for I/O-bound work.
📦
Huge npm Ecosystem
Well over a million packages mean most common functionality already exists as a library.
🖥️
Cross-Platform
The same code runs unmodified on Windows, macOS, and Linux.
📈
Scalable
Apps scale horizontally across machines or across CPU cores using the built-in cluster module.

✅ Node.js vs. Traditional Server-Side Technologies

A common question for beginners is how Node.js compares to server-side technologies like PHP, Java, or Python-based frameworks. The honest answer is that there is no universally "best" choice - each is suited to different situations.

AspectNode.js
Concurrency modelSingle-threaded event loop with async I/O, versus one thread/process per request in many traditional servers.
Best suited forI/O-heavy apps - APIs, real-time apps, streaming - more than raw CPU-heavy computation.
LanguageJavaScript on both client and server, rather than a separate back-end language.
Learning curve for JS devsLow - same language, new environment.
Package ecosystemnpm - very large and JavaScript-focused.

In practice, Node.js tends to shine in scenarios involving many simultaneous, relatively lightweight connections - chat applications, live dashboards, streaming services, and REST or GraphQL APIs - while CPU-intensive tasks such as heavy image processing are often better handled by offloading to worker threads or a separate service, even within a Node.js-based system.

✅ Installing Node.js

Getting Node.js running on your machine takes only a few minutes:

// Check the installed Node.js version
node -v

// Check the installed npm version
npm -v

If both commands print version numbers instead of an error, Node.js is successfully installed and you are ready to run your first program.

💡 Tip: If you need to switch between multiple Node.js versions on the same machine for different projects, install a version manager such as nvm (Node Version Manager) rather than reinstalling Node.js repeatedly.

✅ Your First Node.js Program

Let's write the traditional "Hello World" program, then go one step further and build a tiny web server - the single most common thing beginners want to see Node.js do.

Hello World

Create a new file called app.js and add the following line:

console.log("Hello, Node.js!");

Now run it from your terminal, in the same folder as the file:

node app.js

You should see Hello, Node.js! printed directly in your terminal. Notice there is no browser involved at all - this is JavaScript running directly on your machine.

A Minimal Web Server

Node.js includes a built-in http module that lets you create a fully functional web server in just a handful of lines, with no external framework required:

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello from my first Node.js server!');
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

Save this as server.js and run node server.js. Open a browser and navigate to http://localhost:3000/, and you will see the text response rendered on the page. This tiny script demonstrates the essence of Node.js: it imported a core module, defined a callback to handle each incoming request, and started listening for connections - all without installing any third-party library.

✅ Understanding npm

npm, short for Node Package Manager, is installed automatically alongside Node.js and serves two purposes: it is a command-line tool for installing and managing packages, and it is also the name of the world's largest software registry, hosting well over a million open-source JavaScript packages.

Initializing a Project

npm init -y

This command creates a package.json file, which acts as the manifest for your project - it records the project name, version, dependencies, and scripts.

Installing a Package

npm install express

This downloads the popular Express.js framework into a local node_modules folder and records it as a dependency inside package.json, so anyone else who clones your project can run npm install and get the exact same dependencies.

Running Scripts

Developers commonly define custom commands inside the scripts section of package.json, such as npm start or npm test, which makes it easy for anyone on a team to run the project the same way regardless of the underlying commands involved.

✅ Node.js Modules Explained

Node.js organizes code into modules, which keeps applications maintainable as they grow. There are three categories of modules you will encounter:

🧱 Core Modules

Built directly into Node.js and always available without installation - such as fs (file system), http (web servers and clients), path (file path utilities), and events (custom event emitters).

📁 Local Modules

Files you create yourself within your project and import using a relative path, like ./math.js.

🌍 Third-Party Modules

Packages installed via npm and published by the community, such as Express, Axios, or Mongoose.

Here is a simple example of creating and using a local module:

// math.js — a local module
function add(a, b) {
  return a + b;
}
module.exports = { add };

// app.js — using the local module
const math = require('./math');
console.log(math.add(5, 7)); // 12

Newer versions of Node.js also support ECMAScript Modules (ESM) using import and export syntax - the same module syntax used in modern front-end JavaScript, further reinforcing Node.js's "one language everywhere" philosophy.

✅ Streams and the EventEmitter Pattern

Two concepts appear throughout almost every serious Node.js application: streams and the EventEmitter pattern. Understanding them early makes the rest of the ecosystem, including popular frameworks, much easier to follow.

Streams

A stream is a way of handling data piece by piece rather than loading it all into memory at once. Imagine reading a two-gigabyte video file - loading the entire file into memory before processing it would be slow and could easily exhaust available memory. Instead, Node.js streams let you read (or write) data in small chunks, processing each chunk as it arrives.

const fs = require('fs');

const readStream = fs.createReadStream('largefile.txt', 'utf8');

readStream.on('data', (chunk) => {
  console.log(`Received ${chunk.length} characters.`);
});

readStream.on('end', () => {
  console.log('Finished reading the file.');
});

There are four main types of streams in Node.js: Readable (a source of data, like reading a file), Writable (a destination for data, like writing to a file), Duplex (both readable and writable, like a network socket), and Transform (a duplex stream that modifies data as it passes through, such as a compression utility). Streams are memory-efficient and underpin the built-in HTTP module's handling of request and response bodies.

The EventEmitter Pattern

Node.js is fundamentally event-driven, and the events core module exposes the EventEmitter class that powers this behavior throughout the platform - streams, HTTP servers, and countless third-party libraries all extend or use EventEmitter internally.

const EventEmitter = require('events');
const orderEvents = new EventEmitter();

orderEvents.on('orderPlaced', (order) => {
  console.log(`New order received: ${order.id}`);
});

orderEvents.emit('orderPlaced', { id: 'ORD-1001' });

This pattern - defining named events, listening for them with .on(), and triggering them with .emit() - is one of the clearest illustrations of why Node.js feels natural to JavaScript developers coming from the browser, where listening for events like clicks and key presses is already second nature.

✅ Real-World Use Cases

🔌 REST and GraphQL APIs

Node.js is an extremely common choice for building the backend API layer that mobile apps and single-page web apps consume.

💬 Real-Time Applications

Chat applications, live notifications, and collaborative tools rely heavily on Node.js paired with WebSockets for instant, bidirectional communication.

🎬 Streaming Services

Node.js's stream-based architecture makes it well suited to handling continuous data, such as video or audio streaming.

🧩 Microservices

Many companies break large applications into small, independently deployable Node.js services that communicate over lightweight protocols.

🛠️ Command-Line Tools

Many popular developer tools, including build tools and scaffolding generators, are themselves written in Node.js.

✅ Node.js and SAP

ℹ️ How Node.js connects to the SAP world: For readers coming from an SAP background, Node.js is increasingly relevant because SAP has embraced JavaScript as part of its modern development strategy. The SAP Cloud Application Programming Model (CAP) uses Node.js as one of its two primary runtime options - alongside Java - for building cloud-native business applications on SAP Business Technology Platform (BTP).

Node.js is also commonly used to build middleware layers that connect SAP systems to external web applications, mobile apps, or third-party services - for example, exposing SAP OData services through a lightweight Node.js API layer. For an SAP consultant learning to code, Node.js is often a practical entry point into full-stack development because SAP's own cloud tooling documentation and SAP Business Application Studio both support it natively.

✅ Node.js Best Practices Checklist

// Reading an environment variable safely
const port = process.env.PORT || 3000;
console.log(`Server will run on port ${port}`);

✅ Node.js - Quick Reference Table

TermOne-Line Meaning
Node.jsA JavaScript runtime environment for running JS outside the browser.
V8Google's engine that compiles JavaScript into machine code.
libuvC library providing the event loop and async I/O access.
Event LoopThe mechanism that executes callbacks when the main thread is free.
npmNode Package Manager - installs and manages JavaScript packages.
package.jsonThe manifest file describing a project's dependencies and scripts.
Core ModuleBuilt-in Node.js functionality, like fs or http.
StreamA way of processing data piece by piece instead of all at once.
EventEmitterThe core class powering Node.js's event-driven design.

✅ Try It Yourself: Code Game Playground

Edit the JavaScript below and click "Run" to see simulated console output. This demonstrates basic JavaScript concepts you would run identically inside Node.js using node yourfile.js.


Output will appear here...

✅ Practice - Yes / No Quiz

1. Is Node.js a programming language?

2. Does Node.js run JavaScript using the V8 engine?

3. Should CPU-intensive computation run directly on Node.js's main thread as best practice?

4. Is npm installed automatically alongside Node.js?

5. Does the asynchronous version of fs.readFile block later lines of code from running?

0/5
Your Score - Keep Practising! 🎯

✅ Frequently Asked Questions (FAQ)

Is Node.js a programming language?
No. Node.js is not a programming language; it is a runtime environment that lets JavaScript run outside a web browser, on a server or a local machine.
Is Node.js single-threaded?
Node.js runs your JavaScript code on a single main thread, but it uses a background thread pool through libuv for certain operations, which is why it can still handle many concurrent tasks efficiently.
What is npm in Node.js?
npm stands for Node Package Manager. It installs, manages, and shares reusable JavaScript packages, and it is installed automatically when you install Node.js.
Can Node.js be used for frontend development?
Node.js itself runs on the server side, but it powers the build tools, bundlers, and package managers used in almost all modern frontend development workflows.
Is Node.js good for beginners?
Yes. If you already know basic JavaScript, Node.js is a natural next step because it uses the same language on the server side, so there is no new syntax to learn.
✍️ About the Author - Pramod Behera

Pramod Behera is the founder of LearnToSAP.com and an experienced technology educator. He creates beginner-friendly tutorials spanning SAP modules, web development, and Cyber Security, helping thousands of learners worldwide build practical, job-ready skills.