Why SPAs Took Over —
and Why the Web Is Looking Back

The single-page application was not simply a phase where the web got carried away with JavaScript. It was a serious answer to a real problem: people wanted the web to feel less like a stack of documents and more like software. The current return to HTML is not a retreat. It is the frontend world asking a better question: what should run in the browser, and what should never have left the server?

Was the SPA just “too much JavaScript”?

These days, the phrase single-page application can make people pause. Many of us have lived through the same symptoms: a blank screen while the bundle loads, a loading spinner that feels too proud of itself, a page that needs a full framework just to display a paragraph, a Lighthouse score that quietly judges every decision we made last sprint.

It is tempting to tell the story as a simple morality play. First, the web was clean and document-based. Then JavaScript frameworks took over. Then everyone realized the mistake and went back to HTML. That version is tidy, but it misses the reason SPAs became popular in the first place.

SPAs were not born because developers hated HTML. They were born because the classic request-response rhythm of the web started to feel too slow, too interruptive, too page-shaped for the kinds of products people were trying to build. If every click means throwing away the entire screen and asking the server for a new one, certain interfaces feel clumsy from the start. Email clients, maps, dashboards, chat apps, collaborative tools — these are not pages you merely read. They are places where state changes constantly.

The SPA did not reject the web because it disliked documents. It changed the web’s rhythm because applications needed a different beat.

When I started building websites, “page” was still the most natural unit of thought. There was a home page, a list page, a detail page, a contact page, a confirmation page. Designers designed screens. Engineers wired templates. The user moved through the site like rooms in a building.

Then products like Gmail and Google Maps changed the feeling of what a web page could be. You did not simply move from one document to another. You stayed inside an environment. Messages appeared, labels changed, maps moved under your cursor, search suggestions arrived while your fingers were still typing. The web was no longer only a publication medium. It was becoming an operating surface.

💡 Perspective
The most useful way to understand SPAs is not “HTML versus JavaScript.” The deeper question is whether a web experience behaves primarily as a document to be delivered or as an environment whose state keeps changing.

Ajax opened the door to the web without full page reloads

To understand the SPA, we need to go back to Ajax. In 2005, Jesse James Garrett published “Ajax: A New Approach to Web Applications,” giving a name to a pattern that was already becoming visible in products such as Google Suggest and Google Maps. Ajax was not one single technology. It was a way of combining JavaScript, XMLHttpRequest, DOM manipulation, CSS, and asynchronous communication so that a browser could talk to a server without replacing the whole page.

That sounds ordinary now. At the time, it changed the texture of the web. Before that shift, many interactions felt like submitting paperwork. You clicked, waited, watched the page blink, and received a new document. With Ajax, the page could stay alive. Part of it could update. A suggestion list could appear. A map could pan. A message could be saved in the background.

Google Maps, launched in 2005, is still one of the clearest examples. Older web mapping tools often felt like a sequence of static images. Move the map, wait for a new image. Zoom in, wait again. Google Maps made the web feel physical. You dragged the map, and the world moved with your hand. For web designers and frontend developers, that was not just a feature. It was a challenge: why should the rest of the web feel so stiff?

1999
XMLHttpRequest begins inside Internet Explorer

Microsoft introduced an early form of asynchronous communication for products such as Outlook Web Access, planting the seed for what would later become Ajax-style interaction.

2004
Gmail makes the web feel like software

Gmail showed that reading, searching, labeling, and managing email could happen with far fewer full page transitions than users expected from the web.

2005
Jesse James Garrett names Ajax

Garrett’s essay gave a shared language to a new approach to web applications, with Google Suggest and Google Maps as visible examples.

2010
AngularJS brings structure to large browser apps

AngularJS popularized ideas such as data binding, client-side routing, and application architecture inside the browser.

2013
React is released

React reframed UI as a function of state and helped make component-based development the dominant mental model of frontend work.

2014
Vue.js appears

Vue offered a gentler path into component-based interfaces and found a home in many production teams and design-heavy websites.

The important shift was not just technical. It changed what frontend developers had to think about. In the old model, many temporary states were hidden between pages. After Ajax, they became visible parts of the interface: loading, saving, failed, empty, authenticated, unauthenticated, stale, optimistic, offline. The web page became less like a printed sheet and more like a living system.

After Ajax, the page stopped being the main character. State took its place.

What SPAs solved — and what they quietly broke

The promise of the SPA was easy to understand. Load the application shell once. Fetch data through APIs. Change the interface in the browser without asking the server for a new HTML document every time. For products where users stay for a long time and keep interacting — dashboards, admin panels, project management tools, chat clients, design tools — this model made real sense.

It also changed how teams built interfaces. Instead of scattering behavior across templates and small scripts, developers could model the UI as a tree of components. A button was not just markup. A modal was not just a hidden block in the DOM. A page was a composition of smaller pieces, each responding to state. React, Vue, Angular, and later Svelte all helped make this way of thinking feel natural.

SERVER-RENDERED WEB
HTML arrives first

The server sends a complete document. Links, forms, headings, and browser behavior work with the grain of the web. The first useful thing the user receives is often readable HTML.

CLIENT-SIDE SPA
JavaScript builds the screen

The browser downloads code, fetches data, and creates the UI on the client. This can support rich interaction, but it makes performance, SEO, accessibility, and loading states more delicate.

