
You probably don't need a single-page app - ukutaht
https://journal.plausible.io/you-probably-dont-need-a-single-page-app
======
save_ferris
This. So much this.

My company (4,500+ people) ordered all products in their portfolio (~12 web
apps) to migrate to SPA front ends about a year ago as a way to stand out from
our competitors, and boy has it been painful.

Prior to that initiative, we had been using the hybrid approach mentioned in
this piece, embedding SPAs only where necessary and sticking to SSR everywhere
else, which worked really well.

Since the announcement, our productivity has diminished dramatically since so
much of our time is now focused on re-working functionality that already
exists into an SPA, and it's completely unnecessary. Not only that, but
extending these UIs will take more time in the future than their SSR versions
due to the added complexity of the front end frameworks, and we're definitely
going to make mistakes along the way that we weren't making before.

It drives me crazy to think that some exec came up with SPA-ing everything as
a sales pitch to clients, when 99.9% of our clients have no idea what an SPA
is. And the amount of money being spent on turning already-working apps into
SPAs is astronomical.

~~~
marktangotango
I don’t disagree here at all, but I would note that generally server side
templating is often a mish mash of business logic, view logic, accessing query
string and session parameters, and whatever server side Singleton/globals
available in the template context, that becomes horrific spaghetti in no time
at all.

Compared to client side rendering discrete web requests with minimal
templates; you usually get much better separation of logic, view, and code
than the typical serverside solution.

There is a happy medium where server side services are encapsulated to
separate concerns in a similar manner, but it rarely happens, even with
competent, experienced, well intentioned teams.

~~~
mattmanser
This is a load of nonsense.

If you can't separate concerns in a hybrid MVC pattern, you'll be screwing it
up just as much in an SPA.

Plus you've got the extra layer of an API to maintain too making it even more
complicated, and more likely to spaghettifi, not less.

~~~
ryukafalz
>Plus you've got the extra layer of an API to maintain too

On the other hand, if you're providing a service that will _always_ have an
API, and you want to make sure that all the functionality you provide is
nicely accessible through the API, building the frontend on top of it can be a
good approach. The developers at the company I work for have done this, and
IMO it's worked out pretty well.

~~~
eeZah7Ux
Nonsense. People have been doing that for years before the single-page hype.
The servers generating HTML contents use the API as their own backend and you
have better layering.

~~~
pvorb
Are you sure about that? Today I think this is a good model, but I haven't
seen it in the wild before.

------
kyledrake
Agree with the article. I find server views to be substantially easier to work
with.

But more importantly, I also find server view rendering to be a faster, better
UI experience. It's really frustrating having to wait several seconds for a
SPA to load, or to have unexpected behavior when clicking the browser back
button, or failing completely because some random hunk of JS garbage errored
out, and it's one of the big contributors to why I don't really like using
Facebook or Twitter anymore. They murder my browser with megabytes worth of
slow SPA crap to give me less than a few kilobytes of meaningful data (and/or
people screaming at each other). Gmail now takes 10-20 seconds for me to load
at this point, on my high end laptop. I just want to switch to HTML mode by
default.

I definitely get edge cases like Slack, but honestly don't think SPA has been
a positive development, overall. I think the web was better as a document/HTML
oriented design.

~~~
Twirrim
With gmail: Move your mouse pointer down to the lower right corner of the tab.
Do a forced refresh (Ctrl+f5) and you'll see some text pop up while it's
loading, one of which is a link to a basic HTML version of the site. Click on
it and you're back to what appears to be almost the original gmail interface.
Up the top of the page you'll see an option to make it default.

It's super fast. Almost absurdly so, compared to the "full" gmail experience.
Added bonus: It gets out of the damn way so you can just do what you came
there to do: write and read email.

~~~
ibty
There is a direct link to access basic HTML version of GMail :
[http://mail.google.com/mail/h/](http://mail.google.com/mail/h/)

~~~
KuhlMensch
hm. So.

The SPA gmail platform has an _infuriatingly long_ loading screen, but once
loaded the click-> to reading email _is_ quicker.

I suspect there is allot that can (and should) be done to optimize the SPA
version.

But man, the html version is speedy.

I barely use email, but I'm going to put the html-only version into my
rotation and see which one I gravitate toward.

------
cfv
You probably don't _need_ a single-page app, right up to the point where it's
a business requirement and you have to translate a GB worth of convoluted JSPs
into one because the client likes smoothness in their flows, continuous
saving, and all those nicely choreographed state transitions you just cannot
get without having a framework hijack the History and File APIs from the
browser's paws.

Yes, a nice state machine-like flow with each thing happening only once at a
given time is great, right until you get asked to make it so that clicking on
a thing shouldn't reset all user input, and progress of a task should be
communicated live, maybe while we also we want this app to just not show a
blank screen like, ever, just comes and happens to you and that's what you
kind of have to do now.

~~~
LaGrange
> smoothness in their flows

...what?

> continuous saving

No problem.

> and all those nicely choreographed state transitions

Learn to say "no." It works wonders whenever people tell you that your
aircraft has to go under water now.

~~~
Spivak
It's difficult to tell the person who's writing your paycheck "this is totally
possible I just don't like it and so won't do it."

Like if you're doing SSR you could at least use something like turbooinks to
implement state transitions.

~~~
andrei_says_
How about “that’s totally possible. It will cost you 10x what you’re paying
now, it will be much more brittle and harder to fix. I personally would love
to work on it, just keep in mind that any changes will require 10x the time
and budget”

And ...

“Here are a couple of technologies which would allow us to speed up the
experience at a very low cost. I recommend we try these first.”

Turbolinks for the win :)

~~~
scrollaway
> _It will cost you 10x what you’re paying now, it will be much more brittle
> and harder to fix._

I say this as someone who's done a lot of freelance work: No, you can't
bullshit your clients like this. You may be able to tell them that if it's not
an actual lie, but in your case, if you _actually_ would endure such costs and
fragility, it speaks volumes about your agency's skill levels.

If you're in the business of selling websites, maybe it's time to actually
learn how to write a good SPA rather than bury your head in the sand, because
yeah, clients _do_ actually want those.

~~~
andrei_says_
Maybe I should’ve made it clear that the 10x is an example. In most cases it
would be 2x to 4x, the cost for implementing two apps instead of one.

Of course the cheaper option (monolith app + turbolinks and js sprinkles)
could be framed as a discount.

And I can imagine how many agencies would not mention the expense of
maintenance, because they’d actually want to lock in the client first.

------
lmilcin
All that complaining serves no purpose. SPA is just another tool in a belt.
Where I think it shines is making rich apps that need complex flow and
communication. This is where productivity is important and the process is
complex and up until recently I would be advocating native desktop app. Now
with advent frameworks that help me organize this very efficiently (I use re-
frame/reagent with ClojureScript) I can create complex SPAs without the
project collapsing under its own weight at some point.

I don't want to say you should use SPA frameworks for anything, don't make
your company website with SPA. What I want to say that if you have a complex
process you can consider creating "enterprise" UI instead of trying to dumb it
down to a series of billion simple forms.

If you feel your business is overusing SPAs (is it so strange they want new
shiny toy?) then as the technical person you need to educate them on pros/cons
of the technology.

~~~
movedx
> All that complaining serves no purpose.

It's not complaining. It's a profession's view on the state of (default)
behaviour by most developers in the wild. It's a valid set of points as to
what the default mode of operation seems to be, as a general rule, and why it
might not always be the correct default mode of operation.

------
paultopia
Unpopular opinion: I love SPAs for simple stuff. Yes, they're a ton of work.
But the feel of them is unparalleled.

I have my personal home page written as a Vue SPA. It was a silly amount of
work to get together, and not everything works perfectly. BUT: it moves like a
rocket. I pre-render the simple front page, so initial load is nearly
instantaneous (especially with cloudflare &c), and, by the time a visitor
finishes absorbing the information on the front page (which is just a palmos
style collection of icons to other content), everything else is loaded. Which
means that the effective load time of the whole website is perceptually
indistinguishable from zero on a moderate-speed connection (like my crappy
home DSL).

And that's... cool. It's legitimately cool. Let me have my fun!

~~~
bo1024
I want to be open-minded for you to have your fun. But at the same time, I
want to let you know the problems with your approach from my perspective if
you want me to interact with your site.

No offense, but I don't know you, so I'm not going to run untrusted code you
serve my computer without some good reason. That means your website is
completely broken for me. It is also likely broken from an accessibility
standpoint for those with special needs or using tools to access your webpage.
(edit: People's personal browser defaults such as size, font, scrolling,
language translation, or any other plugins they use for their workflow may
easily break.) It also means that search engines and robots will have a hard
problem indexing the links on your page or understanding the layout of your
site.

So while I could agree you've created this cool user experience for the most
common case, it breaks the fundamental precepts underlying the web and I think
this does have some negative consequences, especially if this became the
default approach. That all said, you do your thing - I just hope this provides
useful food for thought!

