Skip to main content
Engineering 8 August 2026 · 8 min read

SPA, MPA, or islands? Choosing a web app architecture in 2026

The web-app-vs-website distinction has quietly collapsed. What's replaced it is a smaller, sharper set of choices that most teams still model badly. Here's the version we use.

PI

Parth Infotech engineering practice

Parth Infotech

Five years ago, “we’re building a web app” meant one thing: a React SPA against a JSON API, with the whole app booted client-side on first load. That was the default even when it was the wrong default.

In 2026, the default is more nuanced — and that’s a good thing. But teams that picked SPA out of habit five years ago are now picking Next.js out of habit, and neither reflex is thoughtful. Here’s the version of the decision we actually run in scoping calls.

The four viable shapes in 2026

1. Pure SPA (Vite + React / Vue / Svelte)

  • Everything client-side after first load.
  • Static hosting, no server runtime required.
  • Best fit: internal admin tools, dashboards, authenticated apps where SEO is irrelevant.
  • Weak fit: anything public-facing where crawlability and initial paint matter.

2. Server-side rendered (Next.js, Nuxt, SvelteKit)

  • Server renders HTML per request (or per build for static routes).
  • Best fit: hybrid content + app (a marketing site with an authenticated dashboard behind login).
  • Weak fit: highly interactive apps where the SSR overhead adds no user value — just deploy complexity.

3. Islands architecture (Astro, Fresh, Enhance)

  • Most of the page is static HTML. Interactive components (“islands”) ship JS only where needed.
  • Best fit: marketing sites, content sites, docs, portfolios, mostly-static pages with occasional interactivity.
  • Weak fit: apps where every page is heavily interactive — the islands model becomes overhead without benefit.

4. Multi-page app with progressive enhancement (Rails, Django, Laravel + HTMX / Hotwire / htmx-style)

  • Server renders full pages. Small doses of JS layer on interactivity.
  • Best fit: CRUD apps with real backend logic, teams that don’t want a separate frontend/backend split, latency-tolerant workflows.
  • Weak fit: apps that need genuinely offline capability or heavy client-side state.

The five questions that decide

1. What percentage of users hit the page from Google?

  • > 40% → SSR or Islands. Anything else costs you traffic.
  • 10–40% → SSR is safer; SPA is fine if you SSR the marketing surface separately.
  • < 10% (internal / auth-only) → SPA is fine, and probably faster to build.

2. How interactive is the interactive part?

  • Mostly reads with occasional writes (docs, content, catalogues, marketing) → Islands.
  • Mostly writes with heavy client state (dashboards, editors, admin panels) → SPA or SSR-with-hydrated-islands.
  • Simple CRUD → MPA + HTMX/Hotwire — you’ll be shocked how far this scales.

3. What’s the team shape?

  • One team, full-stack, TypeScript-fluent → Next.js. Cross-boundary work is cheapest.
  • Split frontend/backend, backend not JS → SPA + JSON API. The interface boundary is well-understood.
  • Small team, backend-strong (Rails, Django, Laravel, ASP.NET) → MPA + progressive enhancement. Skip the SPA overhead.
  • Content-heavy site with a CMS → Islands (Astro). It compiles content beautifully.

4. How stringent is the performance budget?

  • CWV metrics matter for business KPIs (ecommerce, media, marketing) → Islands or MPA. Both beat SPAs and SSR on real-user LCP by default.
  • Internal tool with fast Wi-Fi → SPA is fine.
  • Users on 3G in rural India → MPA or Islands. Do not ship a 300kB JS bundle before first interaction.

5. What’s the SEO story?

  • Public content, needs to rank → SSR or Islands. Don’t argue.
  • Behind login → SPA.
  • Mix → SSR the public routes, SPA (or SSR) the app.

The trap teams fall into

Every 18 months a new default gets marketed as “the right way.” Teams migrate to it, discover the new sharp edges, and quietly wish they’d stayed put.

Two consistent mistakes we see:

Trap 1: SSR because SEO — for an authenticated app

