OrgPad logo

Mindmap-2-Real-Apps.canvas

Created by Mahmood Damra

Mindmap-2-Real-Apps.canvas

rem vs em vs px

px = fixed, doesn't scale rem = relative to html font-size (16px default) em = relative to parent (compounds! ⚠️)

Rule of thumb: • Font sizes: rem • Padding/margins: rem or em • Widths: % or fr • Never: px for fonts

html { font-size: 16px; }
h1 { font-size: 2.5rem; } /* 40px */
p { font-size: 1rem; } /* 16px */
.container { max-width: 75rem; } /* 1200px */

Use Case: Scalable, accessible typography and spacing.

Flexbox for Responsive Layouts

Flexbox shines on mobile-first designs.

flex-direction: column on mobile → row on desktop. flex-wrap: wrap lets items flow to next line. gap replaces margin hacks between items.

Combine with media queries for full control.

.cards {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 300px; /* grow, shrink, min-width */
}
@media (max-width: 640px) {
.cards { flex-direction: column; }
}

Use Case: Card grids, navigation that stacks on mobile.

clamp(), min(), max()

CSS functions for fluid responsive values.

clamp(min, preferred, max) — stays within bounds. min(a, b) — picks the smaller value. max(a, b) — picks the larger value.

No media queries needed!

/* Fluid font: 1.2rem min, scales with vw, 3rem max */
h1 { font-size: clamp(1.2rem, 4vw, 3rem); }

/* Container: 90% of viewport but max 1200px */
.container { width: min(90%, 75rem); margin: auto; }

/* At least 300px wide */
.sidebar { width: max(300px, 25%); }

Use Case: Fluid typography, responsive containers without breakpoints.

Dark Mode & Color Systems

Dark mode is expected in modern design.

Use CSS custom properties for theming:

:root {
--bg-primary: #ffffff;
--text-primary: #1a1a2e;
--accent: #3b82f6;
}
[data-theme='dark'] {
--bg-primary: #0f172a;
--text-primary: #e2e8f0;
--accent: #60a5fa;
}
body {
background: var(--bg-primary);
color: var(--text-primary);
}

Color systems: • Use HSL for easy manipulation • 60-30-10 rule: dominant, secondary, accent • Semantic names: --color-success, --color-error • Check contrast ratios in both themes!

Use Case: Professional apps with theme switching.

Layout Patterns & Spacing

Consistent spacing = professional look.

Use a spacing scale (4px-based or 8px-based): 4, 8, 12, 16, 24, 32, 48, 64, 96

Common layout patterns:Sidebar + Maingrid: 250px 1frHoly Grail — header, sidebar, main, footer • Card Gridauto-fit, minmax(280px, 1fr)Split Screengrid: 1fr 1frStack — flex column with consistent gap

:root {
--space-xs: 0.25rem; --space-sm: 0.5rem;
--space-md: 1rem; --space-lg: 1.5rem;
--space-xl: 2rem; --space-2xl: 3rem;
}
.stack > * + * { margin-top: var(--space-md); }

Use Case: Consistent, scalable design systems.

Viewport Units & max-width

vw = 1% of viewport width vh = 1% of viewport height min(), max(), clamp() — responsive without media queries!

max-width prevents elements from growing too large. min-width prevents too small.

.hero { min-height: 100vh; }
.container { width: min(90%, 1200px); margin: auto; }
.title { font-size: clamp(1.5rem, 4vw, 3rem); }

Use Case: Full-screen heroes, fluid typography, responsive containers.

Color & Visual Hierarchy

Color palette — 1 primary, 1 accent, neutrals. 60-30-10 rule: 60% neutral, 30% primary, 10% accent.

Visual hierarchy — order in which eyes scan the page. Use size, color, position, contrast to control it.

Z-pattern (landing pages) or F-pattern (text-heavy pages).

Use Case: Making designs that look cohesive and guide user attention.