~~~
scrollaway
Relying on JavaScript doesn't "break the fundamental precepts underlying the
web", that horse has sailed long past that bridge.

Today, not running JS breaks the web. You can lament this, I too think it's
not ideal, but you can't change it. So don't accuse devs of breaking the web
for using an SPA just because you're part of the 0.002% of users that doesn't
run js by default.

Furthermore SPAs do not break accessibility, that is nonsense. Devs may break
accessibility if they choose to reimplement components without thinking about
it but that has zero to do with SPAs.

~~~
bo1024
Hi and thanks for your responses. I think you may not be considering my post
in the context of the above person's webpage. I would be interested to hear if
you see my perspective a bit more after viewing the page and its source code
if you haven't already.

(1) I do think I can make a small difference toward making the web better by
pointing out the drawbacks of unnecessary JS. I also think it's fair to
describe this page as breaking the way hyperlinks usually work on the web.

(2) I don't mean to say all SPAs always break accessibility -- again this is
all in the context of the page above. I do think, for the reasons I gave, it's
fair to say that a plain HTML page with a list of links is much more amenable
to generic accessibility tools than a block of JS that emulates behavior of
links.

~~~
scrollaway
I misunderstood your post regarding accessibility then :) it's unfortunate but
some react and Vue patterns tend to lead to a lot of div soup. It doesn't have
much to do with the tooling but rather a lack of education for the devs on the
subject and it's a testament to how easy it is to create custom components in
both.

> _I also think it 's fair to describe this page as breaking the way
> hyperlinks usually work on the web._

Well maybe. A good SPA imo will render the first pageload with SSR, which
means that your links will actually work the same. You share a link or open it
in a new tab or whatever and it will load a page full of HTML that might not
even need JavaScript.

SPAs do hijack the link system but they do so to retain natural back button
functionality. Back when they didn't, people complained about that, rightfully
so.

Howe there's nothing emulating anything. SPA links are anchors, as they are
anywhere else on the web, and all the apis are native to the browser. It
doesn't have anything to do with accessibility, no.

------
tyingq
I'm more interested in the future of _" you probably don't need a native
app"_.

It feels like browsers are closing the gap pretty well with things like
IndexedDB, offline features, WASM, etc. Still a ways off, but seems like it's
getting there.

I do worry, though, that it's not really in Apple's or Google's best interest
to move that along.

~~~
IloveHN84
Native will always be the best solution... Because it's native.

~~~
tyingq
Technically best doesn't always win the market. I'd love not writing 3
versions of every piece of functionality.

~~~
AnIdiotOnTheNet
How's that working out when there's more than one browser you have to account
for? What's the difference between polyfill or some framework, and something
like Qt or SDL?

Or I suppose we could just all use chromium, but we could also just all use
Windows.

~~~
ken
> What's the difference between polyfill or some framework, and something like
> Qt or SDL?

As a user, I usually can't even tell when they're using a polyfill on the web
(except when they stop, like GitHub did with type=date). (As a developer, I
often can't tell the difference, either. Some of them are that good!) So long
as you generate HTML/CSS/JS, it doesn't matter to me how you do it. That's as
'native' to the web as you can get.

I can spot Qt a mile away. A lot of the visuals look wrong and a lot of the
controls don't behave right. It's frustrating to use, and I always slow way
down and double-check my work because, e.g., popup menus show the 'accept'
animation even when you cancel them.

~~~
AnIdiotOnTheNet
> I can spot Qt a mile away. A lot of the visuals look wrong and a lot of the
> controls don't behave right.

You mean it has no respect for your native toolkit... just like the web?

~~~
tyingq
_" just like the web"_

How true is that? I was under the impression that for Android and iOS, Chrome
used the native widgets for most things.

~~~
tedunangst
How many SPAs use native controls with minimal styling?

------
anonyfox
Having developed with nodejs since v0.4, went through jquery => backbone =>
angular (1) => ember => vue => react, written stuff in several incarnations of
javascript (including coffee and typescript), used build tooling from grunt to
webpack and customized browserify, even built stuff with meteor... i can‘t
bear it any longer.

Actually now we are full circle again. Files that mix css/template/logic with
FOTM syntax, add some database calls during SSR and you have basically PHP.
Just more complicated tooling. Deploy your frontend on S3 and its similar to
FTP to Apache Servers, except you can‘t update just individual files. Run your
backend on AWS lambda and you have stateless backends like ... PHP, but with
cloud vendor lock-in. State Management like „Flux“ that poorly resembles state
machines on top of JS shortcomings.

I am personally switching completely to elixir/phoenix to do anything web-
related and can solve things cleanly within minutes. Also when Phoenix
LiveView finally arrives, it could be groundbreaking and replace many usecases
of modern SPAs.

------
BlackFly
I used to feel that way, then I met a one javascript developer in particular
who really made me see it differently. I won't get into those here, I just
want to tone down the "probably don't need" into a "don't necessarily need".

As a predominant back end developer, I do feel that the complaints from the
article are due to inexperience or misunderstanding:

1\. stateless requests: You don't have to cache any state by default, just
like server side. You start caching to improve performance and caching is
always one of the big 2 problems of computer science. Don't cache if you don't
have to: stateless has benefits.

2\. Reinvent browser features: use your framework! This is a solved problem. I
am not sure what the Angular or React solutions are but with vue just use the
vue router.

3\. More mature tools: backend suffers from this as well, I know a lot of mid
level software engineers that are always chasing the latest fads.
Microservices, containers, serverless, etc. The biggest issue I had when I
tried to do serious frontend development is just not being aware of the
tooling and how it works.

4\. SEO: Google can crawl your webapp: [https://searchengineland.com/tested-
googlebot-crawls-javascr...](https://searchengineland.com/tested-googlebot-
crawls-javascript-heres-learned-220157), I would prefer if the person making
the claim (that an SPA does not get crawled) would be the one providing the
evidence...

Don't get me wrong though. Sometimes an SPA is the wrong choice but it would
be hard for me to say if that is usually, rarely or a toss up.

I think many places that go from server-side rendered to client-side rendered
SPAs do not hire a bunch of front end experts when they do so. Then people
experience a bunch of problems because of the fact I point out in 3: lack of
awareness of the ecosystem. On the other hand, there sure are a lot of diva
developers who don't like working with old technology (for example, PHP), and
this probably causes a lot of the front end framework churn. Just like picking
up a new language, it takes time to produce idiomatic code. Of course, for a
new framework it takes time for the idioms to develop...

~~~
crooked-v
> I am not sure what the Angular or React solutions are but with vue just use
> the vue router.

For React there's a couple, but most of them boil down to the same basic idea
that you've got switch statements that decide which components to render based
on router state (rather than there being anything "special" about routing
entry points), and then something like a <Link> component that just acts like
an <a> tag but triggers the client routing change instead.

~~~
ThePhysicist
I used react-router before but absolutely hated how it mixes presentational
logic with URL matching. For new projects I just use a small routing helper
that’s written using React context and that performs URL matching the old
fashioned way (a list of pattern with parameters that are routed to specific
components). Works really well on all modern browsers and is less than 200
lines of code. It even allows for reverse routing (use a view name and
parameters to generate a URL) which to my knowledge isn’t implemented in
react-router.

~~~
crooked-v
> I used react-router before but absolutely hated how it mixes presentational
> logic with URL matching.

You may like redux-first-router, which has the URL literals as part of a
routemap attached to the Redux store, and then has all routing in the app
actually just be the dispatching of Redux actions. Your navigational
components then end up with stuff like:

    
    
         <Link to={{ type: THAT_PAGE_WITH_THE_STUFF }}>Link text here</Link>
    

...where the Link is actually just a convenience helper component wrapping <a>
that dispatches the action and provides a browser-friendly href reverse-
engineered from the routemap if possible.

------
danielovichdk
I tried the other day, yet again, to give it a go. You know, firing up VS Code
and make an app with express, node, react bla bla bla.

Coming from the .NET toolchain and expecting a lightweight, easy to start with
approach I was yet again totally shocked.

The hundreds of possible directions you can go in, in terms of frameworks,
packages and what not is ludacris.

I stopped working when my node modules directory topped 60mb and I still
hadn't made a data layer.

Good luck fixing that. I'd rather keep my code and tooling simple and clean.

~~~
s_y_n_t_a_x
You could use Blazor to export to webassembly, but it includes the entire .NET
runtime, so the payload is huge.

It's a bit silly to say you quit when you topped 60mb in your node modules
directly, something you never have to look at and doesn't represent what gets
built in to the final app. There's tons of dependencies when dealing with the
.NET toolchain.

There are hundreds of directions you could go in, and I consider that a good
thing. There are choices, but there are recommended paths for beginners as
well.

It sounds to me like you're hating on a toolchain that you don't have any
experience in.

~~~
danielovichdk
I understand the toolchain juuust fine. I have been making HTTP and browser
applications for two decades.

The technology landscape is absolutely ridiculous if you want to do things for
the web.

Each browser has its own standard, chrome is the new IE6, the industry is
hacking together assembly languages to port from other technologies,
preprocessors, minification, state and what have you not.

The web today had been tweaked beyond recognition and while the industry is
doing so, most of us forgot the beautiful platform that resides underneath.

I love HTTP, HTML, CSS and JavaScript, I really do, but I really believe there
is a huge tendency of amateurish approach towards making the web a better and
more standardized place.

Back in the day, we had much less choice, and that made working with the web a
lot more joyful.

~~~
stickfigure
_chrome is the new IE6_

I've heard this repeated a few times, and it's utter nonsense. Unless you're
deliberately going off into the weeds, a full featured SPA works the same on
Chrome, Safari, Firefox, and Edge. I don't even bother testing on multiple
platforms anymore; they just work.

I did web development in the IE6 era (and before). This is nothing like that.

~~~
danielovichdk
I do believe the live standards from whatwg is a good example of some vendors
making it possible to implement features before other vendors do.

It creates a gap, it creates a constant drive forward which again seems, IMO,
to sometimes be about vendor competition instead of the greater good of the
web.

------
ccalvert
I have modest skills as a developer. I was trying to convert an old static web
site into something more interactive. Without really thinking it through, I
started building a SPA. I got stuck on the SEO part. I found it innately
complex, but the real trouble came from trying to bring together the disparate
sections of the old static site while preserving and abetting SEO.

One day I just ditched the SPA and rebuilt the whole architecture with NodeJs
and Express. I was done in a few days. It could have gone even faster, but the
original static site was really a mess with years of accumulated bad decisions
embedded in it.

I know this is just one data point and not really proof of anything.
Nevertheless, the linked article made a lot of sense to me. Most of the
bulleted points resonated with me, but none more than the SEO issue. There are
solutions to the SEO issue, but I personally did not find them easy to
implement. If I were part of a big professional team, and we really needed a
SPA, I would have called this one differently, but I was working on my own,
and I didn't really have the sense at first to see that I didn't need a SPA to
achieve my goals. I was perhaps a bit too susceptible to the hype without
enough experience to really understand the issues involved.

~~~
WrtCdEvrydy
React Server Side rendering with Next.js is the best of both worlds.

You get streamed JS, with pre-rendered HTML for SEO.

~~~
ccalvert
Thanks. This does look interesting. It's hard to keep up with all the
frameworks, but this does look like something worth investing some time in.
I'll check it out.

------
dimgl
I can't agree with this article at all. Having an JSON API and a small web app
bundle that you can deliver with a highly-available CDN removes a ton of
scaling problems related to SSR and gives a clean separation of concerns both
from a managerial and architectural standpoint.

It also makes testing dead simple: you just make contracts on what the
response bodies will look like and just feed mock data structures into your
stateless web app. This allows the API team to make changes to the API layer
with confidence that as long as they don't change the contracts with the web
app, everything will still work.

------
caseymarquis
For new development, I reach for SPA tools (like VueJS with Webpack) fairly
quickly. The reasons for this are:

1\. Reusable web components. 2\. Clear separation of backend and frontend
logic. 3\. Using the latest version of javascript.

I really like HTML/CSS/JS as tools for building GUIs, but I feel HTML/CSS
specifically suffer from the inability to make components.

I think there are definitely instances where there is no need for these tools.
I would genuinely like to know how to manage the items listed above when this
is the case. ie Recommended tools for when I go "SPA seems like overkill for
this... what are my other options for this functionality?"

~~~
whytaka
> but I feel HTML/CSS specifically suffer from the inability to make
> components.

Are you familiar with CustomElements? [https://developer.mozilla.org/en-
US/docs/Web/Web_Components/...](https://developer.mozilla.org/en-
US/docs/Web/Web_Components/Using_custom_elements)

~~~
caseymarquis
Unfortunately, they're not widely supported yet. :(

------
valeriobo
Totally agree with the article, the spa hype has produced a lot of crappy slow
web sites and crippled productivity of many teams for years. I think ppl in
the industry are way too young and have the bad attitude to nod add tools in
their belt but keep only the last one that has hype. Spa are like applet or
Silverlight, just different tech, same goes for ws* vs rest api and so on...

~~~
AnIdiotOnTheNet
> I think ppl in the industry are way too young and have the bad attitude to
> nod add tools in their belt but keep only the last one that has hype.

The current culture is to only keep a job for ~2 years before moving on, why
wouldn't they adopt that attitude?

~~~
valeriobo
True, if you do not stay long enough to feel the consequences of your decision
you do not learn from those years. We do not usually hire ppl that change job
that often, but we are not in a silicon valley kind of enterprise

------
rorygibson
1) CRUD / data entry systems: stay with request-response.

