Frontend Architecture
Overview
Frontend architecture has evolved far beyond "put jQuery on the page." Modern frontend development is a spectrum of rendering strategies, each with distinct tradeoffs for performance, SEO, developer experience, and user experience. Choosing the right architecture is one of the most consequential decisions in a web project — it affects everything from time-to-interactive to team structure.
The Frontend Architecture Spectrum
┌──────────────────────────────────────────────────────────────────────┐
│ Frontend Architecture Spectrum │
│ │
│ MPA ────▶ SPA ────▶ SSR ────▶ SSG ────▶ Islands ────▶ Micro-FEs │
│ │
│ Server Client Server+Client Build-Time Partial │
│ Rendered Rendered Hybrid Pre-render Hydration │
│ Full page Single HTML+Hydrate Static HTML Interactive │
│ reloads shell+API on every req + CDN islands │
└──────────────────────────────────────────────────────────────────────┘
Multi-Page Application (MPA)
Traditional server-rendered HTML pages. Each navigation is a full page request. Simple, SEO-friendly, but no client-side interactivity without additional JavaScript.
Single Page Application (SPA)
A single HTML shell with client-side routing and rendering. The server provides JSON APIs; the browser handles everything else. Rich interactivity but challenges with SEO, initial load, and bundle size.
Server-Side Rendering (SSR)
HTML is rendered on the server for each request, then hydrated on the client for interactivity. Best of both worlds — SEO-friendly first paint with SPA-like interactivity after hydration.
Static Site Generation (SSG)
Pages are pre-rendered at build time and served as static HTML from a CDN. Fastest possible TTFB, but content is only as fresh as the last build.
Islands Architecture
The page is mostly static HTML with isolated "islands" of interactivity that hydrate independently. Only interactive components ship JavaScript. Astro pioneered this approach.
Micro-Frontends
Multiple independently deployed frontend applications composed into a single user experience. Each team owns a vertical slice of the UI with its own tech stack, build pipeline, and deployment.
Comparison Table
| Criteria |
SPA |
SSR |
SSG |
Islands |
| First Contentful Paint |
Slow (JS must load) |
Fast (server HTML) |
Fastest (CDN) |
Fast (static + partial JS) |
| Time to Interactive |
Moderate |
Moderate (hydration) |
Fast |
Fast (minimal JS) |
| SEO |
Poor (without SSR/prerender) |
Excellent |
Excellent |
Excellent |
| Dynamic Content |
Excellent (API-driven) |
Excellent (per-request) |
Limited (build-time) |
Moderate |
| JS Bundle Size |
Large |
Large (hydration) |
Small-Medium |
Minimal |
| Caching |
API-level |
Page-level (CDN w/ ISR) |
Full CDN |
Full CDN + selective |
| Complexity |
Moderate |
High |
Low |
Low-Moderate |
| Best For |
Dashboards, apps |
Content + interactivity |
Blogs, docs, marketing |
Content-heavy + some interactivity |
Core Frontend Concerns
Routing
- Client-side: React Router, Vue Router, Angular Router — URL changes without full page reloads
- File-based: Next.js, Nuxt, SvelteKit, Remix — filesystem structure defines routes
- Server-side: Traditional MPA routing — each URL is a server request
State Management
- Local state: React useState/useReducer, Vue ref/reactive, Svelte stores, Angular signals
- Global state: Redux, Zustand, Pinia, NgRx, Jotai, Valtio
- Server state: TanStack Query, SWR, Apollo Client — treats server data as a cache
- URL state: Search params as state (Remix philosophy)
Data Fetching
- Client-side: fetch/axios from useEffect, TanStack Query, SWR
- Server-side: Next.js Server Components, Remix loaders, Nuxt useFetch, SvelteKit load
- GraphQL: Apollo Client, urql, Relay
- Real-time: WebSockets, Server-Sent Events, tRPC subscriptions
Code Splitting
- Route-based: React.lazy + Suspense, dynamic import()
- Component-based: Loadable Components, Vue async components
- Framework-managed: Next.js automatic splitting, Vite's chunk optimization
Hydration
- Full hydration: Entire page re-rendered on client (React SSR, Next.js)
- Partial hydration: Only interactive parts hydrate (Astro Islands)
- Progressive hydration: Components hydrate on visibility/interaction
- Resumability: Skip hydration entirely, serialize state (Qwik)
Framework Landscape
| Framework |
Type |
Rendering |
Language |
| React |
Library |
SPA, SSR (via Next.js) |
TypeScript/JSX |
| Vue |
Framework |
SPA, SSR (via Nuxt) |
TypeScript/SFC |
| Angular |
Framework |
SPA, SSR (Angular Universal) |
TypeScript |
| Svelte |
Compiler |
SPA, SSR (via SvelteKit) |
TypeScript/Svelte |
| Solid |
Library |
SPA, SSR (via SolidStart) |
TypeScript/JSX |
| Astro |
Meta-framework |
Islands, SSG, SSR |
Any (React, Vue, Svelte, etc.) |
| Next.js |
Meta-framework |
SSR, SSG, ISR, RSC |
TypeScript/React |
| Nuxt |
Meta-framework |
SSR, SSG, ISR |
TypeScript/Vue |
| Remix |
Meta-framework |
SSR, SPA mode |
TypeScript/React |
| SvelteKit |
Meta-framework |
SSR, SSG, SPA |
TypeScript/Svelte |
Architecture Decision Guide
| When You Need... |
Choose |
| Rich interactivity, dashboard-style UI |
SPA (see dev/frontend/spa) |
| SEO + interactivity, content sites |
SSR (see dev/frontend/ssr) |
| Static content with occasional interactivity |
Islands (Astro) |
| Offline support, native-like experience |
PWA (see dev/frontend/pwa) |
| Multiple teams, independent deployment |
Micro-frontends (see dev/frontend/micro-frontends) |
| Blog, documentation, marketing pages |
SSG (Next.js, Astro, or Hugo) |
| Full-stack with tight server integration |
Remix or SvelteKit |
Performance Budgets
A well-architected frontend should target:
- Largest Contentful Paint (LCP): < 2.5s
- First Input Delay (FID): < 100ms
- Cumulative Layout Shift (CLS): < 0.1
- Total JS bundle (initial): < 200KB gzipped
- Time to Interactive (TTI): < 3.5s on 4G
Best Practices
- Choose the simplest architecture that meets your requirements — not every app needs SSR or micro-frontends.
- Measure performance with real user metrics (Core Web Vitals), not just Lighthouse scores.
- Use code splitting aggressively — no user should download JavaScript they will never execute.
- Treat server state and client state differently — use TanStack Query or SWR for server state, not Redux.
- Design for progressive enhancement — the page should be usable before JavaScript loads.
- Consider the Islands Architecture for content-heavy sites that need sprinkles of interactivity.
Sub-Skills
dev/frontend/spa — Single Page Applications: client-side routing, state management, bundle optimization
dev/frontend/pwa — Progressive Web Apps: service workers, offline support, installability
dev/frontend/micro-frontends — Micro-Frontend Architecture: Module Federation, single-spa, composition
dev/frontend/ssr — Server-Side Rendering: SSR, SSG, ISR, Islands, React Server Components
1---2name: frontend-103description: Frontend architecture approaches — from Multi-Page Apps through Single Page Apps, Server-Side Rendering, Islands Architecture, and Micro-Frontends. Covers the full spectrum of client-side concerns: routing, state management, data fetching, code splitting, and hydration. USE FOR: frontend architecture selection, comparing SPA vs SSR vs micro-frontends, choosing frontend frameworks, client-side architecture decisions DO NOT USE FOR: specific rendering approach details (use sub-skills: spa, pwa, micro-frontends, ssr), backend architecture (use dev/backend), design system components (use design-system)4license: MIT5---6
7# Frontend Architecture
8
9## Overview
10Frontend architecture has evolved far beyond "put jQuery on the page." Modern frontend development is a spectrum of rendering strategies, each with distinct tradeoffs for performance, SEO, developer experience, and user experience. Choosing the right architecture is one of the most consequential decisions in a web project — it affects everything from time-to-interactive to team structure.
11
12## The Frontend Architecture Spectrum
13
14```
15┌──────────────────────────────────────────────────────────────────────┐
16│ Frontend Architecture Spectrum │
17│ │
18│ MPA ────▶ SPA ────▶ SSR ────▶ SSG ────▶ Islands ────▶ Micro-FEs │
19│ │
20│ Server Client Server+Client Build-Time Partial │
21│ Rendered Rendered Hybrid Pre-render Hydration │
22│ Full page Single HTML+Hydrate Static HTML Interactive │
23│ reloads shell+API on every req + CDN islands │
24└──────────────────────────────────────────────────────────────────────┘
25```
26
27### Multi-Page Application (MPA)
28Traditional server-rendered HTML pages. Each navigation is a full page request. Simple, SEO-friendly, but no client-side interactivity without additional JavaScript.
29
30### Single Page Application (SPA)
31A single HTML shell with client-side routing and rendering. The server provides JSON APIs; the browser handles everything else. Rich interactivity but challenges with SEO, initial load, and bundle size.
32
33### Server-Side Rendering (SSR)
34HTML is rendered on the server for each request, then hydrated on the client for interactivity. Best of both worlds — SEO-friendly first paint with SPA-like interactivity after hydration.
35
36### Static Site Generation (SSG)
37Pages are pre-rendered at build time and served as static HTML from a CDN. Fastest possible TTFB, but content is only as fresh as the last build.
38
39### Islands Architecture
40The page is mostly static HTML with isolated "islands" of interactivity that hydrate independently. Only interactive components ship JavaScript. Astro pioneered this approach.
41
42### Micro-Frontends
43Multiple independently deployed frontend applications composed into a single user experience. Each team owns a vertical slice of the UI with its own tech stack, build pipeline, and deployment.
44
45## Comparison Table
46
47| Criteria | SPA | SSR | SSG | Islands |
48|----------|-----|-----|-----|---------|
49| **First Contentful Paint** | Slow (JS must load) | Fast (server HTML) | Fastest (CDN) | Fast (static + partial JS) |
50| **Time to Interactive** | Moderate | Moderate (hydration) | Fast | Fast (minimal JS) |
51| **SEO** | Poor (without SSR/prerender) | Excellent | Excellent | Excellent |
52| **Dynamic Content** | Excellent (API-driven) | Excellent (per-request) | Limited (build-time) | Moderate |
53| **JS Bundle Size** | Large | Large (hydration) | Small-Medium | Minimal |
54| **Caching** | API-level | Page-level (CDN w/ ISR) | Full CDN | Full CDN + selective |
55| **Complexity** | Moderate | High | Low | Low-Moderate |
56| **Best For** | Dashboards, apps | Content + interactivity | Blogs, docs, marketing | Content-heavy + some interactivity |
57
58## Core Frontend Concerns
59
60### Routing
61- **Client-side**: React Router, Vue Router, Angular Router — URL changes without full page reloads
62- **File-based**: Next.js, Nuxt, SvelteKit, Remix — filesystem structure defines routes
63- **Server-side**: Traditional MPA routing — each URL is a server request
64
65### State Management
66- **Local state**: React useState/useReducer, Vue ref/reactive, Svelte stores, Angular signals
67- **Global state**: Redux, Zustand, Pinia, NgRx, Jotai, Valtio
68- **Server state**: TanStack Query, SWR, Apollo Client — treats server data as a cache
69- **URL state**: Search params as state (Remix philosophy)
70
71### Data Fetching
72- **Client-side**: fetch/axios from useEffect, TanStack Query, SWR
73- **Server-side**: Next.js Server Components, Remix loaders, Nuxt useFetch, SvelteKit load
74- **GraphQL**: Apollo Client, urql, Relay
75- **Real-time**: WebSockets, Server-Sent Events, tRPC subscriptions
76
77### Code Splitting
78- **Route-based**: React.lazy + Suspense, dynamic import()
79- **Component-based**: Loadable Components, Vue async components
80- **Framework-managed**: Next.js automatic splitting, Vite's chunk optimization
81
82### Hydration
83- **Full hydration**: Entire page re-rendered on client (React SSR, Next.js)
84- **Partial hydration**: Only interactive parts hydrate (Astro Islands)
85- **Progressive hydration**: Components hydrate on visibility/interaction
86- **Resumability**: Skip hydration entirely, serialize state (Qwik)
87
88## Framework Landscape
89
90| Framework | Type | Rendering | Language |
91|-----------|------|-----------|----------|
92| **React** | Library | SPA, SSR (via Next.js) | TypeScript/JSX |
93| **Vue** | Framework | SPA, SSR (via Nuxt) | TypeScript/SFC |
94| **Angular** | Framework | SPA, SSR (Angular Universal) | TypeScript |
95| **Svelte** | Compiler | SPA, SSR (via SvelteKit) | TypeScript/Svelte |
96| **Solid** | Library | SPA, SSR (via SolidStart) | TypeScript/JSX |
97| **Astro** | Meta-framework | Islands, SSG, SSR | Any (React, Vue, Svelte, etc.) |
98| **Next.js** | Meta-framework | SSR, SSG, ISR, RSC | TypeScript/React |
99| **Nuxt** | Meta-framework | SSR, SSG, ISR | TypeScript/Vue |
100| **Remix** | Meta-framework | SSR, SPA mode | TypeScript/React |
101| **SvelteKit** | Meta-framework | SSR, SSG, SPA | TypeScript/Svelte |
102
103## Architecture Decision Guide
104
105| When You Need... | Choose |
106|-----------------|--------|
107| Rich interactivity, dashboard-style UI | SPA (see `dev/frontend/spa`) |
108| SEO + interactivity, content sites | SSR (see `dev/frontend/ssr`) |
109| Static content with occasional interactivity | Islands (Astro) |
110| Offline support, native-like experience | PWA (see `dev/frontend/pwa`) |
111| Multiple teams, independent deployment | Micro-frontends (see `dev/frontend/micro-frontends`) |
112| Blog, documentation, marketing pages | SSG (Next.js, Astro, or Hugo) |
113| Full-stack with tight server integration | Remix or SvelteKit |
114
115## Performance Budgets
116
117A well-architected frontend should target:
118- **Largest Contentful Paint (LCP)**: < 2.5s
119- **First Input Delay (FID)**: < 100ms
120- **Cumulative Layout Shift (CLS)**: < 0.1
121- **Total JS bundle (initial)**: < 200KB gzipped
122- **Time to Interactive (TTI)**: < 3.5s on 4G
123
124## Best Practices
125- Choose the simplest architecture that meets your requirements — not every app needs SSR or micro-frontends.
126- Measure performance with real user metrics (Core Web Vitals), not just Lighthouse scores.
127- Use code splitting aggressively — no user should download JavaScript they will never execute.
128- Treat server state and client state differently — use TanStack Query or SWR for server state, not Redux.
129- Design for progressive enhancement — the page should be usable before JavaScript loads.
130- Consider the Islands Architecture for content-heavy sites that need sprinkles of interactivity.
131
132## Sub-Skills
133- `dev/frontend/spa` — Single Page Applications: client-side routing, state management, bundle optimization
134- `dev/frontend/pwa` — Progressive Web Apps: service workers, offline support, installability
135- `dev/frontend/micro-frontends` — Micro-Frontend Architecture: Module Federation, single-spa, composition
136- `dev/frontend/ssr` — Server-Side Rendering: SSR, SSG, ISR, Islands, React Server Components