Writing Media Queries

Mobile-first: base styles = mobile. @media (min-width: 768px) = tablet and up.

Can combine: @media (min-width: 768px) and (max-width: 1023px)

viewport meta tag is REQUIRED for mobile: <meta name='viewport' content='width=device-width, initial-scale=1'>

/* Mobile first (default) */
.grid { display: flex; flex-direction: column; }

/* Tablet */
@media (min-width: 768px) {
.grid { flex-direction: row; flex-wrap: wrap; }
}

/* Desktop */
@media (min-width: 1024px) {
.grid { max-width: 1200px; margin: auto; }
}

Use Case: Making layouts adapt from phone to desktop.

Responsive Images

Images must adapt to screen sizes.

max-width: 100% — image never exceeds container. height: auto — maintain aspect ratio. object-fit: cover — fill container, crop if needed. object-fit: contain — fit inside, no crop.

<picture> element for art direction. srcset for resolution switching.

img { max-width: 100%; height: auto; }
.hero-img { object-fit: cover; width: 100%; height: 50vh; }
<picture>
<source media='(min-width: 768px)' srcset='large.webp' />
<img src='small.webp' alt='Hero' />
</picture>

Use Case: Fast-loading, crisp images on all devices.

Contrast, Scale & Typography

Contrast — make important elements stand out. Size, color, weight, position all create contrast.

Scale — create visual hierarchy with size. Big = important, small = secondary.

Typography — font choice sets the tone. Max 2-3 fonts. Pair serif + sans-serif.

Use Case: Creating designs that guide the user's eye naturally.

Mobile Navigation Pattern

Hamburger menu on mobile, full nav on desktop.

Hide nav links by default on mobile. Toggle with JS classList.toggle('open'). Use display:nonedisplay:flex in media queries.

.nav-links { display: none; flex-direction: column; }
.nav-links.open { display: flex; }
.hamburger { display: block; cursor: pointer; }

@media (min-width: 768px) {
.nav-links { display: flex; flex-direction: row; }
.hamburger { display: none; }
}
hamburger.addEventListener('click', () => {
navLinks.classList.toggle('open');
});

Use Case: Every mobile-responsive website needs this.

White Space & Alignment

White space (negative space) lets content breathe. More white space = more premium feel.

Alignment creates visual order. Align elements to a grid or shared edges. Misalignment looks unprofessional.

Less clutter = better UX.

Use Case: The difference between amateur and professional design.

Responsive Units

Relative units are key to fluid design.

px is fixed. Avoid for containers and typography. rem = relative to root font-size (good for accessibility). % = relative to parent container. vw / vh = 1% of viewport width / height.

html { font-size: 16px; }

h1 { font-size: 2rem; } /* 32px, scales if user zooms */
.hero { height: 100vh; } /* fills entire screen height */
.sidebar { width: 25%; } /* 25% of its parent div */

Use Case: Typography that scales, layouts that adapt to ANY screen.

Media Queries

Apply CSS rules at specific screen sizes.

Mobile-first: start with mobile styles, add complexity for larger screens with min-width.

Common breakpoints: • 640px (small) • 768px (tablet) • 1024px (laptop) • 1280px (desktop)

Sessions & Protected Routes

express-session stores session data server-side.

Session cookie sent to browser automatically. req.session.userId — check if logged in.

Protected route middleware: redirect if not authenticated.

const session = require('express-session');
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));

// Protect route
function requireAuth(req, res, next) {
if (!req.session.userId) return res.redirect('/login');
next();
}
app.get('/dashboard', requireAuth, handler);

Use Case: Protecting pages, maintaining login state.

12. UI Design Fundamentals

2.5 hours · 13 lessons

Design principles that make interfaces beautiful AND usable.

No design tool needed — these are universal principles.

REST API Design Patterns

Good REST = predictable, consistent URLs.

