SPA vs MPA vs Hybrid
A related but separate distinction from rendering strategies. How navigations work — full page reloads or in-place swaps — and why modern frameworks do both.
SPA vs MPA vs Hybrid
In one line: "How is HTML built?" and "What happens on navigation?" are two different questions. SPA, MPA, and Hybrid are answers to the second one.
Imagine you click a link from /home to /about.
- MPA (Multi-Page App): The browser tosses the current page in the trash and loads
/aboutfrom scratch. Brief white flash. New HTML. Page-reload feeling. - SPA (Single-Page App): The browser stays on the same HTML page the whole time. JavaScript fetches the
/aboutcontent, swaps it into the existing DOM. No reload. Instant feeling. - Hybrid: First visit is MPA (server sends real HTML). Subsequent navigations within the site are SPA-style (JavaScript handles them).
Almost every modern framework defaults to Hybrid.
MPA — Multi-Page Application
Every navigation is a full page load. The browser requests /about, the server sends a new HTML page, the browser tosses the current page and renders the new one.
This is how the web worked from 1993 to ~2010 and how most content sites still work.
Pros:
- Simple mental model — every URL is a real page.
- Browser back/forward works perfectly.
- SEO is automatic (every URL returns full HTML).
- Smaller bundle size — no client-side router.
Cons:
- Each navigation feels heavier (white flash, asset re-downloads).
- Shared state (like a music player) gets reset on every navigation.
- No app-like persistence between pages.
SPA — Single-Page Application
The browser loads one HTML page at the start. All subsequent "navigations" are simulated: JavaScript updates the URL (using the History API) and swaps content in place.
Pros:
- Instant navigation after initial load.
- Persistent state across "pages" (music keeps playing while you browse).
- App-like feel.
Cons:
- Slow first load (need to download the JS bundle).
- Breaks browser features if implemented carelessly (back button, scroll position, focus management).
- Bad SEO without extra work.
- More complex to build and debug.
Hybrid — The 2026 Default
Modern frameworks (Next.js, Nuxt, SvelteKit, Remix) do both:
- First request: Server renders HTML (SSR or SSG).
- Subsequent navigations: Client-side router takes over, fetches only the data needed for the new page, swaps content.
You get fast first paint, good SEO, and snappy navigation — all without choosing.
Open https://nextjs.org (a Hybrid app).
- First request to
/: Server returns fully-formed HTML. You see the page immediately. ~100ms. - Click "Docs": No white flash. The URL changes to
/docs. Content swaps in place. ~50ms. - Click "Examples": Same — instant, in-place.
- Open a new tab and visit
/docsdirectly: Server returns fully-formed HTML again. Still ~100ms. SEO and direct-URL access work perfectly.
You get the best of MPA (real HTML on every URL) and SPA (instant navigation within the app).
How the two questions relate
| Rendering strategy | Navigation style | Common together? |
|---|---|---|
| SSG | MPA | Astro default |
| SSG | SPA | Older Gatsby apps |
| SSG | Hybrid | Modern Astro with view transitions |
| SSR | MPA | Traditional Rails, Django |
| SSR | SPA | Rare — defeats the purpose |
| SSR | Hybrid | Next.js, Remix, SvelteKit (the dominant 2026 combo) |
| CSR | SPA | Vite + React/Vue (internal tools) |
| CSR | MPA | Doesn't really exist |
This page taught you the vocabulary. You don't actually need to choose between SPA, MPA, and Hybrid on day one — the framework you pick chooses for you.
- Use Next.js or Remix → you get Hybrid by default.
- Use Astro → MPA by default, Hybrid optionally.
- Use Vite + React alone → SPA by default.
Pick a framework first; the SPA-vs-MPA decision falls out naturally from that choice.
Common mistakes
- Conflating "SPA" with "CSR" and "MPA" with "SSR." They're orthogonal axes. SSR + SPA-style navigation is a real combo (Next.js, Remix). SSG + MPA navigation is a real combo (default Astro). Mixing the vocabulary leads to muddled architecture conversations.
- Breaking the browser back button. A SPA that updates the URL but doesn't push to the History API correctly — or one that restores scroll position to the top on every back navigation — feels broken even though every page loads instantly. Test back/forward as a first-class flow, not an afterthought.
- Letting client-side navigation skip critical refreshes. In a SPA, mounting a "new page" doesn't actually re-run the whole module — stale data, leftover event listeners, and persistent timers can leak between routes. Treat route changes as a lifecycle event, not a free re-mount.
- Adding a SPA router to a content site that doesn't need one. A blog has nothing to gain from instant in-place transitions and everything to lose: bigger bundle, harder SEO, more bugs. If the site is essentially documents, MPA (or Hybrid with view transitions) is simpler and better.
- Assuming Hybrid means "no first-paint problem." Hybrid is fast on the first request because the server returns real HTML, but the hydration bundle still has to load before anything is interactive. A heavy
_app.tsxor root layout can still produce a 3-second Time-to-Interactive even though FCP looked great.
Page checkpoint
Did SPA vs MPA vs Hybrid stick?
RequiredWhat's next
→ Continue to REST APIs where we shift from rendering HTML to the other major thing web servers do: serve raw data.