2) Complex webapps with snappy functionality that need to feel "native" \-
whatever that means: think about an SPA. Then realise that mostly what you
need is (1).

3) Corporate homepages / brochure sites / product sites / blogs: use a static
site generator like Hugo, Jekyll etc. It's amazing what you can do with a
staticgen site now

[Insert shameless plug for Trolley, my product,
[https://trolley.link](https://trolley.link) ]

------
pcmaffey
The concept of a SPA is a total hack of web patterns. I predict in a few years
we'll refer back to SPA's the way we do now to AJAX or DHTML.

We're getting closer to the best of both worlds, where we SSR pages and then
"hydrate" them with JS components. The tooling around this isn't great yet,
but it's definitely all there.

------
amoitnga
1\. It's like saying you don't need Rails, just use Sinatra and if your app
really needs it then use Rails. I'll pick rails even for a super simple
project because I'm very comfortable, quick with it.

2\. "You don't need the complexity of SPA or javascript fatigue" and then you
install webpacker gem that wraps around webpack and not only you have a
headache of webpack but also of a gem that wraps around it. And then you need
some front end libraries and you start including them in in the way that feels
like a workaround.

I mean no disrespect to these wonderful tools, I appreciate the hard work
being put into these gems, and I will admit I didn't give it TOO MUCH effort
to learn. I tried it. didn't feel right. moved on.

I've just decided for myself that for now I'm gonna keep my backend ( ruby,
db, server ) in one mental bucket, and all the fronted ( css, js, html ) in
another.

For me to go traditional Rails way it has to be a super simple app, at which
point there will probably be other tools to solve the problem.

------
petilon
I couldn't disagree with this article more. Developing SPAs is easier than
server-render applications. The problem is React, Redux, and other such libs
make this more complicated than necessary. React is all about surgically
making the smallest possible change in the DOM to refresh the page. But is
that really needed? Most of the time it is not. Why not re-render the whole
page? This is what happens in the case of server-render applications any way,
right? Turns out 99% of the time it is performant for the SPA to rerender the
whole page. Instead of Angular and React, if you use simple libraries such as
UIBuilder (
[https://github.com/wisercoder/uibuilder](https://github.com/wisercoder/uibuilder)
) and MVC router ( [https://github.com/Rajeev-K/mvc-
router/](https://github.com/Rajeev-K/mvc-router/) ) you can build simpler
applications that work well and are super easy to develop and maintain. Each
of those libs is less than 500 lines, so super easy to learn and use.

This article says traditional web servers are stateless, but in the case of
SPAs servers are stateful. The opposite is true. Traditional web servers have
session state, but in the case of SPAs the servers can be stateless because
all servers are responsible for is persistence and query/search.

This article says maintaining browser history is a mess in SPAs. Not true. The
same MVC architecture that works so well on the server can be done just as
easily on the client, see this lib: [https://github.com/Rajeev-K/mvc-
router/](https://github.com/Rajeev-K/mvc-router/)

This article says server-rendering has fewer more mature tools. That may be
true. There are so many new tools for SPAs. But you can ignore them and build
SPAs trivially using the libs mentioned above.

This article says server-rendering is better for SEO. Not true anymore. Google
and Bing crawlers now execute javascript to crawl your content. This is more
work for Google and Bing but not more work for you.

If you know how to do it SPAs are the easiest and best approach because all
the server needs to do is implement persistence and query/search using a REST
API. If you later need a native mobile client this approach is already more
compatible with mobile than if the server renders HTML in addition to
persistence and query/search.

~~~
trimbo
> Developing SPAs is easier than server-render applications.

Not sure about "easier". I'm a backend person so take this with a grain of
salt but, to me, nothing on the web is easier than doing everything server
side. All of your code can be in one language (plus a template) and the same
build.

Consider what it takes to make a change in each model. In an SPA with one of
the frameworks mentioned, it requires several changes, across directories and
languages in both the front and back-end, and usually two different build
chains.

~~~
jamespollack
I think that "I'm a backend person" says it all -- most of the people in this
thread are probably not JS natives or front-end natives. All of the complaints
about JS fatigue, or not knowing how to use client-side routing are because
you've done things differently on the backend. Is it such a surprise that
front-end frameworks and tools make more sense to people who actually enjoy
and have experience working on the frontend?

If you provide an API schema, with a SPA the whole frontend can be developed
separately of ever touching backend code. Okay, so you changed the name of
model.thing to model.anotherThing - quick change in the reducer that is
consuming that end point and call it a day.

------
pier25
I've been making SPAs for a couple of years now and I totally agree.

Not only the complexity of development is increased, but there is no real
benefit for the vast majority of use cases.

I think there is merit in using an API though and clearly separating data from
presentation.

What I've been doing lately is using Jekyll with Vue components for some in
house projects. It works great.

Another option I've been trying out is doing SSR in JavaScript on Zeit Now
monorepos. Haven't used it in a real project, but so far it's awesome. You can
keep using all your front end knowledge, but render each route on the server.
No more managing state (Redux, Vuex, etc) or router.

------
nkozyra
While I've long been more comfortable with server rendered pages, I feel like
we're oversaturated with this sentiment. I don't think it matters all that
much.

The message is build with what accomplishes your goals and works with your
team's skills.

The notion that SPAs are only good for certain types of applications or
organizations doesn't make much sense to me.

Building server-generated web sites works faster for me because I'm still more
comfortable with it. SPAs make concessions but so do server generated apps.

~~~
sigfubar
> The message is build with what accomplishes your goals and works with your
> team's skills.

Unfortunately most teams cannot be trusted to pick the right tool for each job
without overcomplicating the planned implementation. Ego and the yearning to
do “cool stuff” conspire to derail projects that could have been built without
fuss using simpler tools.

~~~
marcinzm
>Unfortunately most teams cannot be trusted to pick the right tool for each
job without overcomplicating the planned implementation. Ego and the yearning
to do “cool stuff” conspire to derail projects that could have been built
without fuss using simpler tools.

Force them to only use simple tools and the good ones will move elsewhere
because they know that being stuck on just the simple things is going to limit
their careers.

edit: And losing them will probably cost you more project velocity than you'd
ever gain with different tools.

~~~
sigfubar
Good riddance! A project is undertaken to achieve some specified result, not
to advance a career or learn some new tool. Don’t get me wrong: those lofty
things are welcome when they occur as a byproduct of developing commercial
software, but these cannot be the driving factor behind decisions that affect
the bottom line.

~~~
marcinzm
Part of working with humans and managing humans is understanding they're human
and not machines. And keeping those humans happy does very much impact the
bottom line. If spending 20% more effort on a project retains engineers that
speed up projects by 30% then it's a net gain for the business. Bad companies
and managers don't understand that and then wonder why all their engineers are
bottom of the barrel (or rather why their projects end up such disasters while
those of their competitors don't).

------
bzalasky
The answer to whether a single-page app is appropriate for a given project
needs to consider product requirements, team structure and available
resources.

Libraries like React are awesome for breaking down complex (or even not so
complex) UIs into story sized chunks that can be tackled by different
engineers or even different teams. This is one of the biggest reasons to
consider using them, IMO.

Even in the case of relatively unremarkable CRUD application, if the backend
is split across multiple services and teams it may be entirely reasonable to
choose to build a SPA frontend with a dedicated team.

On the other hand, if you're building a Rails app with a small team, and most
engineers are working full-stack out of necessity, a SPA may not be
appropriate.

As companies grow, I've found roles tend to become more specialized. Your
decision to build a Rails web app early on could be considered legacy cruft
(by some) down the road because it can be difficult to break down and deliver
a feature across the full stack if you're not accustomed to building web apps
that way.

There are tradeoffs to all of these approaches (including the hybrid
approach). Ultimately, you need to do what's what right for your product and
team(s), and make your technology choices intentional.

~~~
onion2k
_The answer to whether a single-page app is appropriate for a given project
needs to consider product requirements, team structure and available
resources._

And the users.

~~~
bzalasky
Hopefully, users have been considered in the product requirements, but yes, I
wholeheartedly agree.

------
alexandernst
The main problem with SSR is that the moment you want to do something a little
bit outside of the-happy-path of your framework o choice, you're knee deep
into sh __.

Let me give you the simplest possible example. A form with multi-dependant
inputs: you select an option from a dropdown, and depending of the choice you
made, you see another dropdown with some options, or maybe an entire new set
of inputs. Maybe there is a button that will open a popup with another form,
dynamically generated based on what you choose. Or maybe there is data you
must dynamically fetch from the server, based on some combination of actions
that the user did.

You can play the ".show()" and ".hide()" game with plain JS, but if you have
more than 5 inputs, I promise you, you'll be really sorry for choosing that
method.

You can also "inject" somehow any SPA just into that particular view in your
project, but then you'll be already dealing with the cons of both SPA and SSR.
It doesn't pay off.

I have been doing all types of FE and BE development, and what has given me
the best results is making the BE a REST API and doing the rendering on the
frontend.

Just my 2 cents.

~~~
save_ferris
This is where the hybrid approach they mention in the article really shines.
Embed front end frameworks where you need it, and stick to SSR where you
don't. It doesn't have to be a binary choice.

~~~
alexandernst
Yes, that's what I said in my comment. But if you choose that path, you
automatically have to deal with the problems from both worlds. "How do I
configure webpack?", "Why is babel not working?", "How do I do _this_ or
_that_ in React or Vue or whatever?". Going the hybrid approach is choosing to
deal with the problems from both worlds.

~~~
save_ferris
But configuring webpack is usually just an initial set-up cost. I've never had
to go back and rejigger webpack once it's set up. You might have to touch it
again if you make major changes to how you serve assets or something, but
these one-time costs are part of development.

> Going the hybrid approach is choosing to deal with the problems from both
> worlds.

This is true of any technology. Every framework, language, library, etc. comes
with a cost in setup, design, maintenance, etc. For us, the cost of dealing
with problems from both worlds is much, much lower than trying to shoehorn a
SSR app with SPA-like functionality. By limiting the size and scope of the
SPA, you avoid a lot of the really hairy state management problems that can
arise when an SPA is trying to keep track of too much state.

------
wrestlerman
I have the same opinion. Building SPA is f* hard and time-consuming. But it
depends. If you know how to build SPA fast, then, by all means, go that route.
(As a solo dev or small team)

I use Rails, but Rails views are a disaster. You can use a lot of different
patterns/gems, but still, logic is highly coupled with the view layer.
Personally, I like Phoenix approach with templates + views. But still writing
script tags makes me cringe a little bit.

But I wouldn't discourage people from using SPAs, though. If you are gonna
have a lot of buttons, modals, different tables, charts, forms and stuff like
that, I would go SPA. Or first serverside -> SPA. Especially, when you are
working in the team, it's so much easier to tell one person to craft this json
api and another to craft this design with a consumer for the json api.

That become long... in short: if you have a small team or solo go server side
99%. If you have a big team or app that's gonna be very heavy UI -> go full
spa or go server(mvp) -> spa

~~~
64738
Take this with a grain of salt, as I only recently came across it and haven't
used it, but the Trailblazer framework looks like it has a good way of getting
logic out of the views.

~~~
fyfy18
I've been using parts of it on most Rails apps I've worked on for the last few
years. The form object pattern (Reform) really helps when you need to update
the same model in different places with different validations.

For example maybe an Order only needs a price when it's created, but needs a
invoice number (and some other validations) when marked as paid, but an admin
should be able to override those validations at any stage. If you are doing
something like that with standard Rails the model is going to end up as an
untestable mess, where as the form objects can be tested on their own.

My only complaint is that the creators of Trailblazer really don't seem to
like Rails, so trying to get them to both work together can sometimes be a bit
tricky. And the documentation is lacking if you want to do some more
complicated things.

~~~
64738
Thank you for your thoughts on it, I'm intrigued enough to really want to look
more into it. Even if I don't get to use it, I think it will give me some
ideas that I can apply to other projects.

------
ozim
I don't get 'SEO for free' argument. You don't SEO application, you SEO
landing page and you don't want crawlers to crawl your app.

~~~
Illniyar
Not quite. Lot's of applications have SEO for their main content. Social
networks (reddit, twitter), marketplaces, shopping sites (some shops, like
nike's, are quite complicated js-wise), forums (stackoverflow for instance)

------
syllable_studio
I have experience building both SPA apps and server-side templated apps. They
each have their strengths and weaknesses.

Just as a SPA won't solve all your problems without any trade-offs, getting
rid of a SPA framework also won't solve all your problems -- you'll probably
need to re-invent some wheels and then discover that your new solutions are
hard too.

I think it's good to have a healthy dose of skepticism about new technologies.
But it's also important to understand their value and not to hate them just
because they're hard. I like that the author tries to find this ballance.
Though, honestly, from my own experience, I would rename this title to "You
might not need a single-page app."

More than once, I've tried to build something without a SPA framework only to
realize that if there is any interactivity at all, it's often just simpler to
use a SPA framework in the first place.

~~~
wreath
> it's often just simpler to use a SPA framework in the first place.

Simpler or more convenient? I've yet to see a production-grade React setup
(for example) that is simpler than having either vanilla JavaScript or even
jQuery to achieve the same interaction. The amount of tooling required to do
simple interactions does not justify the technology for most applications IMO.

~~~
pault
How complex were the applications that used those production-grade React
setups?

As the number of possible states increases, your vanilla JS solution explodes
in complexity when you have to manually define every state transition. The
declarative nature of SPA frameworks means all you need to worry about is
presentation of your data. If all you need to do is some form validation, then
writing an SPA is a terrible idea. If you need to build a UI that functions
more like a desktop app with long-lived sessions and complex workflows, trying
to manage all of your DOM updates will be a monstrously difficult task. You'll
basically end up implementing a slow, buggy version of react.

------
rajangdavis
I used to love SPA's but, in my experience, the most poorly organized SPA code
is severely more complex than poorly organized server side rendered app code.

With SPA's, you're usually dealing with some build system, a variety of
dependencies, and a swathe of design patterns. At worst, you have everything
located in a single file which has all of the above across tens of thousands
of lines.

With server side rendered code, you are (at worst) following someone's code
that didn't follow the correct separation of concerns. At worst, the spaghetti
code will be within a couple thousands of lines of code.

I had a project recently where I ran into both of the above scenarios and I
would prefer to debug poorly written server-side code than poorly written SPA
code. It's night and day in terms of complexity.

------
skinnyarms
How about build-time rendering?

Server-Side rendering tightly couples your front-end to your application
server. Scaling the site means scaling up that application server. A bug in
one "page" of the app can cause the whole application server to go down.

If you leverage client-side rendering then it's easier to decouple your front-
end from the back meaning you can take advantages of things like segregated
micro/serverless services and progressive web apps. You can also re-use those
services for multiple applications, making it easier to keep the business
logic OUT of your pages and in an API layer where they belong.

I agree that SPAs are not the solution for everything, but I think that
server-side rendering is on it's way out.

~~~
bwilliams
> A bug in one "page" of the app can cause the whole application server to go
> down.

That doesn't seem like a valid issue. If a bug in a single page could take the
application down then the same could be said for the API powering the front-
end.

> If you leverage client-side rendering then it's easier to decouple your
> front-end from the back meaning you can take advantages of things like
> segregated micro/serverless services and progressive web apps

Your PWA point is valid but I don't think the microservices point is.
Microservices add a ton of complexity and can easily become overwhelming. If
you get to the point where your application can benefit heavily from
microservices then congrats, you've made it.

> I think that server-side rendering is on it's way out.

If anything I think its on its way back in. So many companies bought into the
benefits of client side apps and are now seeing the trade-offs that aren't
very favorable.

~~~
jamespollack
> That doesn't seem like a valid issue. If a bug in a single page could take
> the application down then the same could be said for the API powering the
> front-end.

What? The previous poster said coupling frontend / server tightly will result
in crash of both if there is a server bug. Your response is that a bug in an
unattached API could happen? Of course a bug in your API could crash your API.
But at least then it's just your API that's crashed, not the (thousand)
servers you're using to serve the front end and every device using them.

~~~
bwilliams
If your API is down who cares if your app is being served or not? In the
majority of cases it won’t work because the API is down.

~~~
skinnyarms
If my app runs off multiple API, then the bug in my (for example) commenting
API shouldn't prevent users from using the shopping cart API to check out.

------
ttty
Normally you'll always need to add something interactive, therefore js. To do
that with server side rendering you'll couple the client side to the server
side.

For example the server has to send a tag with a class name that the client
also is aware of that.

Therefore you have 1 component, where half is on server side and half of on
client side, which in my opinion is not maintainable.

~~~
pmlnr
> Normally you'll always need to add something interactive

Especially in news, articles, longreads, right? /s

Most of the internet content would be perfectly fine without interaction, or
with ordinary, oldschool POST forms

~~~
franzwong
News web site can return part of the page (e.g. news article) to decrease
TTFB, and then load less important content (e.g. news recommendation) after.

As author said, it is tradeoff.

~~~
pmlnr
... or inline all in one html on server side and send it down at once?

------
joduplessis
The massive problem with this approach is that more and more the requirements
we see are exactly where SPA's shine: real-time elements, rich UI and
eventually PWA implementation when/if. I agree that the traditional SSR has
served everyone well - but I don't think we need to be stubborn about what has
worked vs. what can work.

~~~
itronitron
There are a lot of hidden/implicit requirements when people think of SPAs. In
order to do them right the interaction design needs to be worked out in detail
with the developers so that everyone on the team knows all possible states of
the application and how to best manage that.

------
potench
“do I need a component library?” is the question I ask when deciding to use
react or not.

It’s a totally different question to ask do I need a spa or a server rendered
app, both can be dead simple or heinously complex or reasoned away to prove a
point...

I 100% of the time want (1) to architect my UI as a collection of atomic,
reusable components, (2) get page specific server rendered html per route, and
(3) do JS in a sane way (manipulate DOM, manage client state, and support a
series of interactions that do not reload the page.)

So, what are my options?

1\. React/node 2\. Sacrifice one of the above.

~~~
brylie
I think all of your requirements could be met in a myriad of ways. E.g. Django
templates/Handlebars can be organized as reusable components, many backend
frameworks will render HTML per route, and there are several JavaScript client
libraries including Vue and, dare I say, jQuery that will give you a sane way
to do client interactivity without page refresh with varying degrees of
declarative code style.

~~~
potench
I think this means you are sacrificing the component library requirement.
There is not a sane way to intermix js,html,css as a single component with
dependencies on other components with your approach. What you end up with is 3
very distinct/separate/unique/difficult to maintain solutions across css, js
(probably 4 if you include js/html), html.

~~~
brylie
Vue.js and Aurelia offer examples of how UI components can be organized and
composed, while allowing clean separation of structure, function, and
presentation (divided along the lines of HTML, JavaScript, and CSS by design.)

The main point is not to limit ourselves to a monotheistic worldview that
convinces us, without substantive evidence, that "all other ways are wrong."

~~~
potench
The main point is that I listed 3 requirements/wants. Your example of Vue.js
or Aurelia sacrifices the requirement for server-rendering. > Server Side
Rendering is a new feature of the Aurelia framework, intended for use by early
adopters. [https://aurelia.io/docs/ssr/introduction#how-it-
works](https://aurelia.io/docs/ssr/introduction#how-it-works)

------
sametmax
Or microservices.

Or nosql.

Or containers.

Or graphql.

Free tech is not zero cost tech. Size your stacks to your actual needs.

~~~
fma
I happened to watch a conference talk on YouTube by the director of
infrastructure at Netflix. He closed it out by saying, yes we open source
everything, and yes this solution works for us. But just because we do it
doesn't mean you should. Do what works for you.

But in reality...I only need it because people on the other side of the
interview table expects every engineer to have 3-5 years experience of x,y, z.

------
ldiracdelta
One of the biggest reasons I reach straight for React is that I then have only
one UI language. Instead of templating on the server in python or c# and then
doing any UI updates in javascript on the client, I only have to write
templating code in React and it runs on client and server.

~~~
dwaltrip
You switched from a C# or Python backend to node.js so that you can render
React on the server, correct? Or are you doing something fancy to serve
react.js rendered contents from a non-js backend?

I agree that the hybrid approach of both server-side templates and SPA-
controlled content looks difficult.

~~~
ldiracdelta
Personally, I don't use node.js as a backend. I normally use Django REST
Framework (DRF). I may do server-side rendering of the client using express,
still calling back into DRF for the data. The important piece for me is that I
don't like the idea of generating a page in one language and then mutating the
UI on the client side with another language. I just use one language for the
whole UI.

~~~
dwaltrip
Thanks for sharing, that is an interesting setup.

------
dsego
One problem we're having with the hybrid approach (Laravel + Mithril) is not
being able to reuse common UI components between php & js rendered parts.
Laravel has blade templates, and mithril is coded similarly to react.

The other problem is deciding which to use when starting a new feature or
section. A page may start out fairly static but end up needing a rewrite when
the specs change and start requiring more dynamic UI elements.

~~~
scarface74
I would rather change a page if and when it is needed by a new feature than
over engineer up front.

~~~
hombre_fatal
Well, the thing is that you don't know if you're "over engineering" up front.
That's the whole challenge.

And rewriting down the road because of the wrong gamble can be very costly.
Make the wrong bet enough times and you'll see that it's not over-engineering
but just engineering for changing requirements.

A classic example is thinking it will be simpler to avoid React and use a few
.show()/.hide() toggles. Simple at first. Then as you take on complexity, you
start to feel like the lumberjack who thought he could save time by skipping
the axe sharpening.

~~~
scarface74
Exactly. You don’t know what you will need. It’s the classic concept of YAGNI
and emergent design.

------
Trisell
It seems like a good 80-90% of the hate of SPAs doesn’t seem to be aimed at
SPAs as much a poor programming and poor user experience because of that. In a
lot of the cases that people here use. It’s not the SPAs fault as much as the
programmers that messed it up. And honestly why do we think that putting it
all back to SSR is magically going to fix poor programming?

~~~
detaro
You get quite a few of the things that SPAs often break for free with more
traditional apps, because it's provided by the browser.

------
noir_lord
> Frameworks like Rails, Phoenix, Lavarel, etc. have been around for a while
> and they are very stable.

Laravel is stable in production but they break backwards compatability all the
time and not always in major versions.

Symfony is _much_ better about it.

------
subpixel
On the one hand, site like [https://dev.to/](https://dev.to/) that are built
in Rails and rival the speed and performance of any _static site_ support the
argument that you can just use the tools you know.

On the other hand, to get your Rails site to function that well takes a lot of
work - it is by no means the starting point.

Systems like Next.js and Gatsby.js and others are attractive in that A) they
offer the ability to use both server-rendered and client-rendered React, and
B) exceptional performance is the starting point. It's up to you to slow it
down, not speed it up.

~~~
greenhatman
I think dev.to is an SPA. But not built with a framework.

~~~
tpetry
It‘s a traditional server side rendered application. But they use a custom
implementation like turbolinks and instantclick to change the sites content
without a full reload.

------
fma
So, a question coming from a guy who's been doing Java backend processing for
a long time and thinking of making a side project. Was going to go the Angular
route, but I'd like to have good SEO. I'd also like to get a POC/MVP up and
running to build momentum...don't want to waste time on the front end when
it's basic form submissions to kick off data processing.

To show how long it's been since I've done front end...My last 'full stack'
development had plenty of tables to style the application _grin_.

~~~
MarvelousWololo
A couple of weeks ago I tried the official Angular tutorial on SSR and found
it super difficult. If you're willing to give React a try I would choose
Next.js. It's pretty much a Node.js web framework that uses React for its
views and has SSR out of the box. It has client side routing, so smooth page
transitions, it was also fairly use to style the app with good ol css or sass.
Ping me if you have any questions.

~~~
MarvelousWololo
Oh I forgot to mention: if you're doing this just so you could learn modern JS
then rolling your own solution is all fine. Other than that I would avoid this
at all costs.

------
buu700
Anecdotal: cyph.com started off as an SPA, mainly so we could share some
components and styling with our actual application — and ever since we
migrated to a static WordPress site with a handful of Angular Elements it's
been both a lot easier to maintain and way faster for end users.

(Sure, we could've gotten similar performance with server-side rendering, but
at least with the current state of SSR tooling that would've been way more
distraction from building our product than we could justify.)

------
asaddhamani
I agree with this so much. These days, the first thing developers will do when
making a new app is setup babel + webpack + react + redux, then make an API,
all for mostly CRUD applications.

Most applications don't require these frontend frameworks, and it just adds
needless complexity in most cases. I've suffered due to this, and so I've
recently made the move back to server rendered apps.

And Rails with Turbolinks + UJS might not perfect, but it gets you like 80% of
the way there for 10% of the effort.

------
oblib
This article feels to me like complaining about making the simple difficult.

Since I work alone I suppose I'm not up to speed on what defines a single page
app but the apps I've been building with PouchDB, jQuery, and Bootstrap run in
a single page.

"Stateless requests Traditional web servers are built to be stateless. "

True, but "apps" should be designed to be self-contained (i.e. all the user
navigation is done within the app UI, not the browser UI).

"The browser knows how to deal with a traditional architecture If you go with
the SPA route, you’ll always need extra code to emulate trivial browser
features."

That's a pretty trivial problem and browsers don't really solve that, nor
should they.

"Fewer, more mature tools Avoid the Javascript fatigue by not relying so much
on Javascript!"

The apps I'm building are almost entirely Javascript. I see that as a good
thing. What little I do on the server side I do with Perl, which is something
I've been doing since the `90s, so I can feel "traditional" doing that if it
helps me sleep at night.

"SEO for free Single-page apps have to add extra infrastructure and code to
make sure they can be indexed by crawlers."

This is not so difficult to address and in some cases it's not even a
consideration. In the case of a "blog" app you can simply assign a url to a
post and deliver a page built on the fly specifically for it. Google can parse
that.

~~~
Arkanosis
> i.e. all the user navigation is done within the app UI, not the browser UI

Not sure if that's what you mean here, but when this breaks the “back”,
“next”, “refresh”, “bookmark” or “share URL” features of my web browser (among
others), I hate whoever has been responsible of the design as much as I've
hated Flash in the past.

~~~
oblib
I'll offer the distinction is rather you're using a "web site" or a "web app".

A web site should never break your browser. A web app should be able to run in
"Full Screen" mode without needing to use the web browser UI.

~~~
Arkanosis
I get it, and I think the distinction is relevant, indeed. Unfortunately, way
too many developers think it's a good idea to build a web app instead of a web
site, when it's not. Same issue as with Flash before, in fact.

------
1ste
Not very convincing.

React was introduced in 2013 and angular 2 was created in 2015.

The only server side rendering I'll be doing in the future is with the likes
of nextjs or similar.

~~~
a_wild_dandan
Yeah, I start with an SPA and adapt to the use-case. It either needs to be a
SPA, or SPA -> SSR is easy (via Gatsby/Next.js). The other direction though,
seeing projects grow from SSR -> interactivity/SPA is usually a horrifying
display of highly-coupled code spaghettification.

~~~
virtualwhys
> Yeah, I start with an SPA and adapt to the use-case. It either needs to be a
> SPA

Aha, by mistake you corrected your grammar! HNers cargo cult everything,
including grammatical mistakes like "an SPA" ( see literally everywhere in
this thread). Just say it out loud, "I start with an SPA", does that roll off
the tongue? No, neither does, "I'm going to buy an sailboat". However, "It
either needs to be a SPA, ..." is totally natural.

While this comment may not seem on topic/useful, it's a useful meta comment --
please don't take offense.

~~~
edwardhusarcik
SPA isn't pronounced "spa" but S-P-A thus an SPA is more likely correct. See
"an FBI agent" for an example.

~~~
virtualwhys
Hah, the relief! That was driving me crazy, thank you for clarifying the
usage. I've only seen it written and blindly assumed "spa", not S-P-A.

Now I can read SPA posts without cringing...

~~~
edwardhusarcik
Lol keep in mind I could be completely wrong! It seems like there isn't a
definitive rule. :(

~~~
virtualwhys
No, it makes sense, although as you say there's no rule, so some will use
"SPA" and others "S-P-A".

I'm reading it as "an S-P-A" now and it feels so, so much better :)

------
nojvek
I’m an advocate for SPA’s when they make sense. They have a clear niche. When
you need to build an “application”. Like photoshop. Not a simple website that
serves information.

Most websites are best served by serverside rendering. Or some form of hybrid
where you only send the templates as JS that will be in need.

With SPA’s what usually ends up happening is that the whole app is sent in the
first load. All the views, their css and shebang. <1% is actually used by the
browser. This is where most hate comes from. Most people give a shit about
“time to first meaningful paint”. It’s what makes up for that “wow that was
fast experience”

You can optimize both SPAs and server rendered pages for ttfcp. The former
requires a lot more discipline.

Browsers also do a lot to render as quickly as possible without the whole page
being downloaded. With html it’s simple and they have a lot of streaming
tricks.

JavaScript is not that simple. It blocks the eventloop and the payload is
downloaded in full, executed and then a paint can happen.

There are trade offs. SPAs can offer high interactive experience when server
side rendering cannot.

SPAs are great. Just don’t throw everything away. We need the baby.

------
clessg
Personally, I'm very interested in the possibility of Phoenix LiveView giving
us the best of both worlds: [https://dockyard.com/blog/2018/12/12/phoenix-
liveview-intera...](https://dockyard.com/blog/2018/12/12/phoenix-liveview-
interactive-real-time-apps-no-need-to-write-javascript)

~~~
arbie
> As an application developer, you don’t need to write a single line of
> JavaScript to create these kinds of experiences. You can write and test all
> your code in a single language: Elixir.

Now you have _two_ problems.

------
manigandham
Agree that SPAs are usually unnecessary. The big problems with JS SPA's is due
to the limitations of javascript and the browser runtime. The one major
innovation has been component-based view models while server-side frameworks
have been stuck with older template-based approaches.

Component-based views are starting to get to server-side frameworks so that
should reach parity within 2 years and WebAssembly will change the rest. Now
apps can be built using many different languages with OOP/functional styles,
strong typing, dependency injection, etc, and run at native speeds in the
browser. With the next gen of WASM running threads, GC, and DOM abilities, JS
frameworks will likely start a slow death as the existing web frameworks start
to have both server and client side delivery models.

ASP.NET Core with Razor/Blazor is a great early example of this:
[https://www.youtube.com/watch?v=Qe8UW5543-s](https://www.youtube.com/watch?v=Qe8UW5543-s)

------
EGreg
Serious question:

At [https://qbix.com/platform](https://qbix.com/platform) we wanted to stick
closely to the Web standards so we built a hybrid - although new pages would
be loaded with AJAX, out of the box we made the “easy development path” cause
every to page load from the server. This was because back when we started,
search engines and other crawlers didn’t execute Javascript very well.

We always kinda felt bad that we didn’t “fully” embrase the “new and best” SPA
trend, but also felt good we were giving people choice and were more
compatible with Web Standards. And now as time goes by I see more and more of
our choices vindicated. Is this anti-SPA backlash just another fad? Or were we
right to give people two ways to render the same page - one on dynamic
navigation and one on refresh?

[https://qbix.com/platform/guide/pages](https://qbix.com/platform/guide/pages)

------
arendtio
I kinda dislike this article. Not because it isn't true, but because of the
effect it might have on some readers.

Yes, building a SPA is not always the best solution, but sometimes I get the
feeling that a lot of developers hide behind 'I know how to build good SSR
pages and all SPA I have used suck so I will not learn that sh*t'. If you know
how to build a PWA with SEO support, offline+sync capabilities and push-
notifications, you will know when to choose what (because of the pain you
experienced learning it).

If your boss chooses your tech (from the latest buzzwords) and he doesn't
understand the implications, I am truly sorry for you, but don't blame the
tech on it (ask your boss for a seminar on 'How to Communicate with Managers'
maybe then he will understand that you are trying to tell him something...).

------
nkingsy
I have a list of widgets and a button to create a new widget. I don’t want a
full page reload when I create a new widget.

What are some elegant strategies for handling this with SSR?

I’ve used turbo links and found it rather clunky. Haven’t seen a solution that
lets me elegantly reuse server side components in JavaScript without going
SPA.

~~~
colecut
Why does creating a new client side widget require a server call at all?
Couldn't you have the widget in a JavaScript template and just clone it on the
dom client side?

~~~
nkingsy
Cloning from a template would be the what, but I was wondering if there are
tools designed for this. It's the kind of thing that could spike complexity
and I would want an established pattern of delivering html solely for the
purpose of javascript manipulation. It's not a hard problem, but a messy one.

~~~
colecut
I would use a simple "javascript templating engine" like mustache or
handlebars, to easily inject dynamic content into your widget templates.

------
mduerksen
To add some use cases where an SPA would be the favorable choice:

\- Web-tech front-end for an embedded device. The device, which often has very
limited CPU cycles, is not burdened by rendering.

\- Apps that are intended to be running locally and on multiple platforms
(e.g. via Electron), as well as in browser.

------
chimen
What about separations in teams where designers don't mess with backend
programmers code? Updates and parallel works on the frontend and backend
projects without issues? What about servers that respond with minimal data and
consumers that deal only with displaying the received data? Pushing code, re-
compiling and restarting webservers all because a button had to be made green
or its shadow changed? What about CI/CD, automated tests, automated
migrations, builders and compilers consuming dollars and energy for that
button change?

I'm happy with building SPAs where it makes sense (myaccount/admin). The
problem is Javascript and its ecosystem but you could very well go with Ember
which is stable as...and be relevant for years.

------
Ericson2314
Porque no los dos?

We pretender enough so if you turn off JavaScript you get old school and if
you turn on you get SPA. All the basic widgets are server/client agnostic, and
we have a combinator to special-case the server vs client code when needed.
The types enforce client-specific functionality isn't used otherwise.

We also have a "DOM puppet" backend which allows everything to be compiled to
native code puppeteering browser APIs from a fair. Prerendering, that, and
direct JS output all all supported through related typed abstractions. Soon we
will compile the puppeteer to WASM too, so we won't even need the direct JS
output anymore.

------
oneshore
So much of this is because of the mobile "app" craze where -- due to the
limitations of mobile app architecture, you had to build a stateful "app"
instead of several independent screens with some limited shared state (usually
just a token).

Native mobile UIs are great, but something as simple as cookies / local
storage could allow for stateless (or at least less stateful) mobile apps with
native UIs.

Now, the abomination of hybrid (cordova), or pre-processed (react
native/xamarin) mobile apps is whole other thing, but often why web apps are
translated to SPAs.

If we need a mobile app as well, why not use a common code base for web and
mobile...

------
sebringj
I think a more practical approach is to focus on a generic enough UI toolkit
meaning detached from any specific tech stack that will give a feeling of
continuity to customers as they move from static pages and SPAs and different
flavors of ideas that IT tried along the way. One SPA to rule them all is
ridiculous as it doesn't work that way with scale as you have independent
teams working on various projects that will be hindered by a single approach
in that everyone will have to understand x approach and also have stupid
meetings about it.

------
littlecranky67
There are some features which will clearly call for a SPA over SSR, if you
need

* to continuously play media (video/audio) while the user interacts with the web app (think modern youtube, soundcloud, spotify web, video news sites) * provide offline usage/features * highly interactive app with extensive use of drag'n'drop, animations, touch events etc. * data sync between browsers/tabs (think moving a ticket in a trello board should update the stacks in other open trello tabs or even for other users that currently view the board)

------
jtms
A well written rails app with good caching and some async stuff sprinkled in
where necessary generally feels just as responsive as an SPA for a fraction of
the dev cost.

------
PretzelFisch
I have always used SPA for line of business applications. The SPA SEO request
seems like a red flag that the wrong approach has been taken.

------
matchagaucho
Counterpoint... how many times have you clicked on a _Show More_ link and
thought to yourself "No, no... _please_ don't redirect me to another page".

Progressive reveal patterns are expected by end users. It's just lazy for a
programmer to assume old-world CRUD patterns with server-side render.

~~~
Toutou
I can't see why the Show More content couldn't be rendered server-side,
fetched with AJAX and plugged into the DOM with two lines of JS. SSR, no
redirect nor refresh, progressive reveal af.

~~~
matchagaucho
That pretty much describes SPA behavior.

The payload can be JSON or HTML... but the UX should not redirect.

------
lloeki
Not only you probably don't need a single page app but you also probably don't
need a client side lib to build and render your views... Server side view
caching and 304 can go a long way and saves round trips, even at scale and is
much more friendly to high latency/low end cpu user agents.

------
stevehiehn
Most of the projects I've been on there is a web app & native apps. So the
appeal of a single page app is you will write the exact API/auth for all the
clients. Would it be tempting to not use the same auth flow/api etc if you
don't use a single page app? Not sure.

------
stevebmark
It's 2019 why doesn't anyone understand that all search engines can fully
index SPAs?

------
k__
I simply prefer them because I think their architecture is simpler than some
frontend/backend mixed HTML stuff.

JAM-stack etc. just create static html/css/js and deliver it over a CDN of
your choice, then hook into the services as you need them...

------
intrasight
Wait - what other type of application is there? I transitioned to SPAs 18
years ago and would never look back. That is for "applications". For web sites
I would never use SPA. I stick with server-side rendered HTML.

------
ercu
For me, the biggest problem with SPA is, needing node.js when you want SSR.
There should be better ways than adding another backend layer if your stack is
different and you don't want callback based multi-threading.

------
johnchristopher
> Gulp, CoffeeScript, BackboneJS, and SASS, all of which have been superseded
> by newer tools. Avoid the Javascript fatigue by not relying so much on
> Javascript!

What ? These are all javascript things, right ?

~~~
burlesona
That was his point. The rails stuff he learned five years ago is all still
considered good practice, but the JavaScript stuff he learned (listed above)
is now considered antique.

~~~
buu700
I think the general point holds up, but why is sass in that list? I know some
newer alternatives are used with React nowadays, but sass is still very much a
best practice in general as far as I'm aware.

(If he means SASS vs SCSS syntax, I recall using SCSS ~8 years ago, so it's an
odd choice to include either way.)

------
exabrial
If latency drives your conversion, then SPA is [probably] not for you.

------
codeisawesome
In “reasons for going SPA on a greenfield project” I would add:

\- Need for a mobile app is close on the roadma and there is an opportunity to
build server code in an API first fashion.

------
SimeVidas
You probably need a publication date for your article.

------
nailer
The term SPA is outdated and inaccurate ( most web apps have multiple pages)
but until the DOM APIs include data binding: yes you do.

------
zokier
This is a tangent, but is Github really still mostly ssr? It sure feels more
spa-like these days, full with their own loading bar.

~~~
ec109685
They use turbolinks to hot swap the html.

~~~
asaddhamani
Turbolinks specifically?

------
sriram_iyengar
Valid points. \- another aspect to consider seriously when designing SPAs is
authentication. I have built ReactJs applications and everytime we need a
different module that had only the login functionality. Somehow this always
appeared disconnected whereas In traditional apps you have a middleware that
watches before rendering, be it client side or server side rendered.

------
sheeshkebab
Coming from similar background as author (various legacy web apps with all the
challenges of learning now useless js frameworks) - I’m now have a different
opinion:

SPA approach should be the default unless you have specific requirements to
add html SSR (and even then google is pretty good at indexing public spa
content too).

So, respectfully disagree.

~~~
acjohnson55
You're disagreeing, but not providing any justification for why SPA should be
the default. Why do you think this?

~~~
a_wild_dandan
I'll try adding to the conversation by at least justifying why _I_ like SPAs:
clearly decoupled front-end/back-end logic, likewise parallel
updates/deployment from different teams, back-end mocking, minimal data
updates for DOM changes, easy integration with microservices, powerful front-
end tools to deal with client feature creep (e.g. interactive widgets),
reusable UI components, easy migration to multiplatform desktop apps (e.g.
Electron), possible single language for everything (JS, rather than a mishmash
of JS/HTML/CSS/Python/PHP/etc), easy integration with hybrid or SSR stacks (
Next.js, Gatsby, etc).

But all this is just rationalization for one simple fact: I'm vastly more
productive building SPAs. I know the tools, and I can quickly deliver anything
from simple sites to richly interactive experiences _very_ quickly. I can go
from SPA -> SSR (via, say, Gatsby) easily. But going the other direction from
SSR to something interactive has been far more painful for me. That's why I
default to SPAs and adjust from there.

------
Chloro
I don't get it. SPAs are easy to make and have way more pros than cons.

------
miguelrochefort
Building a SPA is not more difficult than SSR.

------
trumped
You probably dont need a 40mb app either...

------
wnevets
but how else would I get a job making SPAs if I don't make SPAs? /s

------
ilrwbwrkhv
and if u have to use a framework please use something like mithril

------
aviato
I’m surprised this article doesn’t touch on Next.js at all.

~~~
jamespollack
Author too busy hating to actually explore tools that would do exactly what
they want.

------
vajrapani666
The OP glossed over managing styles and i18n between embedded JS apps and the
host app. I'm not sure if there is a way to create strictly isolated CSS in
pure server rendered applications without managing naming your own selectors
manually. If you build tiny JS apps into your server rendered apps, you'll
have to keep the styling for the JS app either in the main app, or bundle it
into the embededded JS. If you bundle it into the embedded JS, you'll end up
with two styling pipelines, which could make it more difficult to share
variables and constants between the two, if you put the CSS rules for the
embedded app in the host app, then you have to change the host app CSS for
changes in the child app, which means the two might need to be in the same
repo. This gets especially more difficult with advances in UI and interaction
design which lean more heavily on state based animation. In those cases, we
HAVE to have CSS related to animatable elements that are based on application
state within the embedded JS application, then you'll really have an issue
with having two pipelines. There are similar issues for i18n, asset bundling,
accessibility auditing, and testing.

Given all the complexity of managing multiple pipelines for simple and complex
pages, it seems to make sense to avoid that complexity by adopting a single
pipeline that ensures browser compatibility, testing, i18n, accessibility and
performance optimizations are consistently applied and centrally maintained.

Which might imply , if _any_ of your app requires complex
presentation/interaction, it might be better to just build the entire app
using the same framework.

Unfortunately, even if your app doesn't currently have complex functionality
or interactions, doesn't mean you can guarantee it won't ever. Investors are
known for pushing products to innovate, pivot, and adapt. Which implies that
avoiding SPAs is a privilege for app developers and teams who have absolute
control over their product and won't ever be forced to build more complex
products.

The Op also doesn't address how having frontend dedicated ecosystems might
affect hiring, or influence performance. I remember the days of having 20
instance variables set within a rails action and each of them being deeply
coupled into the Erb template. Having a clear client server separation at
least forces one to use an API, which can make caching easier by separating
the caching of presentational and data elements. Also, the semantics of each
server side templating language are quite different. E.g , slim vs liquid vs
haml vs ejs. Using server side templates requires frontend developers to be
much more versed in both templating languages and understanding the tiny bits
of embedded server side code. I don't imagine too many front end folks jumping
to learn scala, clojure or Haskell. However, if the client and server are
separate than that means a scala shop can focus on the API and hire a frontend
dev with no experience in the server side stack.

------
nfRfqX5n
server rendering has a cost too. SSR is not easy. gatsby is mostly solving
this in the react space.

------
fxfan
I need a quick primer on how spa does seo? Do they "server-render" the
individual instances of pages too?

~~~
empthought
Search engines execute the JavaScript...

~~~
Veen
Google does, but not reliably, especially for newer (ES6) JavaScript features.
Bing and DuckDuckGo do not render complex JavaScript apps. Neither does
Yandex, I believe.

------
patientplatypus
This feels like clickbait, but just as an aside there's nothing that says you
can't do server side rendering and react. Next.js is what I'm using on my
current project and it's server side out of the box. So you have text rendered
in source like you would with a traditional server side app with the benefits
of SPA. So at least one of his nitpicks sounds like he didn't do his homework.

~~~
maxencecornet
Of course you can use server side rendering with Next.js,but it adds some
work/complexity

With a server rendered website, you don't have to do anything

~~~
patientplatypus
I mean, not really? When you want a new page you create a react component in
the "/pages" directory. "/pages/hello/index.js" routes to "mysite.com/hello",
and "/pages/hello/there/world/index.js" routes to
"mysite.com/hello/there/world". The pages are served from a node.js site. The
newest version (8) comes with lambda rendering but you don't have to use it if
you don't want.

This is pretty simple to reason about honestly.

------
kadendogthing
Yes you actually do. At the very least you should build your web app with
technology that makes it fairly trivial to move over to an SPA.

MVC is a mistake. Read that again. MVC is a mistake. It's not a good paradigm
to write web applications in.

SPA's are not complicated. They do not take longer to build. They defacto are
often way more responsive than any server side monolith that gets built.
Because developers who buy into an archaic and broken "MVC" systems typically
do so because its "easier" for them, but it's easier because they're not
willing to think about whats being written in the first place, and that's a
recipe for a bad app no matter how you write it.

Inevitably you will end up hacking your "simple" MVC app to meet perfectly
reasonable, ubiquitous client requirements regarding user experience. Because
the paradigm isn't fit for base level requirements.

A few years ago my entire job was completely based around consulting for these
types web applications. Inevitably you get these developers that think they're
wise by going "we're just going to do it with MVC" \-- and after a few months
of use it becomes completely obvious that the dev team can't meet any kind of
modern requirements for the web application. The existing web app is slow (but
it's "fast" to the developers), buggy, and the worst part for the business is
it takes forever to write features for. Eventually these companies get so
frustrated they look to the outside.

To recap, when you build a "traditional" MVC app this typically means a few
different things:

1) It's written in a toolchain that's fairly niche to "back end" developers;
severely limiting the pool of talent that company can hire to maintain the web
application moving forward. In a fair number of cases the company will have a
front end team and a back end team. And sometimes all that back end team does
is update views so the JS developer can do their thing. So expensive for
something so small.

2) You will end up writing a mass of JS anyways, but the JS will mostly
revolve around dealing with the fact that the server side templating language
controls the original output of the web application. At worst, this means that
a lot of devs like to sprinkle bits of HTML inside the JS. So now your
templating is strewn across multiple languages and locations. The JS is
typically bad because these are "real" developers who don't like JS.

3) Because of 2, there will also be a mess of server side code purely written
to massage data into the server side templating language and an analogous set
of code just for the JS side of things.

4) Because of 2 and 3, the app because buggy and oddly slow (though again, the
devs that wrote it will only look at the original output timing and not the
actual life time performance of the application).

5) Because of all of the above, the company has now spent an enormous amount
of resources for a fairly shitty app that no one likes to use nor maintain.

My primary focus for these companies was to build a baseline SPA. And then
over the next couple of months guide them through creating new features.

And this wasn't a one off thing. I had an entire job based around fixing the
sins of the company's internal developers who are costing the company money
while not delivering, costing the company money making the application way
more complicated than it needed to be, and costing the company money by
forcing the company to hire a specific subset of developers familiar with
their MVC toolchain.

Stop circle jerking about MVC apps. They were ugly in the first place and
continuing to claim that's how we should build web apps is an erroneous
position purely fueled by stubbornness on the part of developers.

Here's my benchmark for an SPA: You can either build your entire site using
static generation, or you need to structure your web app as an SPA (or prepare
to do so in the original implementation). That is the threshold in the current
landscape. If you can't get away with doing a statically generated site then
you're not going to have fun writing your site with backend MVC framework. At
the very least the company's finances definitely won't.

~~~
a_wild_dandan
I really wish I could upvote this twice. Tacking on features to a traditional
MVC app causes orders of magnitude more technical debt and buggy, tightly-
coupled, unmaintainable or extensible spaghetti code. React et al. didn't pass
through a membrane from another reality for the sole purpose of annoying devs
with more stuff to learn -- they're elegant, powerful solutions to the rapid
growing pains and requirements of our modern web. The SPA pattern of
completely separating front-end & back-end concerns is seemingly taking over
the world for _very good reason._

~~~
kadendogthing
Yep. Developers take their choice and then externalize all the costs to the
company; even though the company has put an immense amount of trust and
financial power in them.

It's actually absurdly disgusting once you run the numbers. I've directly
compared projects before and after over a 1-2 year period and the devs
claiming that these "MVC" apps are better for users, the company, or anyone
else besides themselves are actually arrogantly delusional. They write these
apps, and either leave or then sit there in the company and blame everyone
else but themselves.

But hey, at least the problem exists. It allowed me to make a ridiculous
amount of money and invest it wisely. _shrug_