Naming conventions: • Plural nouns: /users not /user • Nested resources: /users/123/posts • Filter with query strings: /users?role=admin • Versioning: /api/v1/users

Idempotency: • GET = safe, no side effects • PUT = same result if repeated • POST = NOT idempotent (creates new each time) • DELETE = idempotent

Pagination: /api/posts?page=2&limit=20

Response shape:

{
"data": [...],
"meta": { "total": 100, "page": 2, "limit": 20 },
"error": null
}

Use Case: Designing APIs other devs enjoy using.

Validation Patterns

Validate BEFORE processing data.

Check: required fields, types, lengths, formats. Return clear error messages.

function validateUser(data) {
const errors = [];
if (!data.email) errors.push('Email is required');
if (!data.email?.includes('@'))
errors.push('Invalid email format');
if (!data.password) errors.push('Password is required');
if (data.password?.length < 8)
errors.push('Password must be 8+ characters');
return errors;
}

// In route:
app.post('/register', (req, res) => {
const errors = validateUser(req.body);
if (errors.length) {
return res.status(400).json({ errors });
}
// proceed with registration...
});

Use Case: Registration, login, any form submission on the server.

7. Responsive Design

4.6 hours · 54 lessons

Make websites work on all screens: phone → tablet → desktop.

Mobile-first approach. Media queries. CSS Grid.

Projects: Product Page, Learning Journal

JSON Deep Dive

JSON = JavaScript Object Notation

Rules: • Keys MUST be double-quoted strings • Values: string, number, boolean, null, object, array • No trailing commas • No comments • No undefined

JSON.stringify(obj) → JS object to JSON string JSON.parse(str) → JSON string to JS object JSON.stringify(obj, null, 2) → pretty print

const user = { name: 'Alice', age: 25 };
const json = JSON.stringify(user);
// '{"name":"Alice","age":25}'

const parsed = JSON.parse(json);
// { name: 'Alice', age: 25 }

// Deep clone trick
const clone = JSON.parse(JSON.stringify(original));

Use Case: Every API request/response uses JSON.

HTTP Requests Anatomy

Every request has: • URL — where to send it • Method — what to do (GET/POST/PUT/DELETE) • Headers — metadata (Content-Type, Authorization) • Body — data to send (POST/PUT only)

Every response has: • Status code — 200 OK, 404 Not Found, 500 Error • Headers — metadata • Body — the data

fetch('https://api.example.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'New Post' })
});

Use Case: Every API interaction follows this pattern.

Registration & Login

Register: validate → hash password → store in DB. Login: find user → compare password hash → create session.

bcryptjs — hash & compare passwords. Never store plain-text passwords!

const bcrypt = require('bcryptjs');

// Register
const hash = await bcrypt.hash(password, 10);
db.run('INSERT INTO users (email, password) VALUES (?, ?)', [email, hash]);

// Login
const user = db.get('SELECT * FROM users WHERE email = ?', [email]);
const valid = await bcrypt.compare(password, user.password);
if (valid) req.session.userId = user.id;

Use Case: User accounts, secure authentication.

Authentication Basics

Verifying a user is who they claim to be.

NEVER store plain-text passwords. Hash them with bcrypt before saving.

const bcrypt = require('bcrypt');

// On Registration:
const saltRounds = 10;
const hashedPassword = await bcrypt.hash('mySecret123!', saltRounds);
await db.createUser(username, hashedPassword);

// On Login:
const user = await db.getUser(username);
const match = await bcrypt.compare('mySecret123!', user.passwordHash);
if (match) generateToken(); else reject();

Use Case: Login forms, protecting user data, generating session tokens.

URLs, Endpoints & Query Strings

Endpoint = specific URL for a resource. Path params: /users/123 — identify specific item. Query strings: ?sort=date&limit=10 — filter/modify.

REST naming: nouns, not verbs. /users not /getUsers

// Path parameter
fetch(`/api/users/${userId}`)

