Skip to main content
Node.js & Express·Lesson 1 of 5

Node.js Basics

Node.js is a JavaScript runtime built on Chrome's V8 engine. It lets you run JavaScript outside the browser, making it possible to build servers, command-line tools, and backend services with the same language you use on the frontend.

What Makes Node.js Different

In the browser, JavaScript has access to the DOM, window, and fetch. In Node.js, those do not exist. Instead, you get access to the file system, network, operating system, and other server-side APIs.

FeatureBrowserNode.js
DOM accessYesNo
File systemNoYes (fs module)
HTTP serverNoYes (http module)
window objectYesNo (global instead)
Module systemES ModulesCommonJS + ES Modules
Package managerN/Anpm, pnpm, yarn

Installing Node.js

Download the LTS version from nodejs.org. Verify the installation:

node --version   # e.g., v22.0.0
npm --version    # e.g., 10.0.0

Running JavaScript Files

Create a file called app.js:

const message = "Hello from Node.js!";
console.log(message);
console.log(`Running on ${process.platform}`);
console.log(`Node version: ${process.version}`);

Run it:

node app.js

The Module System

Node.js uses CommonJS modules by default. Each file is its own module.

Exporting from a Module

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

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

module.exports = { add, multiply };

Importing a Module

// app.js
const { add, multiply } = require("./math");

console.log(add(2, 3));      // 5
console.log(multiply(4, 5)); // 20

ES Modules in Node.js

You can use ES module syntax by either setting "type": "module" in package.json or using the .mjs extension:

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

// app.mjs
import { add } from "./math.mjs";
console.log(add(2, 3));

Built-in Modules

Node.js ships with many useful modules. No installation required.

fs — File System

const fs = require("fs");

// Read a file
const content = fs.readFileSync("data.txt", "utf-8");
console.log(content);

// Write a file
fs.writeFileSync("output.txt", "Hello, World!");

// Async version (preferred)
const fsPromises = require("fs/promises");

async function readConfig() {
  const data = await fsPromises.readFile("config.json", "utf-8");
  return JSON.parse(data);
}

path — File Paths

const path = require("path");

const filePath = path.join(__dirname, "data", "users.json");
console.log(filePath);
// e.g., /home/user/project/data/users.json

console.log(path.extname("photo.jpg"));  // ".jpg"
console.log(path.basename("/a/b/c.txt")); // "c.txt"

os — Operating System Info

const os = require("os");

console.log(os.platform());  // "linux", "darwin", "win32"
console.log(os.cpus().length); // number of CPU cores
console.log(os.totalmem());    // total memory in bytes
console.log(os.homedir());    // user's home directory

npm and Package Management

npm (Node Package Manager) manages third-party packages.

Initializing a Project

mkdir my-project && cd my-project
npm init -y

This creates a package.json file that tracks your project's dependencies and scripts.

Installing Packages

npm install express        # production dependency
npm install -D nodemon     # development dependency

package.json Scripts

{
  "name": "my-project",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "dependencies": {
    "express": "^4.18.0"
  },
  "devDependencies": {
    "nodemon": "^3.0.0"
  }
}

Run scripts with:

npm run dev
npm start

Environment Variables

Store configuration outside your code using environment variables.

// Access environment variables
const port = process.env.PORT || 3000;
const nodeEnv = process.env.NODE_ENV || "development";

console.log(`Server running on port ${port} in ${nodeEnv} mode`);

Use a .env file with the dotenv package:

npm install dotenv
# .env
PORT=4000
DATABASE_URL=mongodb://localhost:27017/myapp
SECRET_KEY=super-secret-value
require("dotenv").config();
console.log(process.env.DATABASE_URL);

Never commit .env files to version control. Add .env to your .gitignore.

Creating a Simple HTTP Server

Node.js can create servers without any framework:

const http = require("http");

const server = http.createServer((req, res) => {
  if (req.url === "/" && req.method === "GET") {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ message: "Hello, World!" }));
  } else if (req.url === "/health") {
    res.writeHead(200);
    res.end("OK");
  } else {
    res.writeHead(404);
    res.end("Not Found");
  }
});

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

This works but gets unwieldy fast. That is why frameworks like Express exist.

Practical Exercise

Build a file-based note-taking CLI tool:

const fs = require("fs/promises");
const path = require("path");

const NOTES_DIR = path.join(__dirname, "notes");

async function ensureDir() {
  try {
    await fs.mkdir(NOTES_DIR, { recursive: true });
  } catch {}
}

async function addNote(title, content) {
  await ensureDir();
  const filename = `${title.toLowerCase().replace(/\s+/g, "-")}.txt`;
  await fs.writeFile(path.join(NOTES_DIR, filename), content);
  console.log(`Note saved: ${filename}`);
}

async function listNotes() {
  await ensureDir();
  const files = await fs.readdir(NOTES_DIR);
  console.log("Your notes:");
  files.forEach((f) => console.log(`  - ${f}`));
}

const [, , command, ...args] = process.argv;

if (command === "add") {
  addNote(args[0], args.slice(1).join(" "));
} else if (command === "list") {
  listNotes();
} else {
  console.log("Usage: node notes.js add <title> <content>");
  console.log("       node notes.js list");
}

Key Takeaways

  • Node.js lets you run JavaScript on the server with access to the file system, network, and OS.
  • Use require (CommonJS) or import (ES Modules) to organize code into modules.
  • npm manages packages and project scripts through package.json.
  • Environment variables keep secrets and configuration out of your source code.
  • The built-in http module can create servers, but Express makes it much easier.