Week 10: Node.js Foundations

Unit IV - Server-Side JavaScript

JavaScript beyond the browser!

What You'll Learn

  • What is Node.js and why it matters
  • npm and package management
  • CommonJS and ES Modules
  • Building a server with Express.js
  • Event-driven architecture

Prerequisites

  • JavaScript fundamentals (Week 7-8)
  • Objects and JSON (Week 9)
  • Async/await understanding

Install Node.js from nodejs.org

Press → or click Next to continue

What is Node.js?

A JavaScript runtime built on Chrome's V8 engine for building server-side applications.

Key Features

  • V8 Engine: Same engine that powers Chrome, compiles JS to native machine code
  • Non-blocking I/O: Handles thousands of concurrent connections efficiently
  • Event-driven: Uses event loop instead of threads
  • Cross-platform: Windows, macOS, Linux
  • Single language: JavaScript on both client and server

Browser vs Node.js

BrowserNode.js
DOM accessFile system access
window objectglobal object
document objectprocess object
fetch / XMLHttpRequesthttp module
localStorageDatabase drivers
ES ModulesCommonJS + ES Modules

Check Installation

$ node --version     # v20.x.x or later
$ npm --version      # 10.x.x or later

Running Node.js

Two ways to execute JavaScript with Node.js.

REPL (Interactive)

$ node
Welcome to Node.js v20.x.x.

> 2 + 3
5

> const name = 'Node.js'
undefined

> console.log(`Hello ${name}!`)
Hello Node.js!

> process.version
'v20.x.x'

> .exit

REPL = Read-Eval-Print-Loop

Great for testing quick snippets!

Running Files

// app.js
console.log('Hello from Node.js!');

// Process information
console.log('Node version:', process.version);
console.log('Platform:', process.platform);
console.log('Current directory:', process.cwd());

// Command line arguments
console.log('Arguments:', process.argv);

// Environment variables
console.log('HOME:', process.env.HOME);

// Exit process
process.exit(0);  // 0 = success
$ node app.js
Hello from Node.js!
Node version: v20.x.x
Platform: darwin
...

npm - Node Package Manager

The world's largest software registry - over 2 million packages!

Initializing a Project

# Create package.json
$ npm init

# Quick init with defaults
$ npm init -y

# package.json
{
    "name": "my-project",
    "version": "1.0.0",
    "description": "My Node.js project",
    "main": "index.js",
    "scripts": {
        "start": "node index.js",
        "dev": "node --watch index.js",
        "test": "echo \"No tests yet\""
    },
    "keywords": [],
    "author": "Your Name",
    "license": "MIT"
}

Installing Packages

# Install a package (saves to dependencies)
$ npm install express
$ npm i express          # shorthand

# Install as dev dependency
$ npm install --save-dev nodemon
$ npm i -D nodemon       # shorthand

# Install globally
$ npm install -g nodemon

# Install specific version
$ npm install express@4.18.2

# Install all dependencies (from package.json)
$ npm install

# Remove a package
$ npm uninstall express

# Update packages
$ npm update

Never commit node_modules! Add it to .gitignore. Others run npm install to get dependencies.

Understanding package.json

Dependencies

{
    "dependencies": {
        "express": "^4.18.2",
        "cors": "^2.8.5"
    },
    "devDependencies": {
        "nodemon": "^3.0.1"
    }
}

// Versioning (Semantic Versioning)
// MAJOR.MINOR.PATCH
// ^4.18.2 - Compatible with 4.x.x
// ~4.18.2 - Compatible with 4.18.x
// 4.18.2  - Exact version only

package-lock.json

Locks exact versions for reproducible builds. Always commit this file!

npm Scripts

{
    "scripts": {
        "start": "node index.js",
        "dev": "nodemon index.js",
        "test": "jest",
        "build": "webpack",
        "lint": "eslint ."
    }
}

// Run scripts
$ npm start        // 'start' is special
$ npm test         // 'test' is special
$ npm run dev      // custom scripts need 'run'
$ npm run build
$ npm run lint