// Query strings
fetch('/api/products?category=shoes&sort=price')

// Nested resources
fetch(`/api/users/${id}/orders`)

Use Case: Designing and consuming APIs with clean URL structures.

Error-Handling Middleware

Express error middleware has 4 params: (err, req, res, next)

Must be defined AFTER all routes. Centralizes error responses.

next(err) inside any route passes to error handler.

// In routes — throw/pass errors:
app.get('/users/:id', async (req, res, next) => {
try {
const user = await db.getUser(req.params.id);
if (!user) {
const err = new Error('User not found');
err.status = 404;
return next(err);
}
res.json(user);
} catch (err) {
next(err); // pass to error handler
}
});

// Error handler (4 params!)
app.use((err, req, res, next) => {
const status = err.status || 500;
res.status(status).json({
error: err.message || 'Internal Server Error'
});
});

Use Case: Clean, consistent error responses across all routes.

HTTP & REST Basics

How the web communicates (Client <-> Server).

Request has a Method, URL, Headers, and Body. Methods:

Use Case: Every time a browser loads a page, or an app fetches data.

11. Express.js

3.9 hours · 33 lessons

The most popular Node.js web framework. Simplifies routing, middleware, and server setup.

Projects: Startup Planet API, Fullstack Express App + Auth

HTTP Status Codes Reference

Status codes tell you what happened.

2xx — Success: 200 OK · 201 Created · 204 No Content

3xx — Redirect: 301 Moved Permanently · 304 Not Modified

4xx — Client Error: 400 Bad Request · 401 Unauthorized 403 Forbidden · 404 Not Found · 422 Unprocessable

5xx — Server Error: 500 Internal · 502 Bad Gateway · 503 Unavailable

⚠️ fetch() does NOT throw on 404/500! You must check response.ok or response.status.

Use Case: Debugging API calls, proper error handling.

Middleware

Functions that run BETWEEN request and response.

app.use(middleware) — applies to all routes. Run in order! Order matters.

Built-in: express.json() — parse JSON body express.static('public') — serve static files

// Parse JSON bodies
app.use(express.json());
// Serve static files
app.use(express.static('public'));
// Custom logging middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // pass to next middleware!
});

Use Case: Authentication, logging, body parsing, CORS, error handling.

🏗️ Part 2: Building Real Apps

Responsive Design · APIs · Node.js · Databases · Express · UI Design

From static pages to fullstack apps. Server-side dev, databases, and professional design.

8. APIs & Async JavaScript

7.6 hours · 96 lessons

APIs are the backbone of the web. Learn HTTP, REST, fetch, Promises, async/await.

Projects: BoredBot, BlogSpace, War Card Game, Dashboard Chrome Extension

Promise Chaining & Error Handling

.then() chains process data step by step. .catch() handles ANY error in the chain.

Promise.all() — run multiple requests in parallel. Promise.race() — first to complete wins.

