How to learn Web development
This curriculum takes a complete beginner from zero web knowledge to a confident, full-stack-aware web developer across four tightly sequenced stages. Each stage builds directly on the last — first mastering the core languages of the browser, then adding interactivity and tooling, then tackling back-end and databases, and finally internalizing professional engineering practices that separate hobbyists from craftspeople.
Foundations: HTML, CSS & How the Web Works
New to itUnderstand how browsers render pages, write well-structured HTML, and style layouts confidently with CSS — the non-negotiable bedrock of every web project.

A visually rich, beginner-perfect introduction to HTML and CSS that builds mental models for how a webpage is structured and styled before any code complexity is introduced.
Making Pages Alive: JavaScript & the Browser
New to itLearn JavaScript from the ground up, understand how it manipulates the DOM, and write interactive, event-driven web pages with confidence.
▸ Study plan for this stage
Pace: 8–10 weeks, ~20–25 pages/day (roughly 1–2 chapters of Eloquent JavaScript per week). Read each chapter actively: run every code example in the browser console or Node.js, then attempt the end-of-chapter exercises before moving on. Suggested pacing — Weeks 1–2: Chapters 1–5 (Values, Types, Control Fl
- JavaScript primitives, type coercion, and the difference between == and ===
- Functions as first-class values: declarations, expressions, arrow functions, closures, and scope chains
- Higher-order array methods: map, filter, reduce, and how to compose them for data transformation
- Object-oriented programming in JS: prototype chains, ES6 classes, and encapsulation patterns
- Asynchronous JavaScript: the event loop, callbacks, Promises, and async/await as introduced in Eloquent JavaScript's later chapters
- The Document Object Model (DOM): how the browser builds a tree from HTML and how JavaScript reads and mutates it
- Event-driven programming: addEventListener, event objects, bubbling/capturing, and preventing default behavior
- Debugging mindset: reading stack traces, using browser DevTools, writing defensive code, and handling errors with try/catch
- After reading Chapters 1–5, can you explain what a closure is and construct a simple counter function that uses one?
- How does JavaScript's prototype chain differ from classical inheritance, and how do ES6 classes relate to it (Chapters 6)?
- What is the DOM, and what methods does Eloquent JavaScript demonstrate for selecting, creating, modifying, and removing elements (Chapter 14)?
- How do browser events propagate (bubbling vs. capturing), and when would you call event.stopPropagation() or event.preventDefault() (Chapter 15)?
- What problem do Promises solve compared to nested callbacks, and how does async/await make asynchronous code easier to read (Chapters 11 & 17)?
- Having worked through the project chapters (19–21), how would you structure a small multi-file JavaScript application using modules to keep concerns separated?
- **Console-first reading:** For every code snippet in Eloquent JavaScript, type it manually into the browser DevTools console or a local .js file — never copy-paste. Predict the output before running it.
- **Chapter exercise completion log:** Eloquent JavaScript ends each chapter with exercises (e.g., 'Flattening', 'Your Own Loop', 'The Debate'). Solve every one; keep a GitHub repo where each solution is a separate commit so you can track progress.
- **DOM manipulation mini-project:** After finishing Chapter 14, build a pure-JS to-do list (no frameworks) — add, complete, and delete items by directly creating and removing DOM nodes, mirroring the techniques Haverbeke demonstrates.
- **Event-driven game:** After Chapter 15, extend the platform game introduced in Eloquent JavaScript Chapter 16 by adding at least one new mechanic (e.g., a collectible item, a score counter, or a new enemy type) using the event and animation loop patterns from the book.
- **Async fetch dashboard:** After Chapter 17 (HTTP and Forms), build a small page that fetches data from a free public API (e.g., Open-Meteo weather or JSONPlaceholder), handles loading/error states with Promises or async/await, and displays the result dynamically in the DOM.
- **Teach-back journal:** After each major section (roughly every 2 chapters), write a 200-word plain-English explanation of the hardest concept you encountered — as if explaining it to a friend who has never coded. This mirrors Haverbeke's own philosophy of understanding over memorization.
Next up: Mastering JavaScript fundamentals and DOM interaction here gives you the dynamic, client-side logic skills needed to tackle the next stage — working with front-end frameworks and build tools — where you'll apply these same JS concepts inside component-based architectures like React or Vue.

Goes far deeper into the language itself — functions, closures, asynchronous programming, and the browser APIs — turning a script-writer into a real JavaScript programmer.

A short but essential read that sharpens judgment about which JavaScript features to rely on and which to avoid, building professional instincts early.
Going Deeper: Modern Front-End & Back-End Development
Some backgroundMaster a modern front-end framework (React), understand server-side development with Node.js, and learn to persist data with databases — completing the full-stack picture.
▸ Study plan for this stage
Pace: 10–12 weeks total: Weeks 1–5 on "Learning React" (~25–30 pages/day, including hands-on coding alongside reading); Weeks 6–12 on "Node.js Design Patterns" (~20–25 pages/day, with deeper pattern-study sessions every 3rd day).
- React fundamentals: JSX, components (functional vs. class), and the virtual DOM as covered in Learning React
- React Hooks (useState, useEffect, useReducer, custom hooks) and the shift away from class-based lifecycle methods, per Learning React's dedicated hooks chapters
- Unidirectional data flow, lifting state, and component composition patterns in React
- Asynchronous JavaScript patterns in Node.js: callbacks, Promises, async/await, and the Event Loop as grounded in Node.js Design Patterns
- Core Node.js Design Patterns: Module pattern (CommonJS & ESM), Observer/EventEmitter, Streams, and the Reactor pattern
- Creational and structural patterns applied to Node.js services: Factory, Proxy, Decorator, and Middleware pipeline (as detailed in Node.js Design Patterns)
- Scalability and modularity in back-end architecture: designing for reuse, separation of concerns, and avoiding callback hell
- Full-stack mental model: how a React front-end communicates with a Node.js back-end via REST APIs, and where a database layer fits in
- After finishing Learning React, can you explain the difference between controlled and uncontrolled components, and when you would choose each?
- How do React Hooks replace lifecycle methods — specifically, how does useEffect map to componentDidMount, componentDidUpdate, and componentWillUnmount?
- From Node.js Design Patterns, what is the Reactor pattern and why is it central to Node.js's non-blocking I/O model?
- How does the Observer pattern manifest in Node.js's EventEmitter, and what are the risks (e.g., memory leaks) of misusing it as described in Node.js Design Patterns?
- What is the difference between Streams and buffered I/O in Node.js, and in what scenarios do Streams provide a decisive advantage?
- How would you wire a React front-end (built with the patterns from Learning React) to an Express-based REST API (structured with patterns from Node.js Design Patterns) — what are the key integration points?
- Build a multi-component React app (e.g., a task manager) using only functional components and Hooks — implement useState for local state, useEffect for a mock API fetch, and at least one custom hook (e.g., useFetch), directly applying the patterns from Learning React.
- Refactor the same React app to lift shared state to a common ancestor and pass it via props, then replace prop-drilling with the Context API — documenting what changed and why, as Learning React recommends.
- Implement a small Node.js CLI tool that reads a large file using Streams (Transform + Readable) instead of fs.readFile, measuring and comparing memory usage — a direct exercise of the Streams chapter in Node.js Design Patterns.
- Create a Node.js EventEmitter-based pub/sub module (e.g., a simple in-process event bus), then deliberately introduce and fix a listener-leak to internalize the warnings covered in Node.js Design Patterns.
- Build a minimal Express REST API applying the Middleware pipeline and Factory patterns from Node.js Design Patterns (e.g., a factory that creates database-connection objects), then consume it from your React app using fetch/Axios — completing a full-stack round-trip.
- Code-review exercise: take a callback-heavy Node.js snippet, refactor it first to Promises, then to async/await, and finally identify which version best fits a streaming use case — mapping each step to the async patterns chapter in Node.js Design Patterns.
Next up: Mastering React's component model and Node.js's design patterns gives you a working full-stack foundation, setting the stage for the next level where you will harden these skills with databases (SQL/NoSQL), authentication, testing strategies, and production deployment practices.

Introduces component-based thinking and React's ecosystem in a practical, project-driven way — the natural next step once core JavaScript is solid.

Moves the reader to the server side using JavaScript they already know, covering Node.js architecture, async patterns, REST APIs, and real-world design patterns.
Craft & Professionalism: Writing Code That Lasts
Going deepInternalize software engineering principles — clean code, testing, security, and performance — so that the web applications you build are maintainable, secure, and production-ready.
▸ Study plan for this stage
Pace: 8–10 weeks total: ~4–5 weeks per book at roughly 20–25 pages/day. Read "Clean Code" first (264 pages), completing ~3 chapters per week with deliberate practice sessions between readings; then move to "The Pragmatic Programmer" (352 pages) at a similar pace, journaling one "Pragmatic Tip" per day as
- Meaningful naming, small functions, and the Single Responsibility Principle (SRP) as taught in Clean Code — every unit of code should do one thing and do it well
- Clean Code's concept of code smells and refactoring: recognizing duplication (DRY violations), long methods, large classes, and feature envy, then systematically eliminating them
- Writing expressive, self-documenting code that minimizes the need for comments — comments should explain *why*, not *what*
- Test-Driven Development (TDD) and the Three Laws of TDD from Clean Code: write a failing test first, make it pass with minimal code, then refactor
- The Pragmatic Programmer's DRY (Don't Repeat Yourself) principle extended beyond code to documentation, data schemas, and team knowledge
- The Pragmatic Programmer's concept of Orthogonality — keeping components independent so changes in one don't ripple unpredictably through others
- The Pragmatic Programmer's philosophy of being a 'Tracer Bullet' developer: building thin, end-to-end slices of functionality early to validate architecture before scaling
- Pragmatic investment in your knowledge portfolio, tool mastery (editors, debuggers, version control), and the 'broken windows' theory of software entropy
- After reading Clean Code, can you identify at least five distinct code smells by name and explain the refactoring move that addresses each one?
- What are the Three Laws of TDD as stated in Clean Code, and why does Martin argue that writing tests first — rather than after — changes the design of production code?
- How does The Pragmatic Programmer define DRY, and how does it differ from simply 'avoiding copy-paste'? Give an example where a DRY violation lives outside of source code.
- What does Orthogonality mean in The Pragmatic Programmer, and how would you use it to evaluate whether two modules in a web application are properly decoupled?
- Both books address the programmer's professional responsibility. How do Clean Code's Boy Scout Rule and The Pragmatic Programmer's 'broken windows' metaphor complement each other as a philosophy for maintaining a codebase over time?
- What is the Tracer Bullet approach from The Pragmatic Programmer, and when would you choose it over building a detailed prototype?
- Code Smell Audit: Take an existing personal or open-source web project and spend one session cataloguing every code smell you can find using Clean Code's taxonomy (long method, large class, primitive obsession, etc.). Prioritize the top three and refactor them, committing each refactor separately with a message explaining the smell removed.
- TDD Kata: Implement a small but complete feature (e.g., a URL slug generator or a shopping-cart discount engine) using strict TDD — Red → Green → Refactor. Do not write a single line of production code without a failing test driving it. Aim for 100% coverage as a natural outcome, not a forced goal.
- Naming Refactor Sprint: Pick one module or file in a project and rename every variable, function, and class until the code reads like well-written prose. Ask a peer to read it cold and note where they still had to pause — those are your remaining naming failures.
- DRY & Orthogonality Mapping: Draw a dependency diagram of a small web app (even a to-do app). Highlight any place where knowledge is duplicated across layers (e.g., validation rules in both the frontend and database schema). Eliminate one duplication using a shared schema or validation library, then verify the two layers are now orthogonal.
- Pragmatic Tips Journal: As you read The Pragmatic Programmer, maintain a running document. For each of the 100 Pragmatic Tips, write one sentence describing a concrete situation from your own coding experience where that tip applies (or where ignoring it caused a bug or delay).
- Production-Readiness Checklist: After finishing both books, build a personal checklist of 15–20 criteria a piece of code must meet before you consider it 'done' (e.g., no functions longer than 20 lines, every public method has a test, no hardcoded secrets, error paths handled). Apply it as a self-review on your next pull request or project submission.
Next up: Internalizing clean code principles, disciplined testing, and pragmatic engineering habits establishes the professional foundation needed to confidently tackle system-level thinking — such as scalable architecture, distributed systems, and advanced design patterns — which are the natural next frontier for a production-ready web developer.

Teaches the discipline of writing readable, maintainable code through concrete refactoring examples — essential before working on any serious team or long-lived codebase.

Broadens perspective from writing code to thinking like a professional engineer — covering tooling, automation, testing philosophy, and career-long learning habits that tie the entire curriculum together.