npx: Run packages without installing them

$ npx create-react-app my-app

CommonJS Modules

Node.js's original module system using require() and module.exports.

Exporting

// math.js

// Single export
function add(a, b) {
    return a + b;
}

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

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

// Or export individually
// module.exports.add = add;
// module.exports.subtract = subtract;

// Or export a single thing
// module.exports = add;

Importing

// app.js

// Import the module
const math = require('./math');

console.log(math.add(2, 3));      // 5
console.log(math.subtract(5, 2)); // 3

// Destructured import
const { add, subtract } = require('./math');
console.log(add(2, 3));           // 5

// Built-in modules (no path needed)
const fs = require('fs');
const path = require('path');
const http = require('http');

// npm packages (no path needed)
const express = require('express');

Module Resolution

require('./file')     // Relative path - local file
require('../lib/util') // Relative path - local file
require('express')    // node_modules folder
require('fs')         // Built-in Node.js module

ES Modules in Node.js

Modern module syntax using import and export.

Enabling ES Modules

// Option 1: Set in package.json
{
    "type": "module"
}

// Option 2: Use .mjs extension
// math.mjs, app.mjs

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

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

// Default export
export default class Calculator {
    // ...
}

Importing

// Named imports
import { add, subtract } from './math.js';

// Default import
import Calculator from './math.js';

// Import all as namespace
import * as math from './math.js';
math.add(2, 3);

// Import built-in modules
import fs from 'fs';
import { readFile } from 'fs/promises';

// Import npm packages
import express from 'express';

Note: Must include file extension (.js) in import paths with ES Modules!

Introduction to Express.js

The most popular Node.js web framework - minimal, flexible, and powerful.

Setup

# Create project
$ mkdir my-app && cd my-app
$ npm init -y
$ npm install express

# Project structure
my-app/
  node_modules/
  package.json
  package-lock.json
  index.js

Basic Server

// index.js
const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(PORT, () => {
    console.log(`Server running on
        http://localhost:${PORT}`);
});

Express Concepts

  • app: The Express application
  • Route: URL path + HTTP method
  • req: Request object (incoming data)
  • res: Response object (outgoing data)
  • Middleware: Functions that process requests

Response Methods

// Send text
res.send('Hello World');

// Send JSON
res.json({ message: 'Hello' });

// Send status code
res.status(404).send('Not Found');

// Send HTML
res.send('<h1>Hello</h1>');

// Redirect
res.redirect('/other-page');

// Send file
res.sendFile('/path/to/file.html');

Express Routing

Define how your application responds to different URLs and HTTP methods.

HTTP Methods

const express = require('express');
const app = express();

// Parse JSON body
app.use(express.json());

// GET - Read data
app.get('/api/users', (req, res) => {
    res.json(users);
});

// POST - Create data
app.post('/api/users', (req, res) => {
    const newUser = req.body;
    users.push(newUser);
    res.status(201).json(newUser);
});

// PUT - Update data
app.put('/api/users/:id', (req, res) => {
    const { id } = req.params;
    // update user...
    res.json(updatedUser);
});

// DELETE - Remove data
app.delete('/api/users/:id', (req, res) => {
    const { id } = req.params;
    // delete user...
    res.status(204).send();
});

Route Parameters

// URL parameters (in the path)
app.get('/users/:id', (req, res) => {
    console.log(req.params.id);  // '123'
});
// GET /users/123

// Query parameters (after ?)
app.get('/search', (req, res) => {
    console.log(req.query.q);     // 'node'
    console.log(req.query.page);  // '2'
});
// GET /search?q=node&page=2

// Request body (POST/PUT)
app.post('/users', (req, res) => {
    console.log(req.body.name);
    console.log(req.body.email);
});
// POST with JSON body

REST Convention

GET    /api/users     - List all
GET    /api/users/1   - Get one
POST   /api/users     - Create
PUT    /api/users/1   - Update
DELETE /api/users/1   - Delete

Middleware

Functions that execute during the request-response cycle.

What is Middleware?

// Middleware has access to req, res, and next
function logger(req, res, next) {
    console.log(`${req.method} ${req.url}`);
    next();  // Pass to next middleware
}

// Apply to ALL routes
app.use(logger);

// Apply to specific path
app.use('/api', logger);

// Built-in middleware
app.use(express.json());       // Parse JSON
app.use(express.urlencoded({   // Parse forms
    extended: true
}));
app.use(express.static('public')); // Serve files

Middleware Flow

// Request flows through middleware in order

app.use((req, res, next) => {
    console.log('1. First middleware');
    next();
});

app.use((req, res, next) => {
    console.log('2. Second middleware');
    next();
});

app.get('/', (req, res) => {
    console.log('3. Route handler');
    res.send('Done!');
});

// Output:
// 1. First middleware
// 2. Second middleware
// 3. Route handler

Popular Middleware: cors, helmet, morgan, body-parser, cookie-parser

Building a REST API

Complete CRUD example with Express.js.

const express = require('express');
const app = express();
app.use(express.json());

// In-memory data store
let todos = [
    { id: 1, text: 'Learn Node.js', completed: false },
    { id: 2, text: 'Build an API', completed: false }
];
let nextId = 3;

// GET all todos
app.get('/api/todos', (req, res) => {
    res.json(todos);
});

// GET single todo
app.get('/api/todos/:id', (req, res) => {
    const todo = todos.find(t => t.id === parseInt(req.params.id));
    if (!todo) return res.status(404).json({ error: 'Todo not found' });
    res.json(todo);
});

// POST create todo
app.post('/api/todos', (req, res) => {
    const { text } = req.body;
    if (!text) return res.status(400).json({ error: 'Text is required' });
    const todo = { id: nextId++, text, completed: false };
    todos.push(todo);
    res.status(201).json(todo);
});

// PUT update todo
app.put('/api/todos/:id', (req, res) => {
    const todo = todos.find(t => t.id === parseInt(req.params.id));
    if (!todo) return res.status(404).json({ error: 'Todo not found' });
    todo.text = req.body.text || todo.text;
    todo.completed = req.body.completed ?? todo.completed;
    res.json(todo);
});

// DELETE todo
app.delete('/api/todos/:id', (req, res) => {
    todos = todos.filter(t => t.id !== parseInt(req.params.id));
    res.status(204).send();
});

app.listen(3000, () => console.log('Server on http://localhost:3000'));

CampusKart Milestone: Backend Setup

Deliverable: Node.js project with package.json, modules, and basic server

What to Build

  • npm init — create package.json
  • Install packages: nodemon, cors, pg (Postgres)
  • Project structure: /server, /routes, /public
  • Utility modules: validators.js, helpers.js
  • Basic HTTP server: "CampusKart API v1.0"
  • Event system for notifications

The Wow Moment

"You're now a backend developer. The frontend you built talks to servers like the one you just created."

Push to GitHub — start the backend repo.

Video Resources

Frontend Masters

Intro to Node.js v3

Node.js Official

Node.js Documentation

Express.js

Express.js Guide

Practice Exercises

Exercise 1: Hello Server

  • Create Express server
  • Serve a home page
  • Add /about route

Exercise 2: Todo API

  • Full CRUD operations
  • Use JSON body parsing
  • Error handling

Exercise 3: Static Site

  • Serve HTML/CSS/JS files
  • Use express.static()
  • Multiple pages

Exercise 4: Middleware

  • Custom request logger
  • Auth middleware
  • Error handling middleware

Week 10 Summary

Key Concepts

  • Node.js runs JavaScript on the server
  • npm manages packages and scripts
  • CommonJS: require/module.exports
  • ES Modules: import/export
  • Express.js for web servers
  • REST API conventions
  • Middleware for request processing

Commands to Remember

node file.js        # Run a file
npm init -y         # Create project
npm install pkg     # Install package
npm run script      # Run script
npm start           # Start project

Next Week

Week 11: Node.js File System & HTTP!