Promise.all([
fetch('/api/user'),
fetch('/api/posts'),
fetch('/api/comments')
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(([user, posts, comments]) => {
render(user, posts, comments);
})
.catch(err => showError(err));

Use Case: Fetching multiple resources simultaneously.

Routes & Parameters

app.get('/path', (req, res) => {}) — handle GET requests.

Path params: /users/:idreq.params.id Query strings: ?sort=namereq.query.sort

express.Router() — modularize routes into separate files.

const router = express.Router();

router.get('/users', (req, res) => {
const { sort, limit } = req.query;
res.json(users);
});

router.get('/users/:id', (req, res) => {
const user = users.find(u => u.id === req.params.id);
if (!user) return res.status(404).json({ error: 'Not found' });
res.json(user);
});

Use Case: Building RESTful API endpoints.

Express.js Basics

The standard Node.js web server framework.

Turns raw Node.js into a clean routing system.

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

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

// A basic route
app.get('/api/health', (req, res) => {
res.status(200).json({ status: 'OK' });
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Use Case: Building REST APIs to serve data to Frontend apps.

Callbacks & Promises

Handling asynchronous actions gracefully.

Promises represent a future value (Pending -> Fulfilled / Rejected).

// Instead of nested callbacks, write flat chains:
function getUser(id) {
return new Promise((resolve, reject) => {
if (id < 1) reject(new Error('Invalid ID'));
setTimeout(() => resolve({ id, name: 'Viktor' }), 1000);
});
}

getUser(42)
.then(user => console.log(user.name))
.catch(err => console.error(err.message));

Use Case: Fetching from APIs, waiting for timers, reading server files.

10. Databases

2.9 hours · 50 lessons

Store, query, and manage data persistently.

SQL = Structured Query Language (relational data). Postgres, MySQL, SQLite — all use SQL.

SQL vs NoSQL, Managed vs Self-Hosted.

async/await + try/catch

The modern standard for async code.

async function always returns a Promise. await pauses execution until Promise resolves. try/catch handles errors gracefully.

Check response.ok — fetch doesn't throw on 404!

async function loadDashboard() {
try {
const res = await fetch('/api/dashboard');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
renderDashboard(data);
} catch (err) {
showErrorMessage(err.message);
} finally {
hideLoader();
}
}

Use Case: Production-quality data fetching with proper error handling.

Tables & JOINs

Combining data spread across multiple tables.

Relational databases heavily utilize foreign keys.

-- INNER JOIN: Only rows that exist in BOTH tables
SELECT users.name, orders.total
FROM users
JOIN orders ON users.id = orders.user_id;

-- LEFT JOIN: ALL users, even if they have NO orders
SELECT users.name, COUNT(orders.id)
FROM users
LEFT JOIN orders ON users.id = orders.user_id
GROUP BY users.name;

Use Case: Getting a user's profile AND their past purchases in one query.

JOIN Types

INNER JOIN — only matching rows from both tables. LEFT JOIN — all from left + matching from right. RIGHT JOIN — all from right + matching from left. FULL JOIN — all rows from both tables.

⚠️ SQL Injection: never concatenate user input into queries! Use parameterized queries.

SELECT users.name, orders.total
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE orders.total > 50;

-- Parameterized (safe!)
-- db.get('SELECT * FROM users WHERE id = ?', [userId])

Use Case: Combining related data, preventing security vulnerabilities.

9. Node.js

3.7 hours · 30 lessons

JavaScript outside the browser! Build servers, APIs, and fullstack apps.

Node uses the V8 engine. Non-blocking, event-driven.

Projects: Wild Horizons API, Fullstack Node App

Callback Hell & Why Promises

Callbacks nest deeply → unreadable 'pyramid of doom'.

Promises flatten the chain. Each .then() returns a new Promise.

Callback hell:

getUser(id, (user) => {
getPosts(user.id, (posts) => {
getComments(posts[0].id, (comments) => {
// 3 levels deep already!
});
});
});

Promise chain (flat!):

getUser(id)
.then(user => getPosts(user.id))
.then(posts => getComments(posts[0].id))
.then(comments => render(comments))
.catch(err => handleError(err));

Use Case: Understanding WHY promises exist.

SQL Query Basics

Talking to relational databases.

The standard language for manipulating tables.

-- Create, Read, Update, Delete
INSERT INTO users (name, email) VALUES ('Alice', 'a@a.com');

SELECT id, name FROM users
WHERE email LIKE '%@gmail.com'
ORDER BY created_at DESC
LIMIT 10;

UPDATE users SET role = 'admin' WHERE id = 1;

DELETE FROM log_entries WHERE created_at < '2023-01-01';

Use Case: Querying Postgres, MySQL, or SQLite databases.

Node.js Fundamentals

JavaScript outside the browser.

No window, no document. We have global and process instead. Access to the file system and network hardware.

// CommonJS imports (older standard, still common)
const fs = require('fs');
const path = require('path');

// Read a file synchronously
const data = fs.readFileSync(path.join(__dirname, 'data.txt'), 'utf8');
console.log(data);

Use Case: Building web servers, CLI tools, automated scripts.

HTTP Module & Servers

Node's built-in http module creates servers.

http.createServer((req, res) => {...}) handles every request. req.url — the requested path. req.method — GET, POST, etc. res.writeHead(200, headers) — set status & headers. res.end(body) — send response.

const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Hello World' }));
});
server.listen(3000);

Use Case: Understanding how web servers work under the hood.

Creating & Altering Tables

CREATE TABLE name (col type constraints)

Common types: INTEGER, TEXT, VARCHAR(n), BOOLEAN, TIMESTAMP

Constraints: PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT, REFERENCES

ALTER TABLE — add/remove columns.

CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE users ADD COLUMN avatar_url TEXT;

Use Case: Designing your database schema.

Fullstack Node Patterns

Architecting your server code cleanly.

Don't put everything in server.js. Use the MVC pattern:

Use Case: Scaling a backend codebase from 1 file to 100+ files without losing your mind.

SQL Data Types Reference

Choosing the right type matters for performance & correctness.

Numeric: INTEGER — whole numbers REAL / FLOAT — decimals NUMERIC(10,2) — exact decimals (money!)

Text: TEXT — unlimited length VARCHAR(n) — max n characters CHAR(n) — fixed length

Date/Time: DATE — just date TIMESTAMP — date + time DEFAULT CURRENT_TIMESTAMP — auto-set

Other: BOOLEAN — true/false SERIAL / AUTOINCREMENT — auto-ID JSON / JSONB — store JSON (Postgres)

Use Case: Designing database schemas correctly.

Aggregates & GROUP BY

Aggregate functions: COUNT, SUM, AVG, MAX, MIN

GROUP BY — group rows for aggregation. HAVING — filter groups (like WHERE for groups). ORDER BY — sort results.

SELECT country, COUNT(*) as user_count,
AVG(age) as avg_age
FROM users
GROUP BY country
HAVING COUNT(*) > 10
ORDER BY user_count DESC;

Use Case: Analytics, reports, dashboards, statistics.

SELECT & Filtering

SELECT columns FROM table WHERE condition

Filtering operators: =, !=, >, <, >=, <= LIKE '%pattern%' — partial match IN (val1, val2) — match any in list BETWEEN min AND max — range AND, OR, NOT — combine conditions

SELECT name, email FROM users
WHERE age >= 18
AND country IN ('US', 'UK')
AND name LIKE '%son'
ORDER BY name ASC
LIMIT 10;

Use Case: Fetching exactly the data you need.

Indexes & Performance

Indexes speed up read queries dramatically.

CREATE INDEX idx_name ON table(column);

How it works: database creates a sorted lookup table. Like a book's index — find pages without reading everything.

⚠️ Trade-off: faster reads, slower writes. Only index columns you frequently search/filter/join on.

-- Speed up user lookups by email
CREATE INDEX idx_users_email ON users(email);

-- Composite index for frequent combined queries
CREATE INDEX idx_orders_user_date
ON orders(user_id, created_at);

-- Unique index (also enforces uniqueness)
CREATE UNIQUE INDEX idx_users_email_unique
ON users(email);

Use Case: Any table with thousands+ rows being searched.

npm & package.json

npm = Node Package Manager

npm init -y — create package.json npm install pkg — add dependency npm install -D pkg — dev dependency npm run script — run a script npx command — run without installing

package.json scripts:

{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "vitest"
},
"dependencies": { "express": "^4.18.0" },
"devDependencies": { "nodemon": "^3.0.0" }
}

^4.18.0 = compatible with 4.x.x ~4.18.0 = compatible with 4.18.x

node_modules/ — NEVER commit! Add to .gitignore

Use Case: Managing every Node.js project.

INSERT, UPDATE, DELETE

INSERT INTO table (cols) VALUES (vals) UPDATE table SET col=val WHERE condition DELETE FROM table WHERE condition

⚠️ Always use WHERE with UPDATE/DELETE! Without WHERE = affects ALL rows!

INSERT INTO users (name, email, age)
VALUES ('Alice', 'alice@mail.com', 25);

UPDATE users SET age = 26 WHERE id = 1;

DELETE FROM users WHERE id = 99;

Use Case: Creating, modifying, and removing records.

Routing & CORS

Routing = matching URL paths to handlers.

Manual routing checks req.url and req.method.

CORS (Cross-Origin Resource Sharing) — browsers block cross-origin requests by default. Server must send Access-Control-Allow-Origin header.

if (req.url === '/api/users' && req.method === 'GET') {
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
res.end(JSON.stringify(users));
}

Use Case: Building APIs that frontend apps can consume.

Server-Sent Events & Nodemon

SSE — server pushes data to client in real-time. One-way: server → client (simpler than WebSockets).

Nodemon — auto-restarts server on file changes. npx nodemon server.js — no manual restart!

// Server-Sent Events
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
setInterval(() => {
res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
}, 1000);

Use Case: Live dashboards, notifications, real-time feeds.

File System & Path Modules

fs — read/write files. path — handle file paths cross-platform.

fs.readFileSync — blocking (simple scripts) fs.readFile — non-blocking (servers) path.join() — safe path concatenation

const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'data.json');
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));

