Hacker News new | past | comments | ask | show | jobs | submit login
The Single-Page-App Morality Play (baldurbjarnason.com)
207 points by midrus on Oct 15, 2021 | hide | past | favorite | 131 comments



As someone that had my fair share of experience with mismanaged teams, this rings very true.

For example I had to maintain a legacy PHP project, relatively old school PHP before there was even OO, plain HTML with just a bit of JS sprinkled it. Everyone complained about it and sure the code was horrible but I could dive in and be productive on day one.

Same company, more recent project with a more modern stack, trying to follow all the OO patterns and everything. I was not even able to fix minor bugs in any reasonable time even studying the code for weeks. What happened? While the developers made good technical choices and the quality of the code in isolation was fine, it was horrible mismanaged. There was no continuity, just people working on it for a couple of days then doing something totally different and forgetting everything again on repeat. Individual design decisions were "industry best practice" but the end result was something I wished I could just delete.

Everyone loves to play wiht the newest toys but you got to keep you developer vanity in check. Sometimes the boring CRUD app should use boring technology. With horrible management you will learn to hate what you once loved anyway.


For some reason, web development seems to have an obsession with "progress" and the new-and-shiny-but-objectively-worse. I've noticed that constant reinvention of the wheel and doing the same thing more inefficiently ("but it's more modern!") is a common theme.


When it comes to pages that would be served just fine with basic HTML, JavaScript and CSS there's an irritating, crossing into stupid, overemphasis on frameworks and patterns. A lot of times it's gotten to the point of bikeshedding.

But that said there _is_ important progress being made in web tech but very little of it has to do with how you mash your HTML, JavaScript and CSS together.

Take a look at what's being done with tech like WebAssembly and full on 3d grpahics in the browser (if youre using a phone I recommend that you connect to a wifi spot to not use up your data).

https://threejs.org/examples/#webgl_animation_keyframes

https://playcanvas.com/

Theres a whole other can of worms to deal with like finding talent (this kind of content is way more labour intensive and requires much stronger domain knowledge). But the point is that there is a path for enhancing online UX and disrupting user expectations. The value add for being able to review 3d models of construction or order previews on demand speaks for itself.


The problem is there are always a couple janky things. This is janky on Chrome. That is janky on Safari. Something else is janky on Edge.

Every framework is about making the janky uniform across operating systems and browsers.

Programmers don't want to have to learn how to anti-jank on 40 different browsers. They want to learn how to anti-jank on 1 framework and get on with life.


When people say a web app is 'modern' I know it involves a javascript framework.

I'm not sure how or why this came about, but it seems to be a code-word meaning one of the newer javascript frameworks, that single word is almost a shibboleth at this point for an entire culture of development.


Rails dev. Did a long pair-coding interview at a company that had all JS for their backend. Tried out the JS ORM.

Most of the day was me: let's do <this easy, normal thing in the ORM.> Them: well, this is more like a half-baked rails knockoff so things like that aren't there.

So, they knew it was lousy, but picked it because it was JS? Sigh.


Not necessarily, it can involve web assembly.


Fashion (which values novelty) is a major factor in web design, it stands to reason this preference would spill over to the underlying technical stack as well.


I agree, but this has always stuck out as odd to me. Why is this so true even of the developers in web when people in something like C# are perfectly content using the established tools/frameworks they know year after year? I have seen sometimes seen this in the same person - someone who would never complain about using Entity Framework, but who is always pushing for the latest trend when working in the front end stack.


As someone who has changed the kind of work I do in my career I've had two very different experiences.

There is a web development culture. There was a pace of advancement for many years that helped shape this desire for newest shiniest stuff. Other ingredients such as chasing FAANG, VC money, and the general youth of the average web dev. Salaries chasing talent due to the online boom and corporate policies not adjusting to keep talent, thus needing to do resume building for the next job hop because it's going to happen in less than 2 years.


Even C# isn't completely immune to trendchasing, although you're right that it's less. Maybe it could also be due to how much effort and money is spent promoting novelty --- and certainly for companies like Google, change is their weapon for fighting competition.


Y’know, I’d argue that C# may be the worst when it comes to trend-chasing — for better or for worse, the language’s a giant toy box that lets you develop in very expressive, not to say idiosyncratic, ways.


A decade and a half or so ago, people were mocking FE saying they weren't "real" developers. Well, instead of taking lessons learned from "real" developers in order to catch up/prove wrong/whatever, I think they took the "hold my beer" mentality and it's kinda stuck.


"There was no continuity, just people working on it for a couple of days then doing something totally different and forgetting everything again on repeat."

This is a great description of my current work. Multiple systems, stacks, and technologies to support. It's just constantly jumping from one thing to the other. It gets even worse when you throw PRD support work in there. The context switching is brutal.


I worked at a job once where this was deliberate.

