A frontend developer builds everything users see and interact with — buttons, forms, animations, responsive layouts, and the JavaScript that makes it all work. This roadmap shows you exactly what to learn, in what order, and realistic timelines to go from zero to job-ready.
At a glance
| Phase | Topics | Time estimate |
|---|---|---|
| 1 | The internet, browsers, DevTools | 1–2 weeks |
| 2 | HTML — structure and semantics | 2–3 weeks |
| 3 | CSS — layouts, responsive design | 4–6 weeks |
| 4 | JavaScript — core language | 6–8 weeks |
| 5 | Version control with Git | 1–2 weeks |
| 6 | React (or Vue/Angular) | 6–8 weeks |
| 7 | TypeScript | 3–4 weeks |
| 8 | Build tools and package managers | 1–2 weeks |
| 9 | Testing | 2–3 weeks |
| 10 | Performance and accessibility | 2–3 weeks |
| 11 | Portfolio projects + job search | 4–8 weeks |
| Total to first job | ~9–14 months |
Phase 1 — The internet and browsers (Weeks 1–2)
Before writing code, understand what you are building on.
| Concept | What it means | Why it matters |
|---|---|---|
| How the web works | Browser → DNS → HTTP → Server → Response | You debug this chain every day |
| HTTP/HTTPS | Request/response, status codes (200/301/404), headers | Every network request uses this |
| DNS | Domain names resolve to IP addresses | Explains CDN, latency, SSL certs |
| Browsers | Rendering engines (Blink, Gecko, WebKit), event loop | Your runtime environment |
| DevTools | Elements, Console, Network, Performance, Lighthouse tabs | Primary debugging tool |
Learn: Open DevTools right now. Inspect a website's network requests. Read the headers.
Phase 2 — HTML (Weeks 3–5)
HTML is the skeleton of every web page. Learn the semantics — not just tags, but meaning.
Core HTML skills
| Topic | What to learn |
|---|---|
| Document structure | <!DOCTYPE>, <html>, <head>, <body>, <meta charset> |
| Semantic elements | <header>, <nav>, <main>, <section>, <article>, <aside>, <footer> |
| Text content | <h1>–<h6> hierarchy, <p>, <ul>, <ol>, <dl>, <blockquote> |
| Links and images | <a href>, <img src alt>, lazy loading (loading="lazy") |
| Forms | <form>, <input> types, <label>, <select>, <textarea>, <button> |
| Tables | <table>, <thead>, <tbody>, <th scope> |
| Embedded content | <video>, <audio>, <iframe>, <canvas> |
| Accessibility | ARIA labels, roles, tabindex, skip links |
HTML example: accessible form
<form action="/search" method="get">
<label for="query">Search</label>
<input
type="search"
id="query"
name="q"
placeholder="Type here…"
autocomplete="off"
required
/>
<button type="submit">Search</button>
</form>
Key insight: Use the right tag for the right job. <button> for actions, <a> for navigation, <input type="checkbox"> for toggles — not <div onclick>.
Phase 3 — CSS (Weeks 6–11)
CSS controls how things look and where they sit on screen. This phase has the steepest learning curve for many beginners.
CSS foundations
| Topic | What to learn |
|---|---|
| Selectors | Element, class, ID, attribute, pseudo-class (:hover, :focus, :nth-child) |
| Box model | content → padding → border → margin, box-sizing: border-box |
| Cascade & specificity | Specificity scores, !important (avoid), inheritance |
| Colors & typography | color, font-family, font-size, line-height, Google Fonts |
| Display | block, inline, inline-block, none |
| Position | static, relative, absolute, fixed, sticky |
| Flexbox | display: flex, flex-direction, justify-content, align-items, flex-wrap |
| CSS Grid | display: grid, grid-template-columns, grid-template-rows, gap, grid-area |
| Responsive design | @media queries, min-width vs max-width, mobile-first |
| CSS variables | --color-primary: #3b82f6; color: var(--color-primary) |
| Transitions & animations | transition, @keyframes, animation |
Flexbox vs Grid — when to use which
| Use case | Use this |
|---|---|
| Single-row navigation bar | Flexbox |
| Card grid that wraps | Flexbox or Grid |
| Full page layout (header/sidebar/main/footer) | Grid |
| Centering one element | Flexbox (display:flex; place-items:center) |
| Magazine-style overlapping layout | Grid |
| Item alignment within a row | Flexbox |
CSS example: responsive card grid
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
@media (max-width: 600px) {
.card-grid {
grid-template-columns: 1fr;
}
}
CSS frameworks to know
| Framework | What it is | When to use |
|---|---|---|
| Tailwind CSS | Utility-first, write classes in HTML | Default choice for new projects |
| Bootstrap | Component library, ready-made UI | Rapid prototypes, admin panels |
| CSS Modules | Scoped CSS per component | React projects without a UI library |
| Styled Components | CSS-in-JS for React | When you want JS-driven styles |
Focus on: Tailwind CSS. It is the most requested in 2025 and teaches you underlying CSS concepts at the same time.
Phase 4 — JavaScript (Weeks 12–19)
JavaScript makes pages interactive. Master the core language before touching any framework.
Core JavaScript concepts
| Category | Topics |
|---|---|
| Variables & types | let, const, var (avoid), primitives vs objects, type coercion |
| Functions | Function declarations, arrow functions, default params, rest/spread |
| Arrays | map, filter, reduce, find, some, every, flat, flatMap |
| Objects | Object literals, destructuring, shorthand, spread operator, Object.keys/values/entries |
| Control flow | if/else, ternary, switch, for, for…of, for…in |
| DOM manipulation | querySelector, addEventListener, classList, innerHTML, createElement |
| Async programming | setTimeout, Promises, async/await, fetch, error handling |
| Error handling | try/catch/finally, custom errors, .catch() on Promises |
| Modules | import/export, named vs default exports |
| Classes | class, constructor, extends, super |
| Closures | Scope, lexical environment, factory functions |
| Prototypes | Object.create, prototype chain (understand, rarely use directly) |
Async example: fetching data
async function getUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const user = await res.json();
return user;
} catch (err) {
console.error("Failed to fetch user:", err);
throw err;
}
}
JavaScript pitfalls to avoid early
| Pitfall | What happens | Fix |
|---|---|---|
var hoisting |
Variables accessible before declaration | Use const/let |
== vs === |
"1" == 1 is true |
Always use === |
this context |
Changes in callbacks and event handlers | Use arrow functions or .bind() |
| Mutating arrays directly | arr.push() mutates original |
Use spread: [...arr, newItem] |
Forgetting await |
Returns Promise<pending> instead of value |
Always await async functions |
null / undefined access |
Cannot read property 'x' of null |
Optional chaining: obj?.x |
Phase 5 — Git and version control (Weeks 20–21)
Every employer expects Git fluency. Use it from day one.
Git commands every frontend dev must know
git init # start a repo
git clone <url> # copy remote repo locally
git status # see changed files
git add . # stage all changes
git commit -m "feat: add login form"
git push origin main # push to remote
git checkout -b feature/navbar # create and switch to branch
git merge feature/navbar # merge branch into current
git pull origin main # fetch + merge remote changes
git log --oneline --graph # see commit history
git diff HEAD~1 # compare with previous commit
git stash # temporarily save uncommitted changes
git stash pop # restore stashed changes
Commit message format (Conventional Commits)
feat: add responsive navigation
fix: correct mobile menu z-index
style: format button component
refactor: extract theme colors to CSS variables
docs: update component usage examples
Phase 6 — React (Weeks 22–29)
React is the dominant frontend library in 2025. Learn it deeply before exploring alternatives.
Core React concepts
| Concept | What to learn |
|---|---|
| JSX | HTML-like syntax in JavaScript files |
| Components | Function components, props, children |
| State | useState, lifting state up, controlled inputs |
| Effects | useEffect, dependency array, cleanup |
| Context | useContext, createContext, avoiding prop drilling |
| Performance | useMemo, useCallback, React.memo |
| Refs | useRef for DOM access and persisting values |
| Patterns | Custom hooks, compound components, render props |
State management options
| Tool | When to use |
|---|---|
useState + props |
Simple local state, small components |
useContext |
Shared state (theme, auth, locale) without a library |
| Zustand | Global state, simple API, no boilerplate |
| TanStack Query | Server state, caching, loading/error states from APIs |
| Redux Toolkit | Large teams, complex state, time-travel debugging |
React example: data fetching with TanStack Query
import { useQuery } from "@tanstack/react-query";
function UserProfile({ userId }) {
const { data, isLoading, error } = useQuery({
queryKey: ["user", userId],
queryFn: () => fetch(`/api/users/${userId}`).then((r) => r.json()),
});
if (isLoading) return <div>Loading…</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>{data.name}</h1>
<p>{data.email}</p>
</div>
);
}
React ecosystem map
| Category | Popular choices |
|---|---|
| Framework | Next.js (SSR/SSG), Vite (SPA) |
| Routing | React Router v6, TanStack Router |
| State | Zustand, TanStack Query, Redux Toolkit |
| Forms | React Hook Form, Formik |
| UI components | shadcn/ui, Radix UI, MUI, Chakra UI |
| Styling | Tailwind CSS, CSS Modules, Styled Components |
| Testing | Vitest, React Testing Library |
| Animation | Framer Motion, React Spring |
Phase 7 — TypeScript (Weeks 30–33)
TypeScript is now required at most companies. Learn it after you are comfortable with JavaScript.
TypeScript essentials
// Basic types
const name: string = "Alice";
const age: number = 30;
const active: boolean = true;
// Interfaces
interface User {
id: number;
name: string;
email: string;
role?: "admin" | "user"; // optional + union type
}
// Generic components
interface ApiResponse<T> {
data: T;
error: string | null;
loading: boolean;
}
// Function types
function greet(user: User): string {
return `Hello, ${user.name}`;
}
// Utility types
type UserPreview = Pick<User, "id" | "name">;
type PartialUser = Partial<User>;
type ReadonlyUser = Readonly<User>;
TypeScript in React
interface ButtonProps {
label: string;
onClick: () => void;
variant?: "primary" | "secondary" | "ghost";
disabled?: boolean;
}
export function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
className={`btn btn-${variant}`}
>
{label}
</button>
);
}
Phase 8 — Build tools and package managers (Weeks 34–35)
| Tool | Purpose | Default choice |
|---|---|---|
| npm / pnpm | Package manager | pnpm for speed, npm for simplicity |
| Vite | Dev server + bundler for SPAs | Yes — fastest cold starts |
| Next.js | Full-stack React framework with built-in bundler | For SSR/SSG/App Router |
| ESLint | Linting — catch errors and bad patterns | Required |
| Prettier | Auto-format code | Required |
| Husky + lint-staged | Run linting on git commit | Optional but recommended |
Common package.json scripts
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .ts,.tsx",
"format": "prettier --write .",
"test": "vitest"
}
}
Phase 9 — Testing (Weeks 36–38)
Employers increasingly require test-writing skills. Learn the basics before your first job.
Testing pyramid for frontend
| Level | Tool | What it tests | Speed |
|---|---|---|---|
| Unit | Vitest | Single functions, utilities | Fast |
| Component | React Testing Library | Single components in isolation | Fast |
| Integration | React Testing Library + MSW | Multiple components + mocked API | Medium |
| E2E | Playwright, Cypress | Full user flows in real browser | Slow |
React Testing Library example
import { render, screen, userEvent } from "@testing-library/react";
import { Button } from "./Button";
test("calls onClick when clicked", async () => {
const handleClick = vi.fn();
render(<Button label="Save" onClick={handleClick} />);
await userEvent.click(screen.getByRole("button", { name: "Save" }));
expect(handleClick).toHaveBeenCalledOnce();
});
Phase 10 — Performance and accessibility (Weeks 39–41)
These two topics separate junior from mid-level developers.
Core Web Vitals (Google ranking signals)
| Metric | Measures | Good score |
|---|---|---|
| LCP (Largest Contentful Paint) | Load speed of main content | < 2.5 s |
| INP (Interaction to Next Paint) | Responsiveness to clicks | < 200 ms |
| CLS (Cumulative Layout Shift) | Visual stability (no jumping elements) | < 0.1 |
Performance techniques
| Technique | Impact | How to apply |
|---|---|---|
| Image optimisation | High | Use <img loading="lazy">, WebP/AVIF, srcset |
| Code splitting | High | React.lazy() + <Suspense>, Next.js dynamic() |
| Font loading | Medium | font-display: swap, preconnect to Google Fonts |
| CSS critical path | Medium | Inline above-the-fold CSS |
| Bundle size | High | Tree shaking, avoid large libraries (moment → date-fns) |
| Caching | High | Cache-Control headers, service workers |
| Debounce/throttle | Medium | Limit re-renders on input, scroll, resize events |
Accessibility essentials (WCAG)
| Rule | What to do |
|---|---|
| Keyboard navigation | All interactive elements reachable with Tab, Esc, Enter |
| ARIA labels | Add aria-label to icon-only buttons |
| Color contrast | Minimum 4.5:1 ratio for normal text |
| Focus indicator | Never remove :focus outline without a replacement |
| Alt text | Meaningful alt on all informative images, alt="" on decorative |
| Form labels | Every <input> has an associated <label> |
| Heading hierarchy | Do not skip <h1> → <h3> without <h2> |
Phase 11 — Portfolio and job search (Weeks 42–50+)
Portfolio projects that impress employers
| Project | Skills demonstrated |
|---|---|
| Personal portfolio site | HTML, CSS, responsive design, deployed to Vercel |
| REST API consumer app | Fetch, async/await, state, loading/error states |
| Full CRUD app with auth | React, forms, React Router, localStorage or Supabase |
| E-commerce product page | Component design, cart state, Tailwind, TypeScript |
| Real-time feature | WebSockets or SSE, Zustand, optimistic UI |
| Open-source contribution | Git workflow, code review, communication |
Rule: Three polished projects beat ten half-finished ones. Deploy everything.
Deployment platforms
| Platform | Free tier | Best for |
|---|---|---|
| Vercel | Yes | Next.js, React SPAs |
| Netlify | Yes | Static sites, SPAs |
| GitHub Pages | Yes | Static HTML/CSS/JS |
| Cloudflare Pages | Yes | Ultra-fast global CDN |
| Railway | Yes | Full-stack with a backend |
CV checklist for frontend roles
- Link to GitHub (active commits in the last 3 months)
- Link to live deployed projects (not
localhost) - List technologies with versions (React 18, TypeScript 5, Next.js 14)
- Quantify impact ("reduced bundle size by 40%", "improved LCP from 3.8 s to 1.9 s")
- No generic phrases ("team player", "fast learner") — show it with projects
Full technology map
Frontend Developer Stack 2025
├── Foundation
│ ├── HTML5 (semantic, accessible)
│ ├── CSS3 (Flexbox, Grid, animations)
│ └── JavaScript (ES2024)
│
├── Language
│ └── TypeScript 5
│
├── Framework
│ ├── React 18 / 19 (primary)
│ ├── Next.js 15 (full-stack React)
│ └── Vue 3 or Svelte (alternative)
│
├── Styling
│ ├── Tailwind CSS 4
│ ├── shadcn/ui (component library)
│ └── CSS Modules (scoped styles)
│
├── State & Data
│ ├── Zustand (global state)
│ ├── TanStack Query (server state)
│ └── React Hook Form (form state)
│
├── Build Tools
│ ├── Vite (SPA bundler)
│ ├── ESLint + Prettier (code quality)
│ └── pnpm (package manager)
│
├── Testing
│ ├── Vitest (unit/integration)
│ ├── React Testing Library (components)
│ └── Playwright (E2E)
│
└── DevOps Basics
├── Git + GitHub
├── Vercel / Netlify (deployment)
└── GitHub Actions (CI/CD)
Realistic timeline
| Month | Milestone |
|---|---|
| 1 | HTML + CSS basics, first static page deployed |
| 2 | CSS layouts (Flexbox + Grid), responsive design |
| 3–4 | JavaScript fundamentals, DOM, fetch API |
| 5 | Git, first open-source contribution |
| 6–7 | React fundamentals, hooks, first React app |
| 8 | TypeScript basics, typed React components |
| 9 | Build tools, testing basics, performance |
| 10–11 | Portfolio projects, accessibility improvements |
| 12–14 | Job applications, interview prep, offer |
Note: These are honest estimates for someone studying 2–4 hours per day. Bootcamp intensives can compress this to 6 months, but depth may suffer.
Frontend vs related roles
| Role | Focus | Salary range (US, 2025) |
|---|---|---|
| Frontend Developer | UI, UX, browser, performance | $70k–$140k |
| Full Stack Developer | Frontend + backend + DB | $90k–$160k |
| UI/UX Designer | Design, Figma, user research | $60k–$130k |
| Mobile Developer (React Native) | iOS + Android from JS/TS | $90k–$160k |
| Backend Developer | APIs, databases, servers | $90k–$160k |
| DevOps Engineer | Infrastructure, CI/CD, cloud | $100k–$170k |
Common mistakes
| Mistake | What goes wrong | Fix |
|---|---|---|
| Skipping HTML/CSS to jump to React | Can't debug layout or responsive issues | Master the basics first — 2 months |
| Tutorial purgatory | Watch videos, never build anything | Code every concept as you learn it |
| Jumping between frameworks | Never get deep in any one | React first, then explore |
| No portfolio projects | Employers have nothing to evaluate | Build 3 deployed projects before applying |
| Ignoring TypeScript | Type errors in production, hard to hire | Start TypeScript alongside React |
| No testing knowledge | Fails technical screens | Learn RTL and Vitest before job search |
| Neglecting accessibility | Excludes 15% of users, legal liability | Add alt, labels, keyboard nav from day one |
| Not using Git from the start | Lose work, can't collaborate | Commit every day, even small changes |
Frequently asked questions
Do I need a computer science degree to become a frontend developer? No. Most frontend developers are self-taught or bootcamp graduates. A degree helps for larger companies, but your portfolio and GitHub activity matter more.
Should I learn Vue or Angular instead of React? Start with React — it has the most jobs (60–70% of frontend postings), the largest ecosystem, and the most learning resources. Learn Vue or Angular after you are employed.
How long does it take to get a junior frontend job? Realistically 9–18 months of consistent study and project building. Coding bootcamps compress this to 6 months but require full-time commitment.
Do I need to learn backend to be a frontend developer? No. Pure frontend roles are plentiful. However, understanding HTTP, REST APIs, and databases makes you significantly more effective and employable.
Is Next.js necessary or is plain React enough? Many jobs require Next.js specifically. Learn React first — Next.js builds on top of it. Once you know React, adding Next.js takes 2–3 weeks.
What is the difference between a frontend developer and a UI/UX designer? Designers use tools like Figma to create visual mockups and user flows — no coding required. Developers implement those designs in code. Some people do both (designer-developers), but they are different disciplines.