// Async version
fs.readFile(filePath, 'utf-8', (err, data) => {
if (err) throw err;
console.log(JSON.parse(data));
});

Use Case: Reading config files, serving static assets, data storage.

Environment Variables

Never hardcode secrets! Use env vars.

.env file stores config locally. dotenv package loads them into process.env.

Always add .env to .gitignore!

# .env
PORT=3000
DB_URL=postgres://user:pass@localhost/mydb
API_KEY=sk-abc123
SESSION_SECRET=mysupersecretkey
require('dotenv').config();

const port = process.env.PORT || 3000;
const dbUrl = process.env.DB_URL;
const apiKey = process.env.API_KEY;

// process.env values are always strings!
const maxRetries = parseInt(process.env.MAX_RETRIES || '3');

Use Case: API keys, database URLs, port numbers, secrets.

Body Parsing & POST

POST/PUT requests send data in the body. Node receives it in chunks — must collect and parse.

req.on('data', chunk) — receive chunks. req.on('end') — all data received. JSON.parse(body) — convert to object.

let body = '';
req.on('data', chunk => { body += chunk; });
req.on('end', () => {
const data = JSON.parse(body);
// sanitize & process data
res.writeHead(201);
res.end(JSON.stringify({ success: true }));
});

Use Case: Handling form submissions, creating resources.

EventEmitter & Streams

EventEmitter — Node's pub/sub system.

emitter.on('event', callback) — listen emitter.emit('event', data) — trigger

Many Node objects extend EventEmitter: servers, streams, processes.

Streams — process data in chunks (not all at once). Readable, Writable, Transform, Duplex.

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

emitter.on('newOrder', (order) => {
console.log(`New order: ${order.id}`);
// notify warehouse, send email, etc.
});

emitter.emit('newOrder', { id: 123, item: 'Widget' });

Use Case: Decoupled event-driven architecture, real-time features.

Input Sanitization

NEVER trust user input!

Types of attacks: • XSS — injecting <script> tags • SQL Injection — injecting SQL commands • Path Traversal — accessing ../../etc/passwd

Defense: • Escape HTML: replace <&lt; • Parameterized queries (never concatenate SQL) • Validate & whitelist input • Trim whitespace

function sanitize(str) {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.trim();
}

// SQL: use ? placeholders
db.get('SELECT * FROM users WHERE id = ?', [userId]);

Use Case: Every app that accepts user input.