Certain voices in the team were terrified of "siloing", and so it was a matter of policy that everyone had to jump tasks and teams every two weeks, unless they had a solid case for a longer term task.

The result was that no one knew what the hell they were doing, because no one had time to learn anything before they were shuffling chairs again.

We were only saved from this madness when a major data center failure took out the app and all process theatre was temporarily suspended during crisis mode. Once we got back online, it was quickly realized that we'd all been wildly more productive and not just because of the crisis, but because we could actually function organically without the artificial strictures.


I feel like our's is the product of management not wanting to staff up our team or another team to handle different tech (not willing to pay up).

It's possible it's intentional though. It's hard to leave the team or company when you're just ok at a lot of things, but not an expert in anything.


Kind of sounds like a continuity problem, perhaps even a leadership problem.

> Sometimes the boring CRUD app should use boring technology.

Absolutely. I would even say most of the time, CRUD and relational databases can be a much better solution.


What was horrible about it if u were able to be productive in a day?


For anyone deciding whether to read, I'd say the article is broadly centered on this:

> As developers, we need to operate under the assumption that good management is the exception, not the norm. Multi-Page-Apps and hybrid frameworks let under-resourced, mismanaged developer teams deliver reliable and safe code. That should not be dismissed lightly.

There's also a helpful "Summary" section at the bottom. Overall it frames the SPA vs. TWA[0] debate in terms of which approach is likelier to produce successful software... or successfully produce software, at least.

[0] Traditional Web Application? Do we call it that?


We've largely broken app architectures in AAD down to spa, hybrid, and "webapp". Where webapp means "a server owns the state, and creates a web page and sends it to your browser". MPA is rough - 110% some engineer within minutes of that doc going live will point out that their spa has multiple pages.

Personally, I like TWA - will start using that locally to see how it goes. Look for a doc update near you soon...


AAD?


Azure Active Directory -- the OP is a PM for that at Microsoft.


<deleting because comment was based on a misreading>


Can you elaborate on what you found laughable? I thought the article made valid points.


<deleting because comment was based on a misreading>


Is the article not arguing the opposite? That multi page apps are the ones that better insulate against management failure?


<deleting because comment was based on a misreading>


The quoted claim doesn't say anything about SPAs providing insulation against bad management either?


Oops, my mistake. Deleting as best I can.


I really like the virtue/vice discussion framing this. You don't see virtue-oriented discussion of topics very often unless it's the accusation of "virtue signalling" being flung around.

> I keep seeing Single-Page-Apps with huge JS files that only, in terms of concrete User Experience (UX) benefits, deliver client-side validation of forms plus analytics. Apps rarely leverage the potential of a Single-Page-App. It’s still just the same ‘click, wait for load’ navigation cycle. Same as the one you get with Multi-Page-Apps. Except buggier and with a much slower initial loading time.

Very true - and also of mobile apps that behave in this way, either because they're using the same SPA technology or are just misconceived.

However:

> The Multi-Page-App forces the team to narrow the scope to a level they can handle. It puts a hard limit on their technological aspirations.

I don't see how this follows at all?

The link to https://doriantaylor.com/agile-as-trauma is fantastic too, as is the whole "I am Vanity" section. But yes, I also agree with the people here asking what this has to do with SPA vs MPA, because I don't understand the scope argument.

