Introduction to Node.js: A Comprehensive Beginner's Guide

Aug 15, 2024
8 min read
Nodejs JavaScript Backend Tutorial

Master the fundamentals of Node.js. Learn what makes Node.js unique, understand core concepts like the event loop and async programming, and build your first server.

Node.js has revolutionized server-side development by bringing JavaScript to the backend. Whether you're a frontend developer looking to expand your skills or a complete beginner exploring backend development, this comprehensive guide will give you a solid foundation in Node.js.

This is Part 1 of our Node.js series. Continue with Part 2: Building RESTful APIs and Part 3: Database Integration.


What is Node.js?

Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a web browser. Built on Chrome's V8 JavaScript engine, Node.js enables developers to use JavaScript for server-side scripting, creating dynamic web applications entirely in JavaScript.

Key Characteristics

  • JavaScript Everywhere: Use the same language for both frontend and backend
  • Event-Driven: Built around an event-driven, non-blocking I/O model
  • Single-Threaded: Uses a single thread with event looping
  • Cross-Platform: Runs on Windows, macOS, Linux, and more
  • NPM Ecosystem: Access to over 2 million packages

Why Use Node.js?

1. JavaScript Across the Full Stack

Before Node.js, developers typically used different languages for frontend (JavaScript) and backend (PHP, Python, Ruby, Java). Node.js unifies the development stack:

// Same language, different environments

// Frontend (Browser)
document.getElementById("button").addEventListener("click", handleClick);

// Backend (Node.js)
app.get("/api/users", handleRequest);

Benefits:

  • ✅ Reduced context switching between languages
  • ✅ Code sharing between client and server
  • ✅ Easier team collaboration
  • ✅ Faster onboarding for frontend developers

2. Exceptional Performance

Node.js leverages the V8 engine, which compiles JavaScript directly to machine code using Just-In-Time (JIT) compilation:

  • Fast execution - Comparable to compiled languages
  • Efficient memory usage - Optimized garbage collection
  • Low latency - Non-blocking I/O operations

3. Non-Blocking I/O Model

Node.js uses an event-driven, non-blocking architecture that makes it ideal for I/O-intensive applications.

4. Scalability

Node.js excels at handling concurrent connections with minimal overhead.


Core Concepts in Node.js

1. Asynchronous Programming

Node.js uses asynchronous programming to handle operations without blocking the main thread. This is crucial for building performant applications.

Example: Asynchronous File Reading

const fs = require("fs");

console.log("1. Start reading file...");

fs.readFile("example.txt", "utf8", (err, data) => {
  if (err) {
    console.error("Error reading file:", err);
    return;
  }
  console.log("3. File content:", data);
});

console.log("2. File reading initiated, continuing execution...");

// Output:
// 1. Start reading file...
// 2. File reading initiated, continuing execution...
// 3. File content: [file contents]

Key Takeaway: The program doesn't wait for the file to be read before moving to the next line. The callback function executes once the file reading completes.


2. The Event Loop

The event loop is the heart of Node.js. It's what enables Node.js to perform non-blocking operations despite JavaScript being single-threaded.

How It Works:

  1. Call Stack: Executes synchronous code
  2. Callback Queue: Holds completed async operations
  3. Event Loop: Moves callbacks from queue to call stack when stack is empty
console.log("Start");

setTimeout(() => {
  console.log("Timeout callback");
}, 0);

Promise.resolve().then(() => {
  console.log("Promise callback");
});

console.log("End");

// Output:
// Start
// End
// Promise callback
// Timeout callback

Important: Promises have higher priority than setTimeout in the event loop!


3. Modules and Module System

Node.js uses a module system to organize code into reusable components.

Creating a Module:

// math.js
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

function multiply(a, b) {
  return a * b;
}

// Export multiple functions
module.exports = { add, subtract, multiply };

// Or export individual functions
// exports.add = add;

Using the Module:

// main.js
const math = require("./math");

console.log(math.add(5, 3)); // 8
console.log(math.subtract(10, 4)); // 6
console.log(math.multiply(3, 7)); // 21

ES Modules (Modern Approach):

// math.mjs
export function add(a, b) {
  return a + b;
}

// main.mjs
import { add } from "./math.mjs";
console.log(add(5, 3)); // 8

