It's time for modern CSS to kill the SPA
303 comments
·July 25, 2025codingdave
jbreckmckye
This article is full of misrepresentations and lazy takes. The author has had other anti-JS polemics widely upvoted on HN, which were just as carelessly written. But people upvote it anyway.
What is the cause of this?
1. Bad experiences with JavaScript apps that have aggregated complexity (be it essential or incidental complexity)?
2. Non-JS developers mystified and irritated at a bunch of practices they've never really internalised?
3. The undercurrent of "frontend is not real programming" prejudice that existed long before React etc al. and will continue to exist long after it?
cleoxjefbjxis
You miss the whole point and the author is correct about this:
Modern CSS is powerful, and HTML is the way to deliver web content.
Every web framework is _literally_ a hack to make the web something it isn’t. People who haven’t seen the evolution often pick up the bad habits as best practice.
For thise JavaScript people, I recommend trying Laravel or Ruby/Rails. And then once you realize that JavaScript sucks you’ll minimize it.
cheema33
> ...if you shared that misunderstanding of SPAs and used them to solve the wrong problem, this article is 100% correct.
Agreed. The article was a frustrating read. The author is an SEO consultant. SEO consultants likely have a heavy focus on marketing websites. Actual apps and not marketing websites do benefit significantly from SPA. Imagine building Google Maps without SPA. You can animate page transitions all you want, the experience will suck!
Tokumei-no-hito
to be fair to both points:
he has a really warped view that SPAs are somehow purely about routing.
he does correctly point out that a lot of sites could and should be treated as sites not apps.
pyman
App development evolves, just like browsers do. The author's point is that browsers have finally caught up and understood why SPAs were created in the first place, which involves recreating some of the functionality they already offer today. (That doesn’t mean all SPAs should turn into MPAs now)
IMO it will be hard for some sites to adapt to the new browser capabilities, since we've built an entire ecosystem around SPAs. But the author's advice is: use the browser's built-in capabilities instead of client-side libraries whenever possible.
Also, keep in mind he's sharing his own experience, which might be different from ours. I've used some great SPAs and some terrible ones. The bad ones usually come down to inexperience from developers and hiring managers who don't understand performance, don't measure it, don't handle errors properly, and ignore edge cases.
Some devs build the SPA and leave behind a horrible UX and tech debt the size of Mount Everest. If you don't know much about software architecture, you're more likely to make mistakes, no matter what language or framework you're using.
I realised years ago there's no "better" language, framework, platform, or architecture, just different sets of problems. That's why developers spend so much time debating implementation details instead of focusing on the actual problems or ideas. And that's fine, debates can be useful as long as we don't lose sight of what we're trying to solve and why.
danielscrubs
I 100% would like to see an MPA Google Maps.
Being able to come back to a webpage with previous directions? I think it would be glorious.
pas
You are mixing up linkability/history and being an MPA/SPA.
Many websites simply have some session/state dependent page.
simonw
I have one of those!
https://datasette-tiles-demo.datasette.io/-/tiles/basemap?no...
I wish I could take full credit but it was a PR by dracos: https://github.com/simonw/datasette-tiles/pull/16
luis_cho
The author states that MPA are not a solution for everything. Sure google maps don’t fit the MPA model but I’ve seen a lot of projects that would be much better using current browser features instead of react.
tanduv
the web app already supports history navigation.
cosmotic
Google maps is a mess these days. Its glitchy, slow, has broken navigation, and is overloaded with unpredictable dynamic content. It's even worse in the native android app. Id totally go for the original version but with the more recent vector maps.
scott_w
The reasons it sucks are nothing to do with it being an SPA, though.
Cthulhu_
> and load up a giant pile of jQuery spaghetti
I'll have you know I spent time on organizing and structuring my code with early JS design patterns like IIFEs to limit scope, lazy loading of modules, and minification.
Anyway, in my experience, AngularJS was the biggest attempt at making structured front-end applications, and it really appealed / appeals (Angular is still very popular apparently) to Java developers; biggest ones was its modularization (which wasn't a thing in JS yet), dependency injection, and testability.
When we started out with an app in Backbone (to replace a Flex app because it wouldn't work on the ipad), I actually advocated against things like testing, thinking that the majority of functionality would be in the back-end. I was wrong, and the later AngularJS rebuild was a lot more intensive in front-end testing.
Of course, nowadays I'm repulsed by the verbosity, complexity and indirection of modern-day Angular code. or Java code for that matter.
aryonoco
Angular not only appeals to Java developers, it also appeals to .NET developers. TypeScript of course borrowed a lot from C# (having the same designer) and dependency injection, MVC patterns etc closely resemble .NET patterns.
Interestingly, new Angular is slowly moving away from these, introducing Signals for state management and standalone components, and I see these developers actually struggling a lot to adopt new Angular patterns.
Still, I believe Angular is a really great platform for building B2B or enterprise apps. It’s testing and forms handling is far ahead of every other SPA, and it actually fees like a cohesive framework where people have spent time designing things the right way; something I absolutely cannot say about react frameworks such as Next.js or Remix.
youngtaff
Angular was created so Java developers could create browser apps
paradox460
Wasn't there the Google closure compiler before angular?
aryonoco
PS and I forgot to mention, new Angular patterns such as Signals and standalone components great cut down on the boilerplate and the verbosity. It’s not (and will never be) something like SolidJS, but each new version is clearly moving away from the heavy OO-based and multi layered patterns.
TimTheTinker
Low-bandwidth/spotty connections (combined with aggressive caching) are one of the strongest cases in favor of SPAs (emphasis on the A for Application, not website). Visit (and cache) the entire frontend for the app when you have a good-enough connection, then further use of the app can proceed with minimal bandwidth usage.
cosmic_cheese
It really depends. There’s a lot of SPAs which are practically unusable on a bad connection simply because it’s a challenge to even get the whole thing loaded in the first place. There’s been several occasions where I’ve had poor cell connectivity and a huge chunk of the web was effectively off limits due to this.
So in addition to aggressive caching, I’d say keeping the app’s file size down is also pretty important to making it useful on poor connections. That’s frequently something that’s barely optimized at all, unfortunately.
jaredklewis
I work on an SPA with hundreds of screens. We package it using off the shelf tooling with barely any configuration. All of the code and styling is still far under a megabyte gzipped.
So unless it is an all text app, the size of the code bundle is probably going to be quickly dwarfed by the size of media like images, animated images, or videos.
If a site has an SPA with a, say, 3mb code bundle, I think in most cases, that’s not an architecture issue. It’s probably an issue of poor engineering and switching to a MPA is not suddenly going to make those engineers competent.
tomnipotent
All three comments to this thread have missed the point that OP said installable SPA, not website SPA. This means the primary bundle is downloaded offline and only API network requests are necessary.
throw-the-towel
This is not true. In practice SPAs break completely when some network request fails which happens a lot on bad connections.
heisenbit
Sadly the art of error handling is often neglected by some SPA developers. I suspect that failures on the client are also less tracked this is tolerated by businesses.
wolpoli
Honest question: Where are the places with low-bandwidth internet? Are we talking about cruise ships and satellites internet use cases?
al_borland
Often times my house. I live in one of the 20 largest metro areas in the US. There is a cellular dead spot around my house, seemingly from AT&T and Verizon. Phones work, but barely. Pages with high data demands become a problem.
maccard
I live in the middle of a major UK city, which is one of the most visited tourist destinations in the UK (if not the world). There are massive gaps of mobile coverage in the city - 5G is spotty at best, and it regularly falls back to much older protocols in the city. There are dead zones where you can literally walk 6 ft and drop to 0 coverage, and walk another 6ft and be on full blown 5G. Apps and sites like uber, twitter, Reddit, instagram all handle these awfully.
tanduv
TBH even in the SF Bay Area "tech capital of the world" you'll find areas with spotty reception.
https://www.reddit.com/r/bayarea/comments/1cqhr4i/what_is_up...
paradox460
Anyone attending a major event, or in a disaster zone. Things are getting better, but if you live near a ball park or something, there will be periodic times when your cellular Internet is unusable
TimTheTinker
There are folks who work with US-based nonprofits, NGOs, and agencies who live all over the world, including regions where local internet access is either non-existent or very slow. Some US-based organizations they work with have had to set up low-bandwidth methods of communicating. Yes - sometimes geosynchronous satellites are the only connectivity available.
luis_cho
There is this post about a experiment on google where they reduced the page weight and the traffic went up instead of down. That was because it open the site to countries with low internet bandwidth https://blog.chriszacharias.com/page-weight-matters
jcpst
All over the world, including the United States.
tcfhgj
Everywhere, my provider limits me to 32 kbit/s
andix
Latency might even be more relevant than bandwidth. Especially if it's a good SPA, that uses optimistic updates (or sync), and some kind of caching for fetching data (tanstack query or similar).
matt_s
If you work at a place that has a modern CI/CD pipeline then your multiple deployments per day are likely rebuilding that large bundle of JS on deploy and invalidating any cache.
HTTP 2 has been adopted by browsers for like 10 years now and its multiplexing makes packaging large single bundles of JS irrelevant. SPA’s that use packaging of large bundles doesn’t leverage modern browser and server capabilities.
wldcordeiro
Lots of SPAs now are code-split too for what it's worth so you shouldn't really have large bundles to download if you're splitting things well.
paulryanrogers
Is this true everywhere? Isn't much of the world still on slow mobile networks?
yawaramin
Being on a slow mobile network and having to reload changing bundles multiple times a day to use SPAs would be an even worse UX.
youngtaff
> HTTP 2 has been adopted by browsers for like 10 years now and its multiplexing makes packaging large single bundles of JS irrelevant
H2 doesn’t make packing irrelevant… there’s still an IPC overhead with many small files… and larger bundles tend to compress better (though compression dictionaries might help here)
Large Js bundles are a huge problem though
QuadrupleA
Side note, sick of jQuery being always associated with spaghetti in the tech lexicon.
Any Turing-complete system is spaghetti in the hands of bad programmers. And simple & clear in the hands of good ones who know how to design.
bobthepanda
Jquery is good for dom manipulation, though most of the best ideas have become vanilla javascript standards.
It isn’t really equipped or opinionated on statefulness, which means that everybody was at one point kludging stuff onto it that didn’t make sense.
sverhagen
Languages... (is jQuery a language, I guess so, let's go with that)... live in a context... there is culture, tooling, libraries, frameworks. Some languages have good culture, some have bad culture. I guess it's not even so black and white: language have good or bad culture in different areas: testing, cleanliness, coding standards, security, etc. If jQuery is misused in the hands of bad programmers ALL THE TIME, that becomes the culture. Not much to do about it anymore once the concrete has set. You can't still be an exception to rules, good for you! But that doesn't change the culture...?
albedoa
> If jQuery is misused in the hands of bad programmers ALL THE TIME, that becomes the culture.
My bet is that everyone here both agrees with you and is able to replace "jQuery" with "HTML", "CSS", and "JavaScript" to reach similar conclusions about the cultures of each. The problem is bad programmers, not the tech.
wild_egg
> in exchange for having really small network requests after the load.
I'd love to see examples of where this is actually the case and it's drastically different from just sending HTML on the wire.
Most SPAs I've worked on/with end up making dozens of large calls after loading and are far far slower than just sending the equivalent final HTML across from the start. And you can't say that JSON magically compresses somehow better than HTML because HTML compresses incredibly well.
Most arguments about network concerns making SPAs a better choice are either propaganda or superstition that doesn't pan out in practice.
raron
> I'd love to see examples of where this is actually the case and it's drastically different from just sending HTML on the wire.
There are complete CAD applications running in browsers for PCB and mechanical design with many layers, 3D view, thousands of components, etc.
For example: https://easyeda.com/ https://www.onshape.com
> because HTML compresses incredibly well
Haven't compression under TLS have been mostly disabled after CRIME and BREACH attack?
niutech
No, HTTP compression is widely used (brotli increasingly).
null
8n4vidtmkvmk
With HTML you have to send both the template and the data. With json, it's just the data. So it's less information total. It should compress a little better, but I don't have stats to back that up.
maccard
HTML templates are still text, text compressed well. As with all these discussions “it depends, profile it” is the only answer. People blindly assuming that X is better is why things are slow and shitty in the first place
buffalobuffalo
I don't know if a bunch of sloppy jQuery modules were ever really a viable option for an SPA. People tried to do it, sure, but I'd say the SPA era really started with backbone.js
kassner
ExtJS/Sencha was quite powerful and complete. I’ve built tons of SPAs with it in the late 00s.
gjtorikian
Wow, I remember Sencha! It’s been a while since I’d heard that name.
null
dsego
I mostly remember doing $(document).ready blocks in php templates :)
zeroq
SPA is not only about seamless transitions but also being able to encapsulate a lot of user journey on the client side, without the need of bothering server too much.
Let me give you an example - one of my biggest gripes about web ux is the fact that in 2025 most shops still requires you to fully reload (and refetch) content when you change filters or drill down a category.
A common use case is when you come to a shop, click on "books" (request), then on "fantasy" subsection (another request), realize the book you're looking for is actually a "sci-fi", so you go back (request, hopefully cached) and go to "sci-fi" (another request).
It's much better ux when a user downloads the whole catalogue and then apply filters on the client without having to touch the server until he wants to get to the checkout.
But it's a lot of data - you may say - maybe on Amazon, but you can efficiently pack sections of most shops in data that will enable that pattern in less kilobytes that takes one product photo.
I've been building web apps like that since ca. 2005 and I still can't understand why it's not more common on the web.
da_chicken
I don't know, I think the most painful aspect of having to do a full reload is how I efficient the site is. The actual data is a few KB, but the page itself has to download 100 MB and the web browser is burning through a GB of RAM.
Like I don't find Hacker News to be egregious to navigate, and nearly every nav is a reload. It runs fine on my 2008 laptop with 4 GB of RAM.
But I go to DoorDash on the same device, and it takes 30s to load up a list of 50 items. They give you a countdown for a double dash, and I genuinely don't think it's possible to order some curry and get a 6 pack of soda in less than 3 minutes. And 2.5 minutes is waiting for it to render enough to give me the interface. Almost none of it is a full reload.
nine_k
An SPA can be lean and fast. React is the prevailing Web framework today? Preact is like 5 KiB of code.
What makes SPAs unwieldy is not the technology but the lack of desire to optimize. It loads fine on yesteryear's Macbook Air? Enough, push it.
I very well remember heavy, slow-loading websites of, say, year 2000, without any SPA stuff, even though lightweight, quick-loading pages existed even then, in the epoch of dial-up internet. It's not the technology, it's the desire to cram in more, and to ship faster, with least thinking involved.
thaumasiotes
> I very well remember heavy, slow-loading websites of, say, year 2000, without any SPA stuff, even though lightweight, quick-loading pages existed even then, in the epoch of dial-up internet.
Sure, lightweight, quick-loading pages existed, but sometimes you want to see a picture.
cosmic_cheese
Yeah, the enemy isn’t the need to reload, it’s reloading taking a long time due to too much garbage that’s not the content the user is interested in having to come down off the wire and render. A site that requires an occasional split second reload is always going to be preferred to a behemoth that doesn’t need reloading but has me staring at blank screens and loading spinners half the time I’m using it.
mym1990
Hmm, I would say comparing Hacker News to DoorDash is not exactly apples to apples. There may also be ulterior motives to make a website slow(or at least not optimized) if the company wants to funnel people towards an app on the phone.
dzhiurgis
Gmail takes 3s to load. And HN is a website, not an app.
xyzsparetimexyz
How is HN not an app? All the content is user generated. Everything is interactive. What's the difference?
paulryanrogers
> Gmail takes 3s to load
On a 2008 device, in 2025? On a mobile connection?
SenHeng
> It's much better ux when a user downloads the whole catalogue and then apply filters on the client without having to touch the server until he wants to get to the checkout.
This is what we[0] do too. We have a single JSON with a thousand over BOMs that's loaded directly into the browser. Previously we loaded the inventory data via an API as is usually expected. The fact that there's even an API meant requiring progress and loading bars, API unavailability scenarios, etc.
Having it all as a single preloaded JSON meant that all of the above goes away. Response is instantaneous.
[0]: https://chubic.com
Zanfa
Please no. Whenever I see an online store as a SPA catalogue I shudder, because it usually breaks after browsing a bit in a weird state. And it resets to somewhere random should you hit back, refresh or try to send a link to somebody.
mirkodrummer
Thing is, and I believe it's a valuable example counterpoint, if I shift-click on a link, like sci-fi category, to open it in a new tab(very common thing people do), having a multi page application is zero work added, on an spa you have to manage that. If the link doesn't exist and categories can only be accessed by a select input then ux isn't that great
paffdragon
This is so annoying when SPAs break browser functionality like open link in new tab. Even if it works often it has to reload a bunch of JS again, which makes things veeery slow. This is why I really don't like Linear, I often open issues in separate tabs, which is every time a pain, browser freezes for seconds just to open a link in a tab...
throwaway7783
HTMX (and similar) solves a lot of this. It so happens that we end up building two apps one frontend and one backend with SPAs as built today. I'd rather build a lot of it on the server side, and add some dumb interactivity on the client (show/hide, collapse/expand, effects). There is still a place for SPA though.
naet
HTMX does the opposite of this, it requires many more round trips to the server instead of using client side JS to do work.
aquariusDue
I find Datastar to be a better replacement for HTMX, especially now that it can also do plain requests instead of Server-Sent Events. You also don't need Alpine.js combined with HTMX anymore.
throwaway7783
I meant for the SPA-like experience.
ThatPlayer
In a similar use, a few of my hobby projects are hosted on static web servers. So instead of rendering out everything into individual pages, which would've been tens of thousands of pages, I have a JSON file that gets rendered by the client in a SPA. I have even used Github Pages for this
I'm playing around with a newer version that uses a sqlite database instead. Sqlite officially has wasm builds, and the database file is already built to be separated into pages. With HTTP Range Requests, I can grab only the pages I need to fulfill any queries.
Sqlite full text search even works! Though I'm hesitant to call that a success because you do end up grabbing the entire FTS table for shorter searches. Might be better to download the entire database and build the FTS table locally.
crazygringo
Generally speaking, companies don't want you to download their entire catalog. They don't want competitors to be able to analyze it easily like that.
And if a store is selling books, it might have hundreds of thousands of them. No, it's not a good experience to transfer all that to the client, with all the bandwidth and memory usage that entails.
zeroq
That's really weak argument.
If it's one their website the competitors can write a simple crawler and create that catalog.
And you don't have to send every single field you have in your database. Once the user selects a category you can send a metadata that enable the client to scaffold the UI. Then you cache the rest while user interacts with the site.
Barnes and Nobles - according to their FAQ - has 1 million unique items in their catalog. But they also have tons of different categories. A single book cover weights around 30kb.
I'll leave it as an excercise to figure out how much data you can fit into 30kb to make usable filtering system.
btw: opening their front page downloads 12.1MB already.
crazygringo
> I'll leave it as an excercise to figure out how much data you can fit into 30kb to make usable filtering system.
Into 30kb? That's just 300 items at 100 bytes each. So not a lot?
what
>I'll leave it as an excercise to figure out how much data you can fit into 30kb to make usable filtering system.
Not even 1 bit per item in the Barnes and nobles catalog? So not much.
ec109685
In almost all cases the back swipe in the spa resets you to the top of the page, navigating out of the app and back in doesn’t work, etc. It’s really hard to build a multi page spa that feels good.
zeroq
It's funny you've mentioned that.
It reminded me of the time when I joined Wikia (now Fandom) back in, I think it was 2006. One of the first things that landed on my desk was (I can't recall the context) deeplinking.
And I remember being completely flabergasted, as I came Flash/games background, and for us that problem was completely solved for at least 4 years at the time (asual swfaddress package). I felt kind of stupid having to introduce that concept to much more senior engineers that I was at the time.
dzhiurgis
Never thought about scroll position (tho SPA I’ve built recently I think does it ok). How do you solve it?
throwawaylaptop
I'm a self taught PHP/jQuery/bootstrap guy with a small saas. I handle page scroll position by literally saving it into some session data cookie and when you go back I check where your scroll was and I fix it for you. I'm not a genius or skilled... But I cared so I did it.
cyco130
I write some of my thoughts on this sone years ago. The library described at the end is now fairly out of date but the ideas and suggestions are still good, I think.
https://dev.to/cyco130/how-to-get-client-side-navigation-rig...
fleebee
Depends on what you're using for routing.
In Tanstack Router it's a boolean you set when creating the router. The documentation nicely lays out what's being done under the hood, and it's quite a bit.[1] I wouldn't try that at home.
In React Router you just chuck a <ScrollRestoration /> somewhere in your DOM.[2]
[1]: https://tanstack.com/router/v1/docs/framework/react/guide/sc...
[2]: https://reactrouter.com/6.30.1/components/scroll-restoration
wlll
It's time for sending HTML rendered on server with CSS, and JS for enhancement only to kill the SPA.
I'm not talking about this from a technical standpoint, though there are many reasons that in most cases this is the best technological fit.
I'm talking about this from the position of "what I want to use". I'm sick of loading and navigting overly JS heavy, overly styled, fragile "apps". When I encounter a "proper" website that loads fast, and I can understand easily it's like a breath of fresh air.
threatofrain
I don't know what universe this SEO-consultant author lives in. The author gives Next & Nuxt as an example of the kind of frameworks going against his prescription, but that is so wrong.
1. Next won the war in the west, big time. Very very big time. Whenever people talk about new React apps they inadvertently mean Next. On the Vue side Nuxt is the default winner, and Nuxt is just the Next of Vue. That means that by default, by reflexive instinct, people are choosing Next and MPA as their strategy. If you want to correct the overly extreme pendulum motion then you should be telling people to try out SPA. The last 8 years has been a feverish push for MPA. Even the Facebook docs point straight to Next, totally deprecating Create React App. This is also Facebook ceding their battle to Next.
2. Whenever people complain about the complexity of Next, they are complaining about the difficulties of cutting edge MPA strategy, which evolves on a year to year basis. SPA on the other hand is a story that has frozen in time for who knows how many years. Almost a decade?
3. Doing MPA is strictly harder than doing SPA, much much harder. You have to observe the server/client distinction much more closely, as the same page may be split down the middle in terms of server/client rendered.
4. If you're writing an SPA and want to be more like MPA and load data at the time of hitting a user-navigable endpoint, that's on you, benefits and costs and all. You can also load data with anticipation so the client navigation is basically instant.
5. For every sexy SEO-able front-facing property you're going to have many teams with internal apps or dashboards backing that front-facing property. That's where many React devs are employed. Do not unnecessarily take on burden because you're so eager to ship the first "frame" of your app in a perfect way.
null
ivape
There was a war? News to me. Saying Next won is like saying React won. Nothing won, everyone just latched on to what they thought the crowd vetted. The blind can't lead each other. Most people that stuck to Angular or minimal or no-frameworks are truly wondering what the fuck are all these people talking about?.
Even the Facebook docs point straight to Next
Startups and SV jerk each other off by promoting each other (think affiliates). None of it means shit.
Next is probably a garbage framework, but it's people's livelihoods. It's very hard to erase something that literally defines people (yes, your resume is YOU).
frollogaston
Kinda is a war unless you're working solo, cause you're gonna get forced to use something or another. When I tried a few solo web projects instead of just being a backend guy, I picked up React on my own because it was the only thing that makes sense. The page does what the code says. And that was after trying other things.
Now I gotta occasionally use Angular, and it's boilerplate hell. Adding one button involves editing 30 classes and files even if you don't use templates. I took a course at work where even the instructor got confused adding a button. Why would anyone ever use this besides Google, or do they even use it?
Tokumei-no-hito
in the world of frameworks it's obvious that
html in your JS > JS in your html.
angular is a mess. it's the java of web frameworks. if you want up be enterprise(tm) go for it. I’m convinced it's only a thing because it gives people job security since nobody else chooses to touch it.
threatofrain
> Startups and SV jerk each other off by promoting each other (think affiliates). None of it means shit.
No, this is FB ceding the battle. They absolutely didn't want this. They dropped CRA because social media celebrities were shitting on CRA. Dan Abramov had to do a complete 180 in a single day, after writing a long thoughtful essay in defense of CRA.
afavour
Wars, battles, personalities on social media… I don’t want to sound too much like a grouchy old man but these frameworks are tools. Nothing more than that. I can’t understand why anyone would become emotionally invested in any of them.
When starting a project the right move to examine what best fits your project, not which one was recently victorious in a war. I’ve grown to dislike React because I see it being abused so often for a site where it isn’t necessary. There are plenty of projects where it is necessary too, but that’s not universal.
ivape
You are in your own little universe. Social media celebrities shitting on React? I don't even want to enter your world.
"Bro, you should see the celebrities shitting on React"
Like WHO!? What developer celebrity, what universe have I been missing out on?
Anyway, I do love me a good ol' fashioned "fuck SPAs, back to HTML" punching bag post on HN. It's always the same discussion over and over.
nromiun
Lots of pushback here in the comments. But I can't think of the last time I enjoyed using a SPA website over a multi-page one. The initial loading feels delayed, the page scrolling feels unnatural and jarring (completely opposite of how a native app feels).
Also, one of my banks recently changed their old website to a new SPA one. And it is now completely useless. It can't load information in time, so most of the forms are empty. You can't even go back because it is a SPA. So I can only log out, log in and try again. Kind of scary when you are handling a lot of money.
And it is not just one website. As I said I can't recall ever using a good SPA website. So yeah, I can't wait until they are all gone.
kertoip_1
Yeah, the worst thing is when parts of the same application are under the hood different SPAs.
First example that comes to my mind: web version of ProtonMail. Going to settings feels like loading a completely separate website. Or OVH dashboard.
croes
You think bad programming is restricted to SPAs?
If they botch the back button in an SPA they will botch other things in an MPA
tossandthrow
> But I can't think of the last time I enjoyed using a SPA website over a multi-page one.
You likely don't even notice that most of what you browse are SPAs.
The reason why there is pushback is because the article is straight up misinformation.
nromiun
Actually the static address bar and the refresh button behavior makes it obvious.
markbao
The point of SPAs was never page transitions. I can’t name a single major SPA that does good page transitions, can you? They all just replace the content. And to take a popular SPA framework as an example, it’s almost impossible to do page transitions in Next.js because of the way routes are loaded. I know this because I added proper page transitions to Next.js and it has been an absolute nightmare.
There are two good reasons for SPAs that I can see:
1. Your app probably needs interactivity anyway; for most apps, it’s not just going to be HTML and CSS. Writing your app in some unholy combination of React and HTML is not fun especially when you need to do things like global state.
2. Loading the structure of pages up front so that subsequent data loads and requests are snappy. Getting a snappy loading screen is usually better than clicking and getting nothing for 500ms and then loading in; the opposite is true below I’d say 100ms. Not needing to replace the whole page results in better frontend performance, which can’t really be matched today with just the web platform.
Basecamp has probably invested the most in making a fairly complex webapp without going full SPA, but click around for like 30 seconds and you’ll see it can’t hold a candle in performance to SPAs, never mind native apps.
With that said, I agree that I’d want the web to work more like the web, instead of this weird layer on top. All the complexity that Next.js and SPAs have added over the years have resulted in more responsive but sometimes more tedious-to-build apps, and gigantic bundles. I just don’t think you can match the performance of SPAs yet with just HTML.
causal
3. APIs. If you already have a client facing API for your iOS and Android apps, and maybe one for developers, a SPA is just another app to plug into that backend.
pas
tiny correction Next is not an SPA (you can in theory write one using NextJS, but by default it's an MPA with aggressive prefetch)
dkarl
I think this article is unfair to SPAs. SPAs are a lot more effort, but they are better. For a long time they have been the only way to "make it feel like an app." (I think the author says "make it feel like an app" because they know we all resent app fatigue, all the apps we have to download that should just be web sites, but I think we also all know that when something really is an application, it's rare for a "web app" to match the experience of a local native application, and an SPA is the only way to make a sincere attempt.)
The comparison of bloated SPAs with lean web sites is bogus. If someone takes the effort to make their web site lean, they'd do the same with an SPA. If someone makes a slow, bloated SPA with megabytes of Javascript, they'd make a slow, bloated web site with megabytes of Javascript. I think we've all seen enough of the web to know this is true.
I click on articles like these because I've seen the effort that goes into a good SPA, and I'm interested in anything that would allow people to deliver an equivalent experience with less effort. All I see here is a tiny bit of cosmetic polish. Polish is appreciated, but this doesn't seem like something that would tip the balance between building an SPA or not. Am I missing something?
adamtaylor_13
“But they are better”
By what measure?
nfw2
Performance, developer experience, user experience
donatj
I'm sorry but what!? Have you talked to your users? The ones that actually are forced to use your app day in and out? They want functional back buttons, they want to be able to open any action in a new tab. No one who actually uses your product would prefer an SPA once the flash wears off.
Let me tell you as a developer who has been on both sides of things, developing server rendered pages and not having to worry about the server disagreeing with the client is the ultimate developer experience. Build a competent app that can serve full pages in .1 seconds and no one will care that your site isn't an SPA. They want a fast reliable site.
romanovcode
Developer experience - Yes, in most cases.
Performance - No, in most cases.
User experience - No, in most cases.
What are you talking about. Majority of SPAs have abysmal performance compared to regular HTML rendered websites and that reflects poorly on user experiences.
victorbjorklund
I see some people claim that client-side routing isnt the strongest argument for SPA:s. And that is probably true from a technical point of view. However, lots of times users/clients want that even if they dont care about the rest (which is why I love how easy HTMX and Astro make it to add client side routing on top of a normal MPA).
nosefurhairdo
This argument is tired and ignorant. Try building linear.app without a SPA framework. The idea that "Native CSS transitions have quietly killed the strongest argument for client-side routing," is dubious at best.
0xCMP
This doesn't seem fair to say. Linear is special even among SPAs; it's by far not the norm. No one said "ban SPAs and remove javascript from the browser".
Linear's speed comes from being "offline-first", but I challenge you to name almost any other product in common usage that does it that way. It's just not common. On the other hand if I want to buy tickets I'd rather most of that website be SSR and do SPA where you actually still need it. Or forums, news sites, blogs, and informational sites.
There is so much out there that would be better developed with SSR and then use CSS to make it feel SPA-like than to actually be a SPA.
nfw2
The article's title is it's time to kill SPAs
lukecjohnson
[dead]
epolanski
No one said SPAs have no place, but 99% of websites out there don't need to be one.
zarzavat
SPA means single page app. For example, Google docs, Figma, Google calendar, etc. Apps that use web technologies instead of being native apps.
A long time ago some webdevs started abusing the SPA concept to build simple websites. However that is not within the original meaning of the term SPA, because simple websites are not web apps. The author assumed that everyone would just understand that they are talking about SP"A"s and not SPAs, because for a certain subset of webdevs working on websites, the antonym of SPA is MPA, and it's normal to refer to your website as an "app". However for a certain other subset of webdevs, the antonym of SPA is simple website, and what the author is talking about are not SPAs at all.
wordofx
So you describe the 1%? Is this to refute the person you’re replying to?
nfw2
What does it's time to kill SPAs mean to you other than they have no place.
vasco
It's incredible to write an article about UX with a main argument of "this way is as good as that way" without visual examples to prove they actually behave the same.
bigtones
Right, I would like to see some examples of what he is talking about considering his tone of voice - he is literally telliong people to change their ways and use modern CSS and the entire article is devoid of such css.
40four
This article is getting a lot of pushback from the SPA champions, deservedly so, but it makes some good points to. I can’t be the only one, but I myself am getting very tired of the amount of websites where I have to sit and look at a skeleton loading for way too many seconds, then the data loads and it looks nothing like the skeleton. There is an over abundance of really crappy SPAs out there. Sorry not sorry
pyman
I thought about your comment, and IMO the reason some (or most) SPAs are badly built comes down to the inexperience of developers and hiring managers. They don't know much about performance, they don't measure it, they don't handle errors properly, they ignore edge cases, and some are learning as they go.
Bottom line: they build the SPA, but leave behind a terrible UX and tech debt the size of Mount Everest.
wyuenho
I swear if I see another "SEO" guy or some rando web dev who joined the workforce after Covid complaining about SPAs by misrepresenting it, I'm gonna explode.
As someone who's been developing web apps since the 2000s, let me tell you the origin of SPA has few things to do with the "false promise of SPAs" he listed, but largely due to companies in the late 2000/early 2010s wanting to go "mobile first". This usually meant they still had a desktop second somewhere, which implied they were architecting the entire system to completely separate the frontends and the backend.
Before, what web devs meant by frontend was essentially server-side rendered HTML templates with perhaps a little bit of jQuery running on the client-side. Now, since mobile and desktop web apps are to share some business logic and the database somehow, people had to rediscover REST by reading Roy Fielding's Phd dissertation that inspired the original HTTP. This meant now every company was moving to service-oriented architecture and started exposing their backend APIs onto the open internet so their mobile apps and SPAs running in the browser can share the same APIs. This was a cost saving measure.
This period also coincided with the steady decline of full-stack webapp frameworks like Ruby on Rails and Django because for a couple of years, these frameworks had no good ways to support an API only applications. Django hadn't even reached 1.0 back then. This was a time when NodeJS was really starting to pick up momentum. Once people had started being more comfortable with JS on the server-side, lots of people suddenly realized they could push a lot of business logic to increasing powerful desktop browsers and phones, application hosts people now call "edge devices".
This is the true impetus of SPA. How is CSS going to kill this need?
SPAs make sense when your users have long sessions in your app. When it is worth the pain to load a large bundle in exchange for having really small network requests after the load.
Smooth transitions are a nice side effect, but not the reason for an SPA. The core argument of the article, that client-side routing is a solution for page transitions, is a complete misunderstanding of what problems SPAs solve. So absolutely, if you shared that misunderstanding of SPAs and used them to solve the wrong problem, this article is 100% correct.
But SPAs came about in the days of jQuery, not React. You'd have a complex app, and load up a giant pile of jQuery spaghetti, which would then treat each div of your app is its own little mini-app, with lots of small network requests keeping everything in sync. It solved a real problem, of not wanting to reload all that code every time a user on an old browser, with a slow connection, changed some data. jQuery made it feasible to do SPAs instead.
Later, React and other frameworks made it less spaghetti-like. And it really took off. Often, for sketchy reasons. But the strongest argument for SPAs remains using them as a solution to provide a single-load of a large code bundle, that can be cached, to provide minimal network traffic subsequent to the load when the expected session time of a user is long enough to be worth the trouble of the complexity of an SPA.