(Frankly I could write a paragraph response to each section as if it were a separate blog post, that's how much good content there is here)


MPAs are naturally limiting compared to an SPA. And dev teams know this. So does management.

SPAs are magical pixie dust that lets you easily code a native experience in the web. Some management thinks this. So do under-experienced dev teams.

MPAs provide natural pushback against unrealistic demands and feature requests that your experience might not let you recognize, or that company politics won't let you do.


My overall experience with SPAs as a user of different services is not so great on average. There are a few services where this works out great but for the most majority it makes the experience worse.


I think he's implying that traditional MPAs are relatively well-understood. The team will pretty much know how to make them and will not expect to break new ground on architecture, discover new things the model enables, or spend a lot of time on "How do we build applications?" versus just delivering on business goals. SPA development is less mature, so there's a lot more room (and sometimes need, or just temptation) to reinvent things.


Maybe I’m just full of Ruby on Rails induced trauma, but I can’t remember any particular pleasant memories. Every app would start with a reasonable and straightforward view layer, usually ERB templates sprinkled with jQuery, and then slowly but surely be consumed by one-off JavaScript snippets.

“We need a sortable table on this route and it should support pagination without a reload, but the pagination needs to be persisted to the address bar for outside link sharing.” This feature alone can introduce all kinds of unmanaged state and be a testing nightmare. And if another part of the site uses the same functionality, you’ve just signed up for an lifetime of maintenance, usually somewhere between your server-side templates, and your asset pipeline. God help you if your bugs can be described as, “I have some local state here, but I’m not sure how to get it either up or down to the right place.”

Personally, these kind of code smells demoralize me enough to consider a job elsewhere, preferably at a company that uses something like React where there’s bound to be complexity, but at least there’s component boundaries to keep your mental facilities from being overrun by a “simple multi page architecture.”


> “We need a sortable table on this route and it should support pagination without a reload, but the pagination needs to be persisted to the address bar for outside link sharing.”

How would you do that differently in a SPA? Or would that just preclude the link sharing, removing the requirement altogether?

Are SPAs doing client-side pagination or something?


I've seen a variety of solutions used in SPAs, from a thin wrapper around server-side pagination to some extremely fancy client mirroring of server state where the client builds an increasingly larger cache of the data coming from the server, complete with eviction strategies and maximum memory usage limitations, and only has to send a request to server side when it knows it cannot satisfy the client's viewing desires with what it's gathered so far.


    > I’ve written in the past about how conferences are the
    business equivalent of morality plays. They don’t exist to
    educate or enlighten but to unify a community around shared 
    values—which is why they are great for networking. That is
    why they need a liturgical adversary; somebody who can
    represent the opposing heterodoxy.

    >> unless it's the accusation of "virtue signalling" being
    flung around.
You can't have one without the other.


The author is talking in context of Frontend system i.e. javascript only.

In SPA, a single app consists of all your frontend system. hence has a high scope.

While in MPA mode, js is split across multiple pages, and each page has a narrow scope for the javascript code to function.

Hence MPA will limit power and misuse of javascript


It's the Web what Tim Berners Lee envisioned it to be, a web of "dumb" hypertext used to disseminate information or a web of interlinked apps which happen to run in the browser instead of desktop or mobile?

In the 2000 it was clear: if you wanted to find informations, you went on the www. If you wanted to chat, you used an IRC app. If you wanted to type a document, you opened a text processor. If you wanted to see a movie, you used a movie player. If you wanted to listen to music, you opened a music player. If you wanted to game, you fired a game. Now all this are on the web.

It's not clear to me if I am a web developer or an app developer because the borders are erased day by day.


This article is blowing my mind, as is the linked article "Agile as Trauma"[1], written by apparently a different author but with a very similar broad perspective.

I want to read more like this.

[1] https://doriantaylor.com/agile-as-trauma

[update: holy cow, this one too https://www.baldurbjarnason.com/2021/software-crisis-2/

Today is turning into "read about existential problems with how software is developed" day for me]


I've been doing web development for over twenty years now. Perl, PHP, ASP, Rails, .NET, Flash, Flex, Silverlight and various JavaScript and SPA frameworks.

I really like the MPA approach. To me it means building a bunch of mini SPAs. You can still stuff everything into a single SPA to deploy to a mobile app, but it gives you the advantage quicker first-time page loads and a lot of extra flexibility.

Compared to the Web 1.0 way of doing things where you POST and then reload the page, you're taking an API based approach so when a 3rd party needs to integrate with you - that part is probably done already.

A lot of sites use the MPA approach wrong though. They load the "apps", then proceed to make a whole bunch of asynch requests for data. In most cases, using a mechanism to inject in data when a page first loads makes everything feel a lot faster.

It's the best of both worlds: you get the speed of the old school web and the flexibility of modern practices.


I couldn't agree more. It is a spectrum.

<-- Fully MPA ... MPA with mini SPAs ... Fully SPA. -->

Many don't venture in the middle. Not sure why. Do not stay on either end. It will bite you!


People don't venture in the middle because it's complicated and scary for many people due to the skill requirements. It only starts to feel safe to play there when you have experience with development at both ends of the spectrum because you likely won't have the support of tools which are intended to run there.

Further, it's a compromise that is difficult to explain and justify to management. If they are risk averse then they won't want to move far from the safety of the frameworks at either end of the spectrum.

If you are a developer of frameworks, it also seems advantageous to go to one end of the spectrum because it's easier to reason about the problem space. When you target the middle there starts to be more variations in how to handle it best. It's really the only place to go though, if folks really want to innovate and provide better experiences for all.


Laravel encourages the middle ground. Sprinkle Vue.js. I've worked in both MPA and SPA. The middle ground is much faster.

You can pre-load objects in the page and then use AJAX to finalize loading. The user experience is snappier.

The bundle size also remains smaller. Divide and conquer.

Yes, it does require being comfortable navigating back and front end. Over time, a good developer will get there.


This trope of "if you were just skilled enough" needs to die. Things cost money. They cost money to maintain and evolve. If a solution requires exceptionally high skill that means it is very expensive and pushes employees to their limits. Meaning it is not a healthy technological solution.

It's funny how the article goes on about "If managers were just good enough". But the problem is managers face real world constraints. They can't just give us unlimited resources to live out our complex ego-driven tech fantasies.


>> This trope of "if you were just skilled enough" needs to die. Things cost money. They cost money to maintain and evolve.

I don't disagree terribly with the trope aspect, but people are hurting from the cost to evolve and maintain projects using approaches that sit at the extremes. There needs to be some understanding, and possible embrace, of elements of the middle ground in order to be truly maintainable in a lot of cases.

My call to action would be more for the innovators and framework developers to think more about this. Companies can try to solve it for themselves, but forces like staff turnover prevent meaningful progress for most.


If you have multiple pages each with their own javascript that allows them to behave like an application, is it still considered a SPA? Yes it behaves like an application, but javascript running AJAX is hardly different from what traditional webpages already do. To me the defining trait of a SPA is a site that does all its routing within a single html page (which I consider an antipattern).


Back-end routing is very solid. My experience is that front-end routing is complex and is hard to maintain. Multi SPA allows you to modularize your application into different concerns.

Most of the time, an SPA can be limited to one action or group of actions. For example one SPA to manage the user's preference, another for managing a list of objects, so on and so forth.


> Back-end routing is very solid. My experience is that front-end routing is complex and is hard to maintain.

There doesn't seem to be anything inherently more complex about routing on the front end vs the back end. Why does it turn out to be messy when the back end isn't? What's keeping you from using the same patterns?


If you implement it on the frontend you lose all the builtin navigation behavior that the browser gives you natively when loading pages. You instead get to build all that behavior yourself in places where you think it should exist using your best judgment (things like deciding when to push to browser history state, for example, may be perceived as breaking the back button to many users if you haven't thought through your app's navigation hierarchy very carefully).


You can cache templates in the user's browser and insert those into the user's page and show/hide parts of a single page.

For example, you can use mustache.js to load a cached "Preferences" template and just grab the data from the server to fill it in, or from the browser's IndexedDB if you've stored that data there.

Does this approach not qualify as a single SPA?


MPA + SPA is how most native Android and iOS apps are developed. I agree with the other commenter that a single html file is an anti pattern.


For the bulk of my Internet surfing, I have JS turned off by default in uBlock. Now and then I encounter a white screen of death which on closer inspection is a Single Page App (and didn't have the courtesy of having a <noscript> tag telling me I needed JS to view the page).

I have JS turned off for accessibility and privacy reasons. What annoys me is sometimes JS is needed just to render a bit of text when it could be rendered with plain HTML. Not everything needs to have JS in order to work/function. Also: many hamburger menus are rendered useless when JS is turned off when it could be implemented with CSS alone.


SPAs make web resources impossible to index or link to - by definition, they do not contain "pages". OP failed to mention this at all. For me, this is the killer "anti" posture.

Hyperlinks are the defining feature of the WWW; that people put resources on the WWW that can't be linked to, is cause for regret.


> SPAs make web resources impossible to index or link to - by definition, they do not contain "pages".

There are two things you could be referring to here. Both are resolved so that you can have an SPA that basically starts out as an MPA and upgrades itself to an SPA, though it’s common for scripting to still be required where it shouldn’t be.

Firstly, putting the route in the path rather than the fragment. That was resolved with history.pushState which shipped across all browsers in 2010–2012. You can safely assume it these days for all JavaScript-enabled browsers (you should not be supporting such browsers as IE9, Firefox 3.6, Chrome 4, Safari 4 and Opera 10.1).

Secondly (dependent on the first), whether the server’s response includes the content. Some SPAs don’t (reasonable for many applications, generally unreasonable for content websites), some do, typically using a family of techniques broadly called server-side rendering (search the term for explanations). It’s only in the last few years that SSR has seen significant uptake, though it’s existed in varying forms since at least the mid-’00s (though there were some fairly significant problems with it until history.pushState existed, so it wasn’t widely done except for Google’s #! → ?_escaped_state_= AJAX crawling scheme from 2009).


> Both are resolved so that you can have an SPA that basically starts out as an MPA and upgrades itself to an SPA, though it’s common for scripting to still be required where it shouldn’t be.

Yuh, I guess my disconnect is that I tend to avoid sites that don't work at all without JS. I'm willing to enable JS if I care about the site (and it at least renders something without JS), but I'm not prepared to drop my pants for some random sales site that gives me a white screen if JS is disabled - someone else gets my business.


It used to be impossible to link to specific page in a SPA without using hashes in the URL, but this problem has been solved years ago, and all modern browsers support it.


What's a "specific page" in the context of discussing single-page applications?


If you go to example.com/user/jim in your browser, it'll navigate to (presumably) the profile for the user with the handle "jim"

Maybe I don't understand what you're asking. Browsers these days have functionality that enables SPAs to navigate between URLs, push/pop to and from the back history, etc. without full page reloads.


Well, example.com/user/jim looks to me like a Unique Resource Locator. If that's right, then what I'll get is a "page" (you could call it a resource). If the locator is really "unique", It'll be different from the page I get if I ask for example.com/user/jane, right? (modulo aliasing)

Well if that's right, then this site is not a "single-page application". It has multiple pages with different URLs, and I don't know how that's different from any other website with server-side state.

[Edited to mention state; state is irrelevant to whether its an MPA or an SPA, but without state it's hard to argue its an application at all]


I see the definition of SPA as a web app that doesn't require page reloading when navigating. So both a SPA an an MPA can have the same URL structure while the latter requires page refreshes when switching between them. I might be wrong.


I see. I guess I'd better inform myself better about the jargon.

So without a page-refresh, does anything get stored in browser history? Does the back-button work?


Correct. What I was trying to get across in my earlier reply is that a URL isn't quite treated the same as their name would imply these days. I could see why that might annoy purists, but these days there are browser APIs that enable modifying URLs (which modifies the "back" history) through Javascript, without actually doing a full reload of resources.

So even though you're requesting a different address, you're technically not getting an entirely new "resource." No matter where you hit the address, you'll get the same base blob of HTML/css/js, but going to the URL directly will fire the proper navigation (through js) to get you to the spot you requested (which may involve loading different resources, dynamically).

Hopefully that explanation makes sense


Traditionally that's been an issue but nowadays there's the History API.

https://developer.mozilla.org/en-US/docs/Web/API/History


SPAs can be linked via url fragments 'www.mysite.io/#/fragment1/subfragment/id'

and modern frameworks allow you to use normal urls directly, by configuring server to ignore url path, and let SPA handle it (along with HTTP 404)

So, it is not a technical limitation of SPA.


> the root cause of every bad Single-Page-App isn’t that it’s a Single-Page-App.

The root cause of https://vector-of-bool.github.io/ scrolling incorrectly when navigating between pages isn't due to bad management or lack of care, it's because it's a single page app that didn't handle scrolling correctly (which a browser would provide for free), and the author didn't notice despite coming in with good intentions.


It gets even muddier when you consider the fact that MPA transitions will be in browsers hopefully quite soon and you will be able to achieve the exact same effect.

https://developer.chrome.com/blog/shared-element-transitions...


That's the point of the article though. SPA is /hard/. Using a normal many-page app, you get scrolling that works across all browser - even mobile - for free, without having to do anything. I'm not saying I necessarily agree, but that's what this article is about.


> Single-Page-Apps can be fantastic. Most teams will mess them up because most teams operate in dysfunctional organisations.

I don't think the vector-of-bool website, and the broken JS transitions, were designed by a dysfunctional organization (or an organization for that matter) (though the author has suffered from burnout: https://vector-of-bool.github.io/2019/05/23/signals.html).


I have been developing lately with A django/HTMX stack[0]. It covers a lot of the positives of JS SPA, without the headache. Also, I get to use the Django superpowers.

https://htmx-django.com


I appreciate that Django is a good old full-stack server-side framework, and there's a lot to like about that. But I can't bring myself to start a new project with something that has the gross inefficiency of CPython (or, IIUC, stock Ruby), as discussed at, for example, [1] and [2]. I want a runtime environment that's efficient enough that I can deploy the web application on a couple of small VMs, still have plenty of headroom for load spikes (which, in my experience, are usually due to screwups on my part and not actual demand spikes), and delay thinking about scaling as long as possible.

[1]: https://rachelbythebay.com/w/2020/03/07/costly/

[2]: https://blog.clubhouse.com/reining-in-the-thundering-herd-wi...


Surprised htmx isn't mentioned more in the comments.

I'm using it with Janet for a side project, really liking it so far. Writing server-side html with a hiccup-like library is very nice! :)

(Clojure Hiccup library, similar libraries exist for other lisp-like languages: https://github.com/weavejester/hiccup)


This article rings very true to me. In my mind a badly managed project (and yes, these are legion) will accumulate complexity very quickly. The important technical difference between MPAs and SPAs is where they put that complexity.

In a multi-page app the complexity largely lives on the server, which is a known quantity, profile-able and scaleable. In a single-page app the complexity lives on the user's device. There are innumerable variations in device power, capability and so on so there is no good sense of what "good performance" even is. But it'll work great on the developers supercharged MacBook Pros, so the code gets shipped.


> The important technical difference between MPAs and SPAs is where they put that complexity.

Just as important a practical difference (an outworking of the complexity location) is the matter of statefulness.

With an MPA, each page load is its own thing, generated from scratch from the canonical data source each time. Pages are essentially stateless.

With an SPA, the client will generally be interested in retaining data and caching things for at least the duration of the session, and it’s easy for state to get out of sync. That can go wrong so many ways, and cause so much pain, and resolving that commonly takes reloading the whole page, which is normally distinctly slower than it would have been in the MPA world. (Not that it need be noticeably slower, but it almost always will be.) Or the absolute worst case, persisted wrong data… that’s a nightmare.


For me SPAs are when we want to run apps in the browser less efficiently than on the desktop or mobile, while taking more time to develop them.


Nice to read something that made me laugh out loud.

Pro tech work really is 80% coordinating people (quashing jerks, dealing with drama, etc: “don’t leave the new guy alone with the CTO”) and 20% funtimes-computer-stuff.

It might not seem like that in terms of wallclock time, but it sure feels like it in terms of energy spent.


Since he refers to misogyny elsewhere, I suspect he might mean "the new gal".


What's worse, those frontend devs who love Javascript frameworks began writing desktop and mobile apps in Javascript.


Maybe an unpopular opinion here: as a user of web applications, I very strongly prefer the "modern" javascript heavy SPA dominated culture of recent years. Every once in awhile I get annoyed by something that is just a webpage but thinks it's an application, but more often I have the reverse annoyance.

But as a developer, I agree that it is harder to develop these kinds of applications that I like than it used to be to develop multi page applications with mostly server side logic and only sprinkles of javascript.

I guess I just do, actually, think there is UX benefit to the complexity. But of course there are better and worse ways to accomplish it, figuring out that balance is the hard part.


Can you expand on why you prefer the JS-heavy SPA style?


Because they are faster and easier to use. Using them is like using an application, rather than like using a website.

I think a good rule of thumb is: am I mostly clicking or mostly scrolling? If I'm mostly clicking - say, something like AirBnB or Zillow or Discord - where I'm exploring things and interacting a bunch, that feels better to me as a rich client-side application. If I'm mostly scrolling, like a blog or substack or a newspaper or even twitter, that feels better as a website.

I thought of a good concrete comparison: Vanguard vs. Coinbase Pro. Vanguard is a website, and it basically works for them because their business model is very passive, but you wouldn't want to do active trading there. Coinbase Pro is a web application where you can do lots of exploration and take actions quickly, and for me, it would be a major hindrance if they implemented it in a traditional page-based way.


If you want to use an application, then why don't you download and run an application? You will have a better experience running an application on desktop instead of running it on the browser.


Write once run anywhere. Nothing else comes close. A lot of web applications simply wouldn't exist on your platform if they were forced to be native applications.


Except now replace "platform" with browser, and you have the exact same dilemma as if we still made desktop applications.

It's sad how many "web apps" (and even more regular sites) only work in Chrome - try using Firefox or any non major browser, and quite a lot of the web simply doesn't work.


Hardly the same. Desktop applications are still much more time-consuming to make. The differences between desktop platforms is on another planet compared to the differences between browsers, especially the difference between Firefox and Chrome, especially when you consider mobile.


Because the web is a revolutionary application distribution platform. It is a better platform in every way except that some things that should be applications are still behaving like websites (and vice versa) and that it is harder for developers to target than native platforms. But as a user, I don't care at all whether it is harder for developers.


if SPAs are bad, compiled JS are evil. They only seem to hijack the scrollbar or give cookie consent or waste 2/3 of viewport with a fucking subscribe/login cover.

Every page should promise some kind of plain text content length vs full page resource bytes ratio. Why would anyone emit 20MB of .min.js only to deliver 140 characters of tweet?


I get the feeling, but it's worth noting that it's not just 140 characters of tweet. It's also delivering all the analytics, the content surrounding the tweet (replies, likes, etc), and is a teaser to the rest of the app.

The business driver isn't just delivering the content, it's increasing engagement, and the SPA application provides a significantly better and scalable way to make that happen. Everyone seems to think they could do better, and we end up with yet another "modern" JS framework.


thank you for saying that.


This rings extremely true based on my observation. Fundamentally, companies working on large projects will ship their org chart. It is modestly more difficult, if your org chart gets spilt in two such that two or more teams are now maintaining the same SPA, to synchronize their work such that they don't interfere with each other's activities. You begin looking at a more traditional application development model with full program integration testing in the mix.

Multiple pages means multiple entirely separate client-side contexts that are a security hole if they can clobber each other.


Well this made me feel good about being a lone developer who gets to make all the decisions on how to make an app.


Is this a React thing? I haven't run into any of these problems in five years of building Vue.js SPAs. Literally everything is easier, and faster, than traditional MPA development.


The bits about SPAs seemed to have no relation to the thesis, which is that management drives the antipatterns, not the tech.


The author argues that the non-SPA approach deals better with that kind of management than SPA does.


It’s hard to draw any real conclusions from this. The author says things that the delta between an average single page app is great from multi page, but is that true?

The author makes tons of claims but presents no evidence.

Seems more about poorly designed apps and managed teams than anything inherent in either type of app.


I can't relate to this at all. I've been happily working on SPAs with React and Redux for nearly 6 years.

Hotwire makes no sense: switching to managing client-side state on the server and sending HTML over the wire introduces a ton of problems: you are going to have to write and debug JavaScript eventually. Now your server is running client-side code to update every local browser state? How is that scalable at all?

React has a ton of great libraries for UI that these articles always ignore: Something like react-select to manage a dynamic dropdown- you can't implement that on the server.

You need SPAs for complex dashboards, and React is a great library to store and update local state. I don't understand what the controversy is.


Meh, I think you can get 98% of the way there. Look at the explosion of these "server side SPA" frameworks popping up. Hotwire for Rails, Livewire for Laravel, LiveView for Phoenix, etc etc.

I think Elixir is a super interesting case given how insanely fast it is. If your request to fetch new data and patch the DOM takes 5ms, who cares if it's slower than React? It's plenty fast for a ton of use cases and lowers complexity.

And then, if you do need the super slick interactive element, you bust out React and code up a nice little inline thing that writes it's value to a hidden input field that you can send along with a the submission of a normal form.

Webdev swung heavy to building entirely frontend solutions and I think the past year or so has been the potential beginning of the pendulum swinging back as teams are now feeling the pains of maintaining these huge frontend applications, on top of already needing to maintain the complexity of their backend.

Time will tell!


> If your request to fetch new data and patch the DOM takes 5ms

Even in the US people are still dealing with pretty bad internet in a lot of places. Even with the best internet, and assuming it takes 0ms to handle the request, 5ms sounds insanely optimistic. I'm in a big city and my ping (to my ISP's datacenters in the same city) is 10-20ms...


So, latency is certainly one locus of optimization.

Another locus of optimization might be development speed and cost. An SPA is really two apps, a front-end, and a back end.

It costs 2x to do an SPA, and all things being equal, features come out 1/2 as fast.

Which wins the app with latency, or the app that gets features twice as fast?


It doesn't cost 2x. Yes you go from two apps to one, but that one app is more complex than either of the original two.


I agree, it doesn't cost 2x. An SPA probably costs more like 3-4x.

Coordinating two apps is much harder than one app.

A reference for this topic is the Mythical Man Month, which concludes that communication overhead is what is expensive. When you have two apps, the humans, and the software both need to communicate and coordinate.

When there's two apps, you have an OR condition where if either app is broken or in disagreement about the expected API, both are broken. You have two sets of build processes, sets of tests, sets of files to serve, caches to manage, state to manage, versions to manage, and they all need to coordinate.

Instead of one thing to test, with an SPA, there's really 3! The server side app in isolation, the client side app in isolation, and the combination of the two.


Sure. I'm being super optimistic there, but it's also worth noting that Phoenix uses a websocket so some of the latency in the handshake is negated for subsequent requests.

Still, 50ms would probably be fast enough for a lot use cases, and if it's not, it's easy to configure debouncing.


There is no "pain" managing large React / Redux applications for experienced frontend software engineers. If you don't want to write JavaScript, you probably shouldn't be building interactive applications for the web.

The Browser manages HTML, CSS and JavaScript and provides Developer Tools to debug and manage these languages. When you build with a javascript framework, you package a user experience that is entirely run by the browser, only to dispatch and save to the server when necessary.

I doubt there is a future for "backend SPA" frameworks- no one will take seriously the idea of, instead of two REST calls to get and put data, every client must connect through a socket to manage user input. Surely that will dramatically increase server bandwidth, and ignite the same type of "bloat" arguments that SPA critics use.


> If you don't want to write JavaScript, you probably shouldn't be building interactive applications for the web.

Wow, thanks! I've been writing production apps in Vue and React for large companies for years now, but good to know I can stop. /s

I have nothing against JS; I have problems with complexity on teams of varying skill levels and tenure. If you're a JS shop, it's great. But if you're an agency of Rails developers building CRUD apps for B2B, you shouldn't feel forced to write a bunch of JS just to get some values updating on the frontend in realtime.


You don't need to write a bunch of JS, that's why JavaScript frameworks like React exist to make this easy. JavaScript is the only client-side scripting language on the browser that you can use to manipulate the DOM. If you want to locally CRUD without making a round trip to the server- you have two options- manual DOM manipulation, or use a JavaScript framework. That idea that HTML streaming will replace JS frameworks and REST APIs, and is easier and less problematic than a JS framework, is preposterous to me.


Who said that JavaScript frameworks and REST APIs are going to be replaced?

I've noticed that many people who enjoy developing SPAs believe that SPAs are the only way that web apps should be developed, and when anyone suggests otherwise, they get very defensive. Pretty weird.


> Surely that will dramatically increase server bandwidth

LiveView can actually decrease B/W and load, because the HTML diffs are more efficient than sending JSON, and the statefulness means you don't need to constantly refetch user information from DB/cache, etc. The details depend on your app and how carefully you optimize it, but it's far from being an unconditional "dramatic increase".

> If you don't want to write JavaScript, you probably shouldn't be building interactive applications for the web.

That's gatekeeping and just plain insulting.


JavaScript is the only language browsers will run. It's not gatekeeping to suggest that you have to learn and use JavaScript frameworks if you want to build web applications- it's a fact.


You can write full-blown SPAs in ClojureScript or Elm, or use the tools we're discussing here like LiveView.

I've had great success with an LV app with minimal JS. The rendering is all server-side in Elixir, plus a few lines of JS hooks for the bits that truly need to happen on the client for a good experience: TZ conversion, countdown timer, table sorting, Chart.js rendering. No framework needed.

The user doesn't notice if a transition takes 100ms because LiveView is fetching an HTML diff from the backend, or 100ms because React is doing an AJAX query to a JSON API, it's the same end result.


This is the problem

>for experienced frontend software engineers

web development skill varies wildly. Much more so than in any other branch of software development.

btw, "backend SPA"? That web world has officially jumped the shark. "page" has no meaning outside of a web browser. backend single string application makes more sense than backend single page application.


I agree with you.

My only, personal, issue with front-end is typescript - I don't enjoy it for some reason.


I've always thought some of it stems from the nomenclature and the cultures that flow from it. A lot of people (reasonably) don't think the best architecture for their application is a "single page". But many of those same people nonetheless have (often large) portions of their application that benefit from complex client side interactivity. But the whole thing can seem really all or nothing, either you have a "single page application" that does everything client side or you do everything through html from the server. Of course in practice everybody does some hybrid in between these two extremes. But the apparent split creates a cultural battle between the extremes, which is not helpful.


I come from a financial reporting background where pages needed to be dynamic and update through filters / sorting / etc- think Excel or Robinhood- these are applications, not pages. When you are building an application, users don't want to experience a page refresh. You either want a dynamic behavior without page refresh, or not. React Router gives you client-side routing- I don't know why you wouldn't want that even if you were building something like AirBnB where there is mostly static content- to argue against dynamic search and filtering without page refresh seems silly to me.


Yep exactly this. I even just used Coinbase Pro vs. Vanguard in another thread as a concrete example of application vs. website where the Vanguard approach would really suck for an actual trading application.


No need to go full SPA, dynamic dropdown can just be a component(with react-select) in your MPA. You create coupling between your front-end server and the browser but that's not bad at all for many type of webapps.


I've always found that when people say they dislike SPAs they actually mean they dislike APIs and the whole circus of how to handle building, consuming, validating, error handling, network errors, etc.

Not affiliated, but Inertiajs[1] has been a fantastic middle ground between MVC goodness and using React/Vue/Svelte for client side interactivity. It even plugins in with your Rails/Laravel errors for form handling.

[1] - https://inertiajs.com


Those interested in this debate really need to watch a very fantastic presentation on this exact topic: "Have Single-Page Apps Ruined the Web? | Transitional Apps with Rich Harris, NYTimes" [1]

[1] https://www.youtube.com/watch?v=860d8usGC0o&list=PL58Wk5g77l...


So... the idea is that there's a gray area in most debates, the answer usually isn't found at the extremes, the tech community needs to beware of groupthink, and, fundamentally, hold on to your hats, that ...

... management is just really stupid?

Yeah, that's a really really rare opinion in tech circles.


> Single-Page-Apps can be amazing.

> You can make a great Single-Page-App with a User Experience that a traditional site will never be able to close to matching.

What is actually meant by this? What is an example of a feature that can be far better in a SPA than in an MPA?


You can persist data on the client with IndexedDB and make a SPA with zero load times no matter what page you’re loading. That would never be possible with a MPA. It’s also almost never something that actually happens with SPAs but it certainly is possible.


The best example I know of a purely client-side web app that makes effective use of local storage is the Pinafore [1] client for Mastodon.

Edit: And it's worth noting that this app is a labor of love by an expert web developer, i.e. the antithesis of a typical corporate project.

[1]: https://pinafore.social/


Playing audio or video without interruption while navigating the site.


Eh unfortunately its muddy there too, see changelog.com which is not an SPA and instead uses Turbolinks (now Turbo) to persist the podcast element at the bottom of the screen.


Somewhat niche but a good use case, thanks.


Spreadsheet apps in the browser?


Is this just an advert for Hotwire? Every single point just seems to mention Hotwire.


Not really.

Hotwire is provided as an example of a Hybrid app framework / toolkit and is mentioned about five times. But so also is Svelte.


Doesn't like it considering below snippet from the post

> (* I say ‘was’ because the instability of Basecamp’s management and the massive turnover of the team working on Stimulus and Turbo makes me wary of using Hotwire on a project. But given how popular Rails is, that’s probably me being overcautious. The principles they describe in their books, such as Shape Up, are still sound. The problem, as many have pointed out, was that they didn’t follow through in practice on what they wrote.)


EDIT: doesn't look like it

Can't update original comment


Great style of writing.

A great example of a 'forced perspective'. The entire ecosystem of browsers, standards, devices, business imperatives is being forcefully turned into a spa/mpa comparison.


Yeah pretty much. Depends if you are making a web app or a web site.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: