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
| Browser | Node.js |
|---|---|
| DOM access | File system access |
| window object | global object |
| document object | process object |
| fetch / XMLHttpRequest | http module |
| localStorage | Database drivers |
| ES Modules | CommonJS + 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
Node.js Official
Express.js
npm
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!