The trouble began when the SPA model escaped the places where it was strongest. Not every website is a long-running application. A company site, a media article, a documentation page, a campaign landing page, a restaurant menu — these experiences often need to be found, opened, read, shared, and understood quickly. They benefit from the old strengths of the web: URLs, HTML, progressive loading, browser defaults, search engine readability, and accessibility semantics.

When we ship a large client-side application for a mostly static page, we ask the browser to do work the server could have done earlier. The user waits for JavaScript before seeing content that may have been known at build time. A crawler has to deal with a page that is not fully there until code runs. A screen reader may receive a document whose meaningful structure appears late. A slow phone becomes responsible for assembling a page that could have arrived already assembled.

Two different mental models
// In an SPA mindset, UI is produced from state
<App>
  {isLoading ? "Loading..." : <Article data={data} />}
</App>

<!-- In a document-first model, meaningful HTML arrives first -->
<article>
  <h1>Why did SPAs become popular?</h1>
  <p>The reader can start here, before any extra behavior loads.</p>
</article>

This is where the critique of SPAs often becomes too broad. The problem was not JavaScript itself. The problem was treating every experience as if it were an app. A checkout flow may need client-side state. A collaborative editor certainly does. But does a blog post need a client-side router before the first sentence can appear? Does a pricing page need a full hydration process before the user can read the plans?

The mistake was not using JavaScript. The mistake was making documents behave like applications when they only needed to be documents.

Why the frontend started moving back toward the server

The strange thing about modern frontend development is that it did not abandon frameworks when these problems became visible. Instead, the frameworks themselves began moving toward the server.

Next.js, Nuxt, SvelteKit, Remix, Astro — each takes a different path, but they all respond to the same pressure. We still want components. We still want rich interaction where it matters. We still want a pleasant developer experience. But we no longer want to send every responsibility to the browser by default.

Server-side rendering, or SSR, generates HTML on the server for each request. Static site generation, or SSG, creates HTML ahead of time during the build. Astro popularized the idea of Islands Architecture: send mostly static HTML, then hydrate only the interactive islands that truly need JavaScript. React Server Components push in a related direction by allowing parts of the component tree to run on the server, reducing what must be sent to the client.

📌 Note
Hydration is the process of attaching JavaScript behavior to HTML that has already been rendered. It is why a page can look ready but still need a moment before buttons, menus, or interactive components fully respond.

This movement is sometimes described as “going back to HTML,” but that phrase can sound too nostalgic. It is not a return to hand-coded pages and a rejection of modern tooling. It is more like a correction in architecture. HTML was never the weak part of the web. HTML is linkable, searchable, accessible, cacheable, streamable, and resilient in ways that pure client-rendered interfaces often have to work hard to recreate.

Modern frontend is not trying to eliminate JavaScript. It is trying to stop spending JavaScript where HTML would have done the job better.

This is why the present moment is more interesting than a simple anti-SPA backlash. The best ideas from the SPA era are not disappearing. Component thinking remains. Declarative UI remains. State management remains. The idea that interfaces should be composed from small, understandable parts remains. What is changing is the default location of work.

Should this component run in the browser, or can it render on the server? Should this page be generated at request time, or can it be built once and cached? Does this interaction need hydration immediately, or only when the user reaches it? These are not questions developers asked as often in the early SPA wave. Today, they are central to frontend architecture.

Before choosing a framework, ask what kind of experience you are building

SPAs became popular because the web was asked to do more than documents could comfortably do. That part of the story matters. Without the SPA era, we would not have the same vocabulary for components, local state, optimistic updates, client-side routing, or rich browser-based tools. Many of the products we use every day would feel slower, more fragmented, and less capable without those ideas.

But the web also lost something when the app model became too automatic. A document that could have been delivered as HTML became a loading sequence. A link that could have opened instantly became a route transition. A simple piece of content became dependent on a bundle, an API response, and a hydration step. Sometimes the result was powerful. Sometimes it was simply heavier.

The better lesson is not “never build SPAs.” It is “do not make everything an SPA by reflex.” A project management tool and a magazine article do not need the same architecture. A pricing page and a video editor do not ask the browser to do the same kind of work. A documentation site may need search and navigation enhancements, but it probably does not need to behave like a full client-side application before the first paragraph appears.

Before you choose React, Vue, Astro, Next.js, Nuxt, SvelteKit, or anything else, pause for a moment. Is this experience mainly a document that should arrive clearly, quickly, and durably? Or is it an application whose value comes from continuous interaction and changing state? That one question can make the frontend landscape feel less like a battle of tools and more like a set of architectural choices.

Takeaways

  • SPAs became popular because the web needed to support application-like experiences that traditional page reloads handled poorly.
  • Ajax, Gmail, and Google Maps changed expectations by showing that web pages could update, respond, and feel alive without full reloads.
  • SPAs are well suited to complex, stateful interfaces, but they can make content-heavy pages slower, harder to index, and more fragile than necessary.
  • Modern frameworks such as Next.js, Nuxt, Astro, Remix, and SvelteKit are not rejecting components; they are reconsidering where rendering work should happen.
  • The future of frontend work is not SPA versus HTML. It is deciding which parts of an experience should be delivered as documents and which parts should behave as applications.