4. NPM (Node Package Manager)

npm is the world's largest software registry with over 2 million packages.

Essential npm Commands:

# Initialize a new project
npm init -y

# Install a package
npm install express

# Install as dev dependency
npm install --save-dev nodemon

# Install globally
npm install -g typescript

# Update packages
npm update

# Remove a package
npm uninstall express

# List installed packages
npm list

Understanding package.json:

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "My Node.js application",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}

5. Creating an HTTP Server

Node.js makes it simple to create web servers with the built-in http module.

Basic HTTP Server:

const http = require("http");

const hostname = "127.0.0.1";
const port = 3000;

const server = http.createServer((req, res) => {
  // Set response headers
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");

  // Send response
  res.end("Hello, World!\n");
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Handling Different Routes:

const http = require("http");

const server = http.createServer((req, res) => {
  if (req.url === "/") {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end("<h1>Home Page</h1>");
  } else if (req.url === "/about") {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end("<h1>About Page</h1>");
  } else {
    res.writeHead(404, { "Content-Type": "text/html" });
    res.end("<h1>404 - Page Not Found</h1>");
  }
});

server.listen(3000, () => {
  console.log("Server listening on port 3000");
});

6. Introduction to Express.js

While the built-in http module works, Express.js makes building web applications much easier and more feature-rich.

Installing Express:

npm install express

Basic Express Server:

const express = require("express");
const app = express();
const port = 3000;

// Middleware to parse JSON
app.use(express.json());

// Routes
app.get("/", (req, res) => {
  res.send("Hello from Express!");
});

app.get("/api/users", (req, res) => {
  res.json([
    { id: 1, name: "Alice" },
    { id: 2, name: "Bob" },
  ]);
});

app.post("/api/users", (req, res) => {
  const user = req.body;
  res.status(201).json({ message: "User created", user });
});

app.listen(port, () => {
  console.log(`Express server running on port ${port}`);
});

Why Express?

  • ✅ Simple, minimalist framework
  • ✅ Robust routing
  • ✅ Middleware support
  • ✅ Template engine integration
  • ✅ Large ecosystem of plugins

When to Use Node.js?

Node.js is ideal for:

✅ Best Use Cases

  • Real-time Applications - Chat apps, live notifications, collaborative tools
  • RESTful APIs - Microservices and API servers
  • Single Page Applications (SPAs) - Server-side rendering with Next.js
  • Streaming Applications - Video/audio streaming platforms
  • IoT Applications - Managing device communications
  • Command Line Tools - Build tools and automation scripts

❌ Not Recommended For

  • CPU-Intensive Tasks - Video encoding, image processing (use Python, Go instead)
  • Heavy Computational Work - Machine learning, scientific computing
  • Applications Requiring Threads - Use languages with better threading support

Getting Started: Your First Project

Step 1: Install Node.js

Download and install from nodejs.org

Verify installation:

node --version   # v20.10.0
npm --version    # 10.2.3

Step 2: Create Your First Application

// app.js
const http = require("http");

const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("My First Node.js Server!");
});

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

Run it:

node app.js

Open http://localhost:3000 in your browser!


Practice Exercises

Exercise 1: Async File Operations

Create a program that reads multiple files asynchronously and logs their content:

const fs = require("fs");

const files = ["file1.txt", "file2.txt", "file3.txt"];

files.forEach((file) => {
  fs.readFile(file, "utf8", (err, data) => {
    if (err) {
      console.error(`Error reading ${file}:`, err);
      return;
    }
    console.log(`Content of ${file}:`, data);
  });
});

Exercise 2: Simple Calculator Module

Create a calculator module and use it in your main file.

Exercise 3: JSON API Server

Build a server that responds with JSON data for different endpoints.


Next Steps

Now that you understand Node.js fundamentals, continue your learning journey:

  1. Part 2: Building RESTful APIs - Learn to build complete CRUD APIs with Express
  2. Part 3: Database Integration - Connect Node.js to MySQL database
  3. Explore npm - Browse npmjs.com for useful packages
  4. Build Projects - Apply what you've learned in real projects

Additional Resources


Let's Connect

Have questions about Node.js? Let's discuss!

Happy coding! 🚀