MPAs vs. SPAs

Understanding the tradeoffs between Multi-Page Application (MPA) and Single-Page Application (SPA) architecture is key to understanding what makes Astro different from other web frameworks like Next.js and Remix.

A Multi-Page Application (MPA) is a website consisting of multiple HTML pages, mostly rendered on a server. When you navigate to a new page, your browser requests a new page of HTML from the server. Astro is an MPA framework. Traditional MPA frameworks also include Ruby on Rails, Python Django, PHP Laravel, Wordpress, and static site builders like Eleventy or Hugo.

A Single-Page Application (SPA) is a website consisting of a single JavaScript application that loads in the user’s browser and then renders HTML locally. SPAs may also generate HTML on the server, but SPAs are unique in their ability to run your website as a JavaScript application in the browser to render a new page of HTML when you navigate. Next.js, Nuxt, SvelteKit, Remix, Gatsby, and Create React App are all examples of SPA frameworks.

Astro is an MPA framework. However, Astro is also unique from other MPA frameworks. Its main difference is that it uses JavaScript as its server language and runtime. Traditional MPA frameworks would have you write a different language on the server (Ruby, PHP, etc.) and JavaScript on the browser. In Astro, you’re always just writing JavaScript, HTML and CSS. That way, you can render your UI components (like React and Svelte) on both the server and the client.

The result is a developer experience that feels a lot like Next.js and other modern web frameworks, but with performance characteristics of a more traditional MPA site architecture.

There are three main differences to be aware of when comparing MPAs vs. SPAs:

Server rendering (MPA) vs. client rendering (SPA)

Section titled Server rendering (MPA) vs. client rendering (SPA)

In MPAs, most of your page’s HTML is rendered on the server. In SPAs, most HTML is rendered locally by running JavaScript in the browser. This has a dramatic impact on site behavior, performance, and SEO.

Rendering your HTML in the browser may sound like the faster option vs. requesting it from a remote server. However, the opposite is true. An SPA will consistently perform slower on first page load vs. an MPA, unless server rendering is used. This is because an SPA needs to download, parse, and run an entire JavaScript application in the browser just to render any HTML on the page. Then, your SPA will likely need to fetch remote data anyway, introducing even more wait time before your page is finished loading.

Most SPA frameworks will attempt to mitigate this performance problem by adding basic server rendering on the first page load. This is an improvement, but it introduces new complexity due to the fact that your website can now render in multiple ways and in multiple environments (server, browser). This also introduces a new “uncanny valley” problem where your site appears loaded (HTML) but is unresponsive since the application JavaScript logic is still loading in the background.

MPAs render all HTML on a remote server and often don’t require much (if any) JavaScript to run. This gives MPAs a much faster first load experience than SPAs, which is essential for content-focused websites. But this comes with a tradeoff: future page navigation can’t benefit from local rendering, so long-lived user experiences won’t benefit as much after the first page load.

Server routing (MPA) vs. client routing (SPA)

Section titled Server routing (MPA) vs. client routing (SPA)

Where does your website router live? In an MPA, every request to the server decides which HTML to respond with, so the routing logic lives in the server. In a SPA, your router locally runs in the browser and hijacks any navigation to render the new page without ever hitting a server.

This is a similar tradeoff to the one described above: MPAs offer a faster first load experience, while SPAs may offer a faster second or third page load once the JavaScript application is fully loaded in the browser.

SPAs can also offer more powerful transitions across page navigation because they control so much about page rendering. To match this support, MPAs leverage tools like Hotwire’s Turbo that mimic client routing by also controlling navigation in the browser. The HTML is still rendered on the server, but Turbo can now display a seamless transition between pages similar to client routing in an SPA.

Server state management (MPA) vs. client state management (SPA)

Section titled Server state management (MPA) vs. client state management (SPA)

SPAs are the superior architecture for websites that deal with complex, multi-page state management (think: Gmail). This is because an SPA runs the entire website as a single JavaScript application, which lets the application maintain state and memory across multiple pages. Interactive, data-driven experiences like inboxes and admin dashboards do well as SPAs because the website itself is inherently “app-like”.

When comparing MPAs vs SPAs, there is no “better” or “worse” choice. It all comes down to tradeoffs.

Astro prioritizes the performance and simplicity of MPAs because it makes the most sense for our usecase of content-focused websites. More stateful, interaction-heavy websites may benefit more from the app-like architecture that SPAs bring at the expense of first-load performance.

Below are all of the public Astro comparisons that we are aware of:

If you know a public migration or benchmark and don’t see it listed here, please create a PR to add it.

If you’d like to learn more, Surma (Google) and Jake Archibald (Google) recorded a great back-and-forth discussion on this exact topic.