A team builds an internal SaaS tool. Every route is behind login. They pick Next.js because “you want SSR for SEO.” They now have a server runtime to deploy, ISR to reason about, and hydration mismatches to debug — for zero SEO benefit because no route is public.

If your app is behind login, SEO is not a factor. Use a pure SPA. Deploy static hosting. Skip the server.

Trap 2: SPA because “it’s an app” — for a content site with a form

A team is building a public marketing site with a contact form and a two-page dashboard behind login. They pick React SPA because “there’s interactivity.” They ship a 400kB bundle that flashes empty on first load, tanks LCP, and their CMS-driven content is invisible to crawlers.

If 95% of the surface is content, use Astro (Islands). Interactive component? Ship a React island where needed. Everything else stays as fast, crawlable HTML.

What we default to per project shape

Absent specific constraints:

  • Marketing site + blog + occasional interactivityAstro (Islands). This site is built this way.
  • B2B SaaS dashboard, authenticated, real client stateReact SPA with Vite + TanStack Query. Fewer moving parts than Next.
  • Content-heavy site with an authenticated app on topNext.js App Router. The one architecture Next.js is unambiguously good at.
  • Rails / Django / Laravel monolith with growing frontend needsHTMX or Hotwire in-place, add React islands only where genuinely interactive.
  • EcommerceNext.js with proper Product/Category ISR, or Shopify Hydrogen if you’re on Shopify.
  • Public-facing content platform (docs, media, blog)Astro or 11ty. Every SPA choice here is a regret waiting to happen.

The runtime cost question nobody wants to talk about

There’s a hidden variable in this decision: how much runtime infrastructure are you willing to operate?

  • SPA + static hosting — S3, Cloudflare Pages, Netlify. Cheap, boring, scales infinitely.
  • SSR on the edge (Cloudflare Workers, Vercel Edge) — moderate ops, pay-per-request, great DX.
  • SSR on Node/Bun servers — real ops. Autoscaling, memory monitoring, cold starts.
  • MPA on Rails/Django/etc. — traditional ops, well-understood, boring in the best sense.
  • Islands (Astro built static) — cheap like SPA static, but with an option to add server islands where needed.

If your team doesn’t have a dedicated ops person, avoid architectures that require you to babysit long-running Node processes. There are good options that don’t.

Two things about “server components” and streaming

One: React Server Components + streaming are legitimately excellent for the class of app they’re designed for — data-heavy interfaces where the server can compose the response faster than the client can wait for a JSON round-trip. This is not every app. It’s a specific pattern. Don’t retrofit your CRUD app into RSC because the framework is pushing it.

Two: if you don’t have a real backend already (Rails, Django, Node with domain logic), you’re going to reinvent one inside your Next.js /app directory. That’s fine, but scope it as building a backend. Don’t pretend the framework did it for free.

The three-question shortcut

If you’re two days from picking and don’t have time for a long process:

  1. Is 50%+ of traffic from search? If yes → SSR or Islands. Skip SPA.
  2. Is the page mostly content or mostly app? Content → Islands. App → SPA or SSR.
  3. Does the team have ops capacity for a server runtime? No → static-hosted (SPA or built Islands). Yes → SSR or MPA.

That’s usually enough to make the right call. The rest is nuance.

Where we actually build

Our last twelve web projects: 5 Astro (marketing sites, docs, portfolios), 3 Next.js (mixed content + app), 2 React SPA + Vite (auth-only dashboards), 1 SvelteKit (a client with strong Svelte preferences), 1 Rails 7 + Hotwire (a client with an existing Rails backend).

Zero angular preferences here — we’ve shipped in all frameworks. The distribution above is what our clients’ problems mapped to, not what our team wanted to work in.

Related: The solution architect’s checklist for enterprise projects for how architecture calls like this fit into a bigger delivery structure.

If you’re picking a web architecture, we’re happy to sit in the scoping call.

Tags

  • #Web
  • #Architecture
  • #SPA
  • #SSR
  • #Islands
  • #Next.js
  • #Astro

Have a project in mind?
Let's see if we're the right fit.

A 30-minute call with a senior engineer — free, no sales pitch. We'll tell you honestly whether we can help.