
None of my projects want to be SPAs - thequailman
https://whatisjasongoldstein.com/writing/help-none-of-my-projects-want-to-be-spas
======
rossdavidh
This may be a mean thing to say, but basically I think SPA's are massively
overused, because developers want to demonstrate that they can do them. Why?
Because big companies like Facebook and Google use them. Why? Because they
actually are doing things that require them. 99% of the SPAs in production are
things that should have been done the old Rails/Django/Laravel way, but that
would not set you up as a developer who can do SPA's.

I have also witnessed discussions where management admits that they want
something done in an SPA so that they can show that work to their investors,
as a means of getting funding to do other projects. So basically the same
reason, except for managers to impress investors instead of developers to
impress potential employers.

Not saying all SPAs are mistakes; some uses clearly are not. But most of them
are.

~~~
kerkeslager
Yeah, some people go so far as to directly claim that something is good
because Google uses it. And when Google uses it, it probably IS good for
solving Google's problems. But most people aren't Google and don't have
Google's problems.

~~~
Freak_NL
Ugh… We've had one of those developers. Now we're stuck with a legacy GWT¹ SPA
that sucks the life out of any developer who touches it.

1: Google's abandoned webapp toolkit where you get all of the drawbacks of
writing Java code with none of the benefits.

~~~
james_s_tayler
GWT ouch. Or as I call it "get with the times!"

------
kerkeslager
Back when I was doing React, what pulled me in was that it WASN'T a framework
for SPAs. What I got from it was the ability to build UI widgets (components,
in React terms) that worked within a page, and were composable with other UI
widgets.

With that approach, you really wanted to keep every component self-contained.
That meant a lot of bookkeeping with passing events back and forth between
parent and child widgets, but while it was a lot of typing, it was all fairly
easy, and if I wanted to change how an event was handled, it usually only
involved a component and MAYBE the components immediately above or below it in
the component tree. Data passed further than that was generally wrapped in
objects and therefore didn't require code changes.

Then introduce Redux and similar frameworks, and I totally lost interest. It's
as if the entire React community forgot all the lessons they learned writing
Python and C programs in college and went back to creating global state. What
in the actual hell? I wrote a good amount of code in Redux, too--I worked on
teams that used it--so this wasn't just pre-judgment. These frameworks add a
huge amount of hidden global complexity just to avoid having to pass
parameters to components, which is the simplest thing to do.

And once you're doing that, you HAVE TO write an SPA, because any part of the
page you want to be interactive gets pulled into Redux and your JS eventually
eats the whole page. It's an infection.

When writing JavaScript now, I sometimes end up rolling my own version of the
component style. It's an effective design pattern for UI widgets. But it
hasn't been worth it to use React for a while now because the tooling and
tutorials are all too conflated with Redux and similarly awful tools. And on a
team, there's always the worry that someone on your team will infect your code
with Redux and it will grow and consume your entire site. It's a real shame.

~~~
joshuacc
> These frameworks add a huge amount of hidden global complexity just to avoid
> having to pass parameters to components, which is the simplest thing to do.

Redux offers a few benefits:

1\. Allows you to keep your global application state 100% predictable by
treating it as a pure function of an event stream (dispatched actions). This
makes it trivial to test.

2\. Allows you to "time travel" the state of your store using the Redux dev
tools by replaying/modifying the event stream. You can also set up QA folks to
export their events so that developers can reproduce any bugs in the global
state 100% reliably.

3\. Allows you to access global state without explicitly passing down props
from great-grandparent to great-grandchild.

While I'm not a fan of using Redux for everything (it does have costs), you
mentioned only the most minor benefit. If you only want #3, you would just use
React's built in context API.

~~~
kokokokoko
I have yet to see a long term project built with Redux that was maintainable.
That seems to be the common denominator in React projects that do not survive
technical debt accumulation.

The issue with Redux is that it encourages side effects in components. After a
while people are dispatching all over the place and you end up in a similar
situation as you were with keeping track of JavaScript events. All of a sudden
something stops working because someone removes a component that is
dispatching on a timed interval etc.

If you can convince and enforce that all Redux activity only happens at the
root component, you should be okay. But the reality is that once you have the
discipline to only mutate state in your root component, then setState tends to
be more than enough for anything but very large and complex interfaces.

With that said this article has the author implementing their homebrew bespoke
event system which is likely even worse. This was a very popular and much
maligned anti-pattern during Angular 1.x days. This article is suggesting the
absolute worst possible idea for maintenance.

What kills the maintainability of React and similar frameworks is tracking
down what component did what. Unfortunately, in real world examples, in my
experience, Redux increases that issue and ultimately leads to a very
difficult application to maintain long term.

~~~
qudat
> I have yet to see a long term project built with Redux that was
> maintainable.

The only maintainable projects I have worked on in terms of web apps have been
with Redux.

Redux is not great for simple projects, it is great for medium and large scale
projects.

> All of a sudden something stops working because someone removes a component
> that is dispatching on a timed interval etc.

That's the problem: react and redux are not enough for large projects, you
also need a way to manage side-effects. Incorporating `redux-saga` would fit
that purpose.

React, redux, redux-saga -> this is the recipe for large scale applications
that I have used, built, and helped maintain with success.

One of the strongest benefits of redux is being able to see every single event
in a debugger that displays current state, action payload, next state. It
really does make tracking down state changes a matter of reading a global log.

Furthermore, because redux is not dependent on react and under the hood it is
simply and event emitter, it becomes relatively easy to use the same exact
business logic for one web app and use it for some other delivery.

We did this at my last company: because our business logic was based on redux
and completely separate from the UI layer: we were able to build: a cli,
chrome extension, outlook plugin, and mobile apps using the same exact
business logic.

~~~
kerkeslager
> Redux is not great for simple projects, it is great for medium and large
> scale projects.

I'd say that the only times I've seen Redux work effectively at all is when
the project was small enough that the complexity remained manageable.

> > All of a sudden something stops working because someone removes a
> component that is dispatching on a timed interval etc.

> That's the problem: react and redux are not enough for large projects, you
> also need a way to manage side-effects. Incorporating `redux-saga` would fit
> that purpose.

I don't need a way to manage side-effects, if I don't use Redux...

I'll admit I haven't used Redux-Saga, but you'll excuse me being skeptical
that introducing more complex tools will solve my complexity problem.

> We did this at my last company: because our business logic was based on
> redux and completely separate from the UI layer: we were able to build: a
> cli, chrome extension, outlook plugin, and mobile apps using the same exact
> business logic.

Again, this is not unique to Redux. It's perfectly possible to have your
business logic completely separate from the UI layer without Redux. In fact,
my experience is that Redux tends to cause devs to mix UI logic into business
logic (and any sufficiently complex UI will have its own state and logic
separate from the business logic).

~~~
korm
> but you'll excuse me being skeptical that introducing more complex tools
> will solve my complexity problem

I'm a consultant and in my experience this misconception is by far the most
common source of problems in redux projects. Redux is a very small and simple
thing so you have to build a framework around it. Even redux-thunk isn't
enough - that's only 5 lines of code.

I wouldn't recommend react/redux for public facing sites if there's no
experienced, pure frontend team. A more batteries-included kind of framework
would be better. There's a lot of thinking to do and hardcore levels of
scaffolding to maintain before writing anything useful and maintainable with
redux. But it can absolutely lead to maintainable applications.

Also, I've never seen any homegrown "vanilla" frameworks or data stores work
well as complexity increases. It usually ends up as spaghetti, especially with
a growing team + growing business demands. Or best case a poor re-invention of
the wheel. There must be brilliant counter examples but they're probably rare,
I may never have the pleasure of working with one.

~~~
acemarke
Hi, I'm a Redux maintainer.

FWIW, we've got a new Redux Starter kit package that tries to be a bit more
"batteries included". It includes utilities that help simplify several common
use cases, including store setup, defining reducers, immutable update logic,
and even creating entire "slices" of state automatically. It also includes
`redux-thunk` built in, as well as some middleware that check for things like
mutations.

Please try it out and let us know what you think!

[https://redux-starter-kit.js.org](https://redux-starter-kit.js.org)

~~~
korm
Thanks, this is incredibly useful, I use everything in this package! It also
doesn't deviate from the spirit of Redux or abstract too much, like rematch
for example. Without something like this, I find that many people structure
their entire Redux code based on simple tutorials. They typically only read
the docs or worry about best practices and complexity _after_ they encounter
problems. This kit will have them start off on the right foot.

~~~
acemarke
Exactly!

I understand why folks have opted to create higher-level frameworks around
Redux like Rematch, and it's not "wrong" that they've done so. But, looking at
Rematch code, you can't really tell that it's actually Redux underneath.

With RSK, I've aimed for an intermediate level - decreasing the amount of
things you have to write by hand and the literal number of keystrokes you have
to type, but preserving the idea of "dispatching actions" and using reducers.

Glad to hear that you think it looks good! If you've got any additional
feedback or suggestions, please let me know.

------
lucidone
I went from MVC style all-in-one frameworks (Rails, Laravel) to application
APIs fronted by single page applications and hope the developer mindshare
tilts back to MVC frameworks. Something that'd take me an hour or two in Rails
can take a week using these new tools, even after being reasonably experienced
with them. Don't even get me started on Apollo (not my thing at all, and from
my experience most don't know how to use it well, including myself).

Most apps are fine serving html, using plain old boring forms, and having the
odd React or Vue component where necessary to do some heavy lifting for user
interactions. Moreover, it's a lot quicker as a small team to iterate.

~~~
quest88
I recently started a hobby project and initially went with a JS solution. But
when I had to start deciding on auth, maybe an orm, routing, db layer, and
templating, I said fuck it and installed Rails.

Previously I had never built a real product in Rails, only the book store
tutorial. I'm really happy with Rails so far. I don't have to worry about a
lot of shit I had to worry about in JS land and now I can focus on the app
itself.

~~~
wlll
As you're doing Rails I recommend you check out Stimulus JS
([https://stimulusjs.org/](https://stimulusjs.org/)). I've installed it in a
recently project (Rails 6, rake webpacker:install:stimulus) and it's like a
breath of fresh air. Totally gets out of your way, but lets you add behaviour
to your app as you need it.

~~~
mike1o1
Agreed. Stimulus has been great and very refreshing. I love writing my html
using erb templates, and being able to do that and easily add client side
interactivity has been great!

------
b3b0p
I feel as if many sites that used to be fine and work well have regressed in
usability and features and introduced unexpected behaviors and bugs since the
SPA paradigm seems to have taken over. This seems especially true for many
corporate, bank, shopping brand sites, etc. An example is the Capital One 360,
Chase, and AMEX sites and even Reddit.

Even JustWatch.com seems like it's fairly polished, still has it's quirks. So,
I just end up using InstantWatcher.com instead. Hacker News works well as is
too, except the search on the bottom can act up it seems once in a while.

Edit: How could I forget, Netflix. The UI, getting to the details of a
show/movie. Browsing, discovery, searching, it all feels broken and
unintuitive. The DVD site last I checked was still decent. Netflix seems like
the poster child for usability and regression issues moving to a SPA.

~~~
endymi0n
Fellow JustWatcher here, care to elaborate which quirks exactly you mean? Back
when SPAs were still pretty new, we took the bet to make one with a pretty
large surface area and despite a lot of issues (SEO especially) so far we're
pretty happy with that decision.

~~~
b3b0p
Infinite scroll, showing the details, clicking back sometimes doesn't bring me
back to where I left off. Same when scrolling horizontally for example on the
New releases I'll have to start scrolling right again after click on the
details.

Honestly, your website is probably the best implementation of a SPA website
with multiple pages I have ever seen I can recollect. It still has quirks
though. I just don't see why you would want to make a website like this a SPA.

Does that help a little? I wrote this quick, off the top of my head. I can try
and provide more details maybe in an email or some other communication means
too.

~~~
endymi0n
Hey, that's super helpful, thanks!

Why SPA? Well, a good question indeed. Actually, we're cross-compiling the
same code for the webapp onto iOS and Android targets with build flags, where
we're leveraging more platform features (i.e. geolocate cinemas).

Also, it lets us make the experience itself much more snappy once you're on
the page, as there's just content to be re-loaded. You can switch tabs, we can
remember scroll positions, stuff like this.

Stay tuned though for our completely rewritten release based on very recent
technology, I'm hopeful this will change your perception about SPAs on large
sites coming in March!

~~~
dagoat
> Stay tuned though for our completely rewritten release based on very recent
> technology

Nothing can possibli go wrong

------
sharps_xp
I don't use Elixir/Phoenix, but Phoenix's LiveViews brings all the butter to
the monolith bread. State remains on the server, only visual state is sent
over websockets, and the HTML is transformed with morphDOM.

[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)

I hope to see this idea brought to Rails, but the its websocket story doesn't
seem there yet.

~~~
jboneal
I agree - it seems like a LiveView equivalent for Rails should be doable in
principle. Check out these two projects, they're sorta heading in that
direction: Fie: [https://fie.eranpeer.co/](https://fie.eranpeer.co/) AnyCable:
[https://anycable.io/](https://anycable.io/)

~~~
rkangel
If you watch Chris Mccord's videos (the creator of Phoenix and LiveView), it
was an attempt to build a similar system for Rails that drove him to create
Phoenix. The Ruby/Rails concurrency model mean that he was patching over so
many cracks to try and get it to work, and it never quite did.

------
asattarmd
For CRUD apps, using Rails etc. with Turbolinks[1] is the best way to go IMO.
It gives you the SPA feel without the headache. In all SPAs, we load JSON,
with Turbolinks, we load HTML of that page alone (without the CSS, JS etc).

[1]
[https://github.com/turbolinks/turbolinks](https://github.com/turbolinks/turbolinks)

~~~
disiplus
this is not just one simple drop in replacement, well it is if you load only
html, but pages are usually html + js, even for "old" mvc. so because there is
no page relaod you have to rethink all your events, objects and so on.

so if i have to rewrite my js with this just so i could fake SPA then benefits
are so much smaller

~~~
theonething
Take a look at Stimulus JS in conjunction with TurboLinks

[https://stimulusjs.org/handbook/origin](https://stimulusjs.org/handbook/origin)

------
pgm8705
We turned to React as the UI solution in our Rails app almost 2 years ago. It
was the hot thing and I fell in love with the concept of components. While it
did work well, I regret the decision. It convoluted our codebase and it seemed
like simple tasks took way longer than I estimated. We're now back to doing
things the "Rails way" with erb templates, turboklinks, and Stimulus to give
us that JS functionality we were looking for when we chose to start using
React. It's been a breath of fresh air.

~~~
wlll
I've started a new project with Rails 6 and Stimulus just recently. Stimiulus
really does feel like a breath of fresh air. Just enough to let me do what I
need to do without feeling like a burden.

------
wickoff
Personally I was dumbfounded by complexity of doing async things in redux.
Libraries like redux-thunk, redux-sage, redux-observable should not exist. The
amount of boilerplate required was incredible and meaningful typescript
support was very difficult to achieve.

Then I tried mobx, I was able to write a small app after 15 minutes of reading
the docs and now I love react.

~~~
supermw
With context api and hooks you don't need redux or mobx.

Not that either one was really all that necessary in the first place anyway.

~~~
_coveredInBees
I've still found the concept of computed properties in mobx to be extremely
useful (and I say this as someone who relies on regular React + SetState 90%
of the times). MobX encourages you to think about representing your state in
the minimal possible representation and to heavily use computed properties
that depend on this smallest, irreducible state representation for everything
else. Switching to this mindset makes developing more complex components
(especially UI/forms) a breeze. I also find MobX to be great for async things
and much easier to handle than via setState. Using setState alone in these
types of complex components ends up being really tedious and prone to errors
(largely driven by the async nature of setState updates).

------
dkarl
As a developer I agree that developers should prefer to get features out
quickly and optimize the experience later. However, as a user, I think this
section is _really_ important:

 _I’d like to try and make it work offline. To do that, and do it well, you
need a way to show the data in different ways even when you can’t call a
server._

I often have "What the hell is this thing doing" moments as a web app hangs
trying to complete a round trip over my mobile connection when I _know_ it has
already fetched the information on that page or I know it could be doing
something useful despite not being able to connect.

The author is not proclaiming that SPAs are a bad idea. He's just pointing out
how much extra work they are, and that some types of apps are worse as SPAs,
or simply much harder with nothing to show for it. He even points out that not
all the badness of SPAs is intrinsic to being an SPA:

 _Why does a website that orders food from restaurants need a Megabyte of
javascript?

I tried to figure that out by inspecting the API calls. It turned out they
were tracking every mouse event._

In short: 1) horses for courses, and 2) SPA apps are a lot more work and you
have to decide when the benefits are meaningful. Less contentious but maybe
less fun than trying to argue which is the one to rule them all.

------
hathawsh
There is a place for SPAs. I just built a single page React app (using the
create-react-app package) that mostly replaced a complex pile of spreadsheets.
It came out fantastic, I think. The entire compressed Javascript is about 150
kilobytes, the scripts typically load in less than 500 milliseconds, and my
co-workers are very happy. The code is easy to change and the interface
between the client and server is clean. (Note: I disabled the built-in PWA
features; they made versioning difficult due to excessive caching.)

On the other hand, I also maintain a public facing service that is mostly
server-rendered with lots of JQuery snippets. I don't see a need to convert it
to a SPA. It works well as-is.

I conclude from my experience that public facing services probably shouldn't
be SPAs, while things that outgrow spreadsheets might be good candidates for
SPAs. I wonder what other areas have been explored.

------
honkycat
> It beats being a Magpie Developer. I have more time time to pet my dog, read
> a lot of books, make fresh pasta by hand, and circle a more slowly evolving
> collection of powerful technologies that let’s me get stuff done without
> spending half my free time chasing shiny new things.

Saying stuff like this is sure to please the hacker-news hipsters. But... is
this honestly anyone's experiencing using new web technologies?

I tend to be on the bleeding edge of tech, and I very rarely regret learning a
new technology. And I do not feel like I am wasting all of my time flitting
from technology to technology.

I just think this is a smarmy attitude disguised as wisdom. People should like
what they like. And as someone who has had to climb that hill before: Waiting
around not expecting the world to change around you is a losing bet every
time.

The fool doth think he is wise, but the wise man knows himself to be a fool.

~~~
purple_ducks
> I just think this is a smarmy attitude disguised as wisdom

> The fool doth think he is wise, but the wise man knows himself to be a fool.

I fear that this wasn't meant to be ironic.

------
mamcx
Another angle is that "SPAs" are build on top of a fragile and anti-
engineering tech stack: JS, CSS, HTML.

In the past a 'SPAs' was build on top of more solid foundation like smalltalk
or later Delphi. Most issues is that the browser stack, put it in real terms,
is not the "right tool for the job" and will never will, without serious re-
engineering.

~~~
alecigne
Could you provide some links/keywords about these alternative solutions? This
sounds very interesting but I don't know were to start.

~~~
mamcx
Is unclear to me if you talk about Delphi and smalltalk?

~~~
alecigne
I am interested in designs/technologies that could be viewed as alternatives
to the usual tech stack for SPAs, even if these technologies are outdated but
exhibit interesting properties compared to what we are used to today. That
would include Smalltalk and Delphi yes. Sorry if I misunderstood your initial
comment.

~~~
mamcx
Well, Delphi is well alive and current:

[https://www.embarcadero.com/products/delphi](https://www.embarcadero.com/products/delphi)

(it have a free edition) and alzo exist Lazarus, a open source clone:

[https://www.lazarus-ide.org](https://www.lazarus-ide.org)

Is probably the most fleshed idea under more "traditional" paradigms (OOP,
RAD, etc)

Smalltalk and others are less popular(?) and only know them passing, so can't
give too much of that.

\---

Another interesting stuff can be rebel/red:

[https://www.red-lang.org](https://www.red-lang.org)

much low-level but nice way to do UIs in a apparent declarative way..

~~~
alecigne
Thank you!

------
drcongo
I come across so many sites that have been needlessly built as SPAs, and so
many of those are broken in ways that are really hard to understand even as a
technically savvy user. For regular people, it's a truly appalling experience
- the sites my wife has to use for work are all like this, all broken and all
slow - she blames her laptop. SPAs need to die.

~~~
ep103
Isn't this just the same as saying bad code acts badly though?

People can, and have written bad websites using every technology. I can think
of plenty of badly written, hard to use MVC websites from my past.

It should come as no surprise, that bad developers have found ways to make
badly written SPAs as well today.

I don't think we should judge a technology by its worst implementations.

~~~
drcongo
I don't think it is, no. A plain old HTML and CSS website gives me some clues
about what's happening when I click things: if I click and nothing happens I
can see a progress bar in my browser that shows me that I'm waiting on network
- if I do the same in a SPA I get no feedback at all. You could say that all
SPA developers should be writing this feedback, but even that isn't reliable -
quite often the broken SPAs _do_ show their own feedback with a spinner or
similar, but still there's no way of knowing if it's actually doing something
or if it's broken. I can open the web inspector and look for XHR requests, but
if it's trying to do something with no XHR then again, no way of knowing. They
break user expectations, and when they don't function correctly this can be
hugely frustrating.

~~~
drcongo
Oh, and I forgot to mention that they often break standards that a lot of
people rely on, in particular the native zoom in browsers.

------
DanielBMarkham
A SPA should be the emergent _result_ of creating an application that does
something people want, not a goal in itself. Your builder doesn't show up at
your house to put on a new deck and go "Gee, I really hope I get to use this
20-pound sledgehammer on this job. I hear it makes great projects"

If you start with how it's going to end -- it's not going to end well.

Having said that, what you're most likely seeing is that a ton of tools and
frameworks are built for no other reason than 1) Coders need something to
create to show other coders how awesome they are, and 2) People want something
that works like everything they know -- it just does these one or two new
things

This is a great way to make a mess over a decade or two, and you're right for
waiting it out.

Make a SPA if you need a SPA. Key question: How do I know whether I need a SPA
or not? (Or whether React makes sense, etc)

------
koblas
There are lots of applications which don't really benefit from being an SPA
(blogs, books, etc.). As soon as you start thinking about meaningful
interactions you quickly start having to pile enough JavaScript into the HTML
that you quickly run into a mess - defining ways to marshal data back and
forth with an ad-hoc structure.

While SPA tooling like React are incomplete since they don't provide all of
the client/server data communications that comes for free with a server side
application. That is starting to become more "standard" as GraphQL and Apollo
start filling the gap of boilerplate. Though of course wrapping your head
around GraphQL takes a bit of work for anybody who's spent their life with
REST.

Most applications should be SPAs to create the interactions that users expect.

~~~
taeric
This builds an implication that spa tooling is the way to avoid a mess.

Which is ironic to me. As soon as the teams I've seen start piling a ton of
extra stuff into the UI, be it types to make things more safe or logic to make
things feel faster, you get a mess.

Note I'm not claiming either of those are the problem. More code is just
almost always more mess. Keep it small. If possible, keep it separate.

~~~
koblas
There are two forms of mess in my experience, none of them have to do with
SPA.

1) You have the problems that different developers have different styles. So
when you jump from one area to another in the code base you're hit with WFT
this is functional/procedural/inheritiance/composition, etc. style and your
first thought is "barf" they did it wrong...

2) People either have huge functions that are spaghetti or tiny little
functions to avoid complexity that are one line if statements.

Both of these are usually rooted in lack of a shared code culture, these are
not SPA issues but team issues.

~~~
cle
These could also partially be language and tooling issues.

There are some languages that are so “powerful”, “flexible”, and unopinionated
that every developer has dramatically different coding styles (JavaScript,
Scala, etc.). On the other end of the spectrum are tightly prescriptive,
constrained languages where everyone’s code looks the same (Go comes to mind).

No doubt team culture plays a part as well, but in team settings it is
important to pick tools that are designed for team settings. These tend to
prioritize regularity, lack of flexibility, syntactic simplicity, static
analysis, etc.

------
aogaili
SPA and react are not the same thing.

React is about components and you can use React in something like NextJS which
is not a single page app but a server rendered pages.

Also, SPA itself is getting outdated concept, now most apps are hybrid of
initial bundle followed by a dynamically imported modules. Finally, MVC is a
pattern for web pages, the complexity in the client side because what is the
being shipped to the browsers are a client side apps with their own router,
render functions, state management and APIs.

------
morpheuskafka
We recently went in the opposite direction for a student project I'm working.
We have a full SPA Angular frontend, and we use CouchDB as our datastore.
There is a Node "backend," but it only serves things like Slack integration,
the browser has a local PouchDB instance that directly syncs with the server's
CouchDB. This way, we can deploy hotspots with nothing more than a Couch
install and a static server for the SPA.

The modern, offline web is great. If we had to do this in a native app we
would never have gotten the project off the ground, because we initially need
to use BYOD phones which were evenly split from iOS/Android. We'd have had to
use three languages, but a Mac, get developer licenses, and learn Swift and
Java just to get an offline frontend, and sharing business logic code would be
impossible.

~~~
raihansaputra
This sounds interesting. I'm light on details on how CouchDB and its sync
works, but how do you deal with data validation/data conflict? Or maybe
malicious actors tampering your data? Or is it a closed app that already have
those dealt with in the spec? It would be awesome if you can share more about
the project.

~~~
morpheuskafka
I'll email you a copy of the whitepaper once it is finished. The famous quote
is, "CouchDB is bad at everything, _except syncing_." It has a built in
revision system that will create two conflicting revisions on both ends, and
allow your code to implement the business logic to determine the one true
revision. This could be a prompt, or a rule based on the data (ex newer
timestamp winds), or even an average of various data fields to create a whole
new field.

[http://guide.couchdb.org/draft/conflicts.html](http://guide.couchdb.org/draft/conflicts.html)

~~~
raihansaputra
Wow, the revision system is really interesting. Makes sense why you used it
that way. Thanks for the link! Am excited to wait for the whitepaper.

------
nisten
To add to this, bandwidth and app size is not important to the user(they'll
watch netflix later). The only thing they notice, is response time.

React with well defined static content routing and server-side rendering is
amazing at this because the first packets that the server sends the user is
html/css jumble.

You can get your app to show text and formatting in as little as
20ms(depending on where you deploy it), then show images, then you don't care
if the rest of App and all the js and 3rd party crap take another 2.5s and 3mb
to load, The user will do a bit of reading and picture watching, before using
a button or input field. However if they're on the go and loose connection,
now they have a fully functional back button in their browser to read the next
or previous cached html/css content.

~~~
arcticwombat
How is this amazing?

We've been "server side rendering" since the inception of the internet.

If you build your pages with CSS at the top and JS at the bottom you're
already achieving most of that effect right there, no extra tools needed.

The browser will load the css and content first, and then process the JS
requests (Which are easily cachable by the server AND the browser).

~~~
arethuza
I suspect nisten is referring to server side rendering using React.

~~~
arcticwombat
I think so too, but my statement still stands.

There's nothing new or especially special about "server side rendering", and
nothing about React rendering either.

Rendering on the server lets you do whatever you want.

Want to put the user in a specific state? Sure, go for it.

Want to use a starter or null-state? Sure, go for it.

------
realusername
Also one of the things not listed here is the added complexity of an SPA, the
routing bugs, the old browsers bugs, the added complexity of splitting js
files so the initial load does not become too big, the data storage...

I'm currently maintaining alone two large websites and only one of them is an
SPA, that's definitely the harder one to maintain by far.

------
laszlokorte
What I did for a mobile web app I built last year after the react prototype
was to slow on old devices:

\- Render all pages/routes/states into a _single_ html file (size ~2mb) but
each page/component/state hidden via style=display:none;.

\- then write some hand crafted js (few hundred lines) to add event listeners
to forms and show/hide the components depending on url change

\- cache everything via appcache/serviceworker

\- result: not so fast initial load (1-2 seconds) but really fast interaction
afterwards even on old lowend devices, almost no time spent running
js/react/vdom. even some scrolbugs I had to work round before when using react
(eg replacing dom nodes but keeping scroll position of a parent container)
resolved on their own.

~~~
arcticwombat
2mb html file, + whatever else for initial load?

That's only 1-2 seconds on a fast connection.

If you have zero of that content cached locally and are on a mobile or just
not-fast connection it'll be way more than 1-2 seconds.

Your "solution" is one of the ones responsible for locking up mobile browsers
all over the place, because the browser still has to deal with the entire DOM,
and it's often done way inefficiently.

~~~
laszlokorte
> 2mb html file, + whatever else for initial load?

nothing else because all images are already inlined as svg as well as all
styles and the mentioned js code

> Your "solution" is one of the ones responsible for locking up mobile
> browsers all over the place, because the browser still has to deal with the
> entire DOM, and it's often done way inefficiently.

I only came up with doing it this way after previously having build the same
app using react and old devices (eg android pre chrome) could not handle all
the vdom diffing and add/removeNode.

Our users preferred a slightly longer initial load (even 10 seconds) and
lightning fast interactions afterwards over fast initial load and sluggish UI
for all the time using the app.

When doing client sit rendering you would still have to transfer and parse
little chunks of json all the time.

As it turns out browsers are really good at handling even huges DOMs as long
as you do not manipulate it to much.

Granted this way only works if you have a limited set of states/pages (eg a
few thousand).

------
geebee
This article and discussion does show, in a pretty stark way, the options and
demands of very different career paths for a software developer.

One option is to become a programmer for hire. You keep your skills up, and
those skills are as much about getting a job as doing the job. You re-study
data structures and algorithms. You can permute sets, find matching subtrees
in binary search trees, and answer questions about how addresses in web
browsers are resolve to web sites. You learn java, then GWT, then EJB, then
spring, then struts, then you add a 2 to the end of struts, then Rails or
Django, then you give it all up and do it again in Javascript, React, Vue,
Ember. You also play the agile "estimate roulette" as you write down tasks and
expected completion times in JIRA, and are asked about deadlines every morning
in an almost inevitable corruption of the original methodology[1].

You would never do this for your own project. If you had an exciting new idea,
the last thing you would do is go off and learn to find all subsets of a
larger set that, when concatenated, form a member or the larger set, at the
whiteboard, in 45 minutes. It's also fairly unlikely that you'd set out to
write an SPA for many business ideas. But you'd definitely be doing this if
you were applying for the next job, which you sort of always are doing, if
you're a programmer for money. Even if you aren't looking to change jobs, you
still do this, by and large.

Or, you can become the kind of programmer who creates a product, chooses the
right tool for the task, and makes it work. The reason that this is difficult
is that these jobs are rare. To really have this option, you often need to
make the leap into doing your own thing.

That sort of entrepreneurial skill and mind-set seems to be orthogonal to most
programmers. I couldn't tell you if it's innate or learned, but I do know that
it's a big leap, involves risk, requires a period of economic uncertainty that
is tough for people with dependents (or people just trying to pay rent and
make it through the next few months in an expensive city). But it may be the
best way out of the programmer-for-money quagmire.

The thing is, if you have that kind of entrepreneurial spirit... well I'm not
sure you really need to be a programmer at all, there are all kinds of great
opportunities out there.

[1] Yes, this is a bad case. Not a worst case, but a pretty bad one. I'd say
all programmers for money have gone through some version of this more than
once, but I'm putting them all together into something that is more grim than
most have to put up with.

------
arcticwombat
I have to say my experience tracks this too.

A lot of the "modern" toolsets just aren't worth the extra fluff they add.

Writing SPA's in React, Angular, etc. tend to result in a very heavy first
page load, then api calls with poor UX for all actions.

~~~
ivanhoe
Don't regular web sites do exactly the same? They also usually pack all JS and
CSS into two big files in order to reduce the number of requests on the
initial load, right? And beside in SPAs you can split the code and lazy load
it to reduce the load.

~~~
collyw
In the last Angular app that I inherited every menu on the page needed a
separate call to populate it. It probably wasn't the best written app. I think
if it had been plain Django with some jQuery for front end validation the size
code could have easily been cut by a half or more.

------
supermw
Why do people insist on comparing the initial frontload of a SPA to the page
load of every page in their SSR web app?

Once a SPA is loaded you can send tiny crumbs of data faster than any
significant SSR.

~~~
shusson
> Why do people insist on comparing the initial frontload of a SPA to the page
> load of every page in their SSR web app?

Because a user doesn't care if it's the initial frontload or not.

~~~
koboll
Prerender the initial page and they won't notice any difference.

~~~
shusson
yeah there are a few ways to reduce the initial load time, but my point is
it's valid to compare the initial load to every page in an SSR (for most use
cases).

------
pastullo
Completely agree on this one. I feel that a big chunk of "let's make it an
SPA" is coming from the development team wanting to use and learn first hand
these new exotic tech stacks. In the past two companies i have been, there was
no strict guidance on the technology stack for each microservice or web app,
so it ended up being a jungle of microservices written in GO, Elixir serving
apps in React.js, VUE.js etc.

Did the company or the end user benefit from this? Hell no. Only one
benefiting were the developers who ten left and asked for a 10k more salary on
their next job for sporting that fancy new javascript framework. NICE!

------
amoitnga
The latest project I'm currently working on I got to choose how to build. It
is an internal CMS. I went with Rails API, React, Material-UI. So far, I like
it.

I like separation. I know that one side ( ruby, rails, gems, pg, sql etc ) is
all about data -> one mindset.

Another side is about views ( js, css, html, multiple select, date pickers,
autocompletes etc ) -> different world.

I build my assets in one place, I work with my data in other. I wear one hat
as a backend guy, and when I need refocus completely on front end work.

I wouldn't argue it's easier, but I think it's easier for me. I like it
better.

Plus, the API will be consumed eventually by user-facing site and apps.

~~~
cjauvin
I'm almost exactly the same situation these days: small project, got to choose
my tech stack, so I went with a "conservative" part I have good experience
with (backend in Flask) and a more experimental part (for me) that I'm taking
the occasion to explore and learn: React + TypeScript + Material UI.

For that latter part, although I must recognize that the tooling has evolved
into a quite complex pipeline (which is a cognitive investment, almost a
gamble, in itself), I also clearly see the benefits of a set of ideas that
have rapidly evolved in the turbocharged settings of the web development
ecosystem:

React: the distillation of many programming paradigms (functional, composition
over inheritance, etc) for building UI components.

TypeScript: the augmentation of JS with mature and powerful programming
constructs.

Material: a visual language for UIs with a strong focus on coherence and being
truly cross-platform.

All in all, although I'm well aware of the critiques that can be addressed to
the modern webdev environment (the so-called "JS fatigue"), I feel like all
these new tools empower me, and I really enjoy learning about them.

------
fouc
There is a slight advantage of separation in frontend & backend - writing
tests for an API-only backend is so easy. On the other hand, the frontend SPA
still needs tests, and I have no idea how to make that trivial yet.

P.S. If you folks want a really small react-like SPA, I recommend either
[https://mithril.js.org](https://mithril.js.org) or
[https://riot.js.org](https://riot.js.org)

And you can avoid state management complexity by using a pattern like
[http://meiosis.js.org](http://meiosis.js.org)

~~~
pas
Testing is easy in Angular. (Thanks to the everything is an object approach.)

[https://angular.io/guide/testing#component-class-
testing](https://angular.io/guide/testing#component-class-testing)

[https://angular.io/guide/testing#service-
tests](https://angular.io/guide/testing#service-tests)

------
nautilus12
I see the same thing happening on the front end that I saw happen on the back
end with big data. Just because it fits better into Google and Facebook's
Enterprise patterns doesn't mean it will work for everyone. Very few companies
need Hadoop, probably as few as need react

------
pier25
After working exclusively on SPAs for a number of years (React, Vue, Inferno)
I'm getting out of that unless there is a strong argument in favor such as a
hybrid mobile app (and that will go away once we move into Flutter).

I don't want to go back to Rails/PHP/Python though. I like having a
REST/GraphQL API. With Hasura I don't have to worry about backend anymore for
80% of the cases.

What I'm doing right now for the front end is using Jekyll with Vue. It's
really liberating not having to worry about a router or managing application
state anymore. For certain in-house projects I don't even have to use Babel or
Webpack anymore and still get to use Async/Await.

------
donatj
In my personal experience very few projects actually want or need to be SPAs,
developers are just dying to work on SPAs so hiring managers oblige to hire
talent.

------
CM30
I'm in pretty much the exact same boat as the writer here. Nothing I want to
build seems like it'd need to be a SPA, nor work better as one.

Maybe that'll change if I decide to build games with HTML/JavaScript/CSS or
want to make some sort of online version of a desktop program, but nothing in
my current ideas list is app like enough to really warrant the SPA setup.

------
platz
My favorite pattern right now is server rendered html shell including static
parts of the page, and then invoking a view-only js framework with all the
server data required sent in the initial page load for the dynamic client
bits, which runs immediately on page load.

so, basically a "functional" front-end view-framework for client-side
behavior, but with no routing.

------
c-smile
Yeah.

1\. Tons of existing jQuery components.

2\. Ten of custom, loosely coupled ones.

3\. Built-in PubSub for their communication:

    
    
       $(document).on("custom-event", function() {...})
    

4\. Routing (if needed) in 60 lines of code:
[https://github.com/c-smile/spapp](https://github.com/c-smile/spapp)

And you can do any SPA out there. Or not SPA.

------
duxup
Every time I read an article about SPAs... I feel like someone has a new view
on what an SPA even IS, what it is good for, and so on. Many articles sound
like they're talking about entirely different things.

I get the definition, but I don't see a lot of problems and etc .... necessary
a part of SPAs.

------
shusson
If anyone would like an example of the silliness that exists in SPA bundling
see [https://github.com/angular/angular-
cli/issues/6137](https://github.com/angular/angular-cli/issues/6137)

~~~
everdev
> For those of you who use moment-timezone there is a trick to reduce the size
> (if you can get away with 2012-2022 dates)

Lol, a 3 year solution. I immediately feel sorry for the future devs jumping
into a codebase like that on New Year's 2023 trying to figure out what broke
overnight.

------
rkangel
I'm really interested in Phoenix LiveView
([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)) when it gets released. It means
you have the normal simplicity of server rendered code, but then an option for
interactivity (e.g. A rich form) without having to have part of your logic in
a completely different place/technology.

When you start thinking about field validations and having to duplicate them
client and server side, it makes even more sense.

------
rkangel
I had always assumed that the move to Spa's occurred in large part due to
mobile apps. A mobile app effectively has to be a client rendering of data
from an API, and if you have to do that for mobile, it makes sense to do it
for the Web.

------
ashelmire
I don't think many projects _need_ to be SPAs. But if you're using node for
your backend anyway, I think it's basically equal work to make something an
SPA vs a non-SPA. The SPA effectively handles the routing for you, and I think
react-router is pretty easy to use.

The speed benefits are noticeable on sites where you're doing a lot of
internal navigation. But you can just as easily make a slow SPA (see JIRA).

So I guess in the end, do whatever takes less development time. Which usually
isn't an SPA, just because there isn't really a good framework that reduces
effort required. Rails and turbolinks are pretty legit.

------
vlasky
The Meteor framework has been actively developed ever since it was released
and continues to have a broad, enthusiastic user base.

Mr Goldstein would have known this if he had visited the Meteor blog
([https://blog.meteor.com/](https://blog.meteor.com/)) and Meteor forums
([https://forums.meteor.com/](https://forums.meteor.com/)).

------
theamazingtoby
If the project I'm working on is a personal project, then hosting price
becomes a big factor, and being able to host an SPA on S3 for pennies a month,
with a free Firebase backend, becomes a MAJOR advantage over hosting a Rails
app on Heroku. If I'm working on OPH (other people's hardware), then I'll go
with whatever makes more sense. Or whatever the rest of the team wants to use.

------
woolvalley
As a mobile app developer, looking at the architecture of PWAs is a bit
obvious to me. It's to turn webpages into stand alone mobile / desktop apps,
with all of the power & setup that implies. But without the size overhead of
an actual app, because every phone has a runtime library called the browser.

It's a great tool if that is your goal. Otherwise why spend the extra effort?

------
tracker1
To contrast, I've been looking for a reason to use Go for a couple years now
on an actual project, I haven't really found one yet. That doesn't mean that
go doesn't serve a purpose and is probably more representative of me being
adverse to taking on the risk of learning/using it with a project than it does
as to the ability of Go to serve a specific role.

------
nisten
Wtf is an SPA?

~~~
octosphere
If you have Javascript disabled, all you should see is a blank white screen,
and if you're lucky a small note saying 'This site requires Javascript to work
correctly'. That's what a SPA is

~~~
WrtCdEvrydy
React Server Side rendering takes care of this... but most people don't know
how to do it.

Without JS, Server Side JS defaults to good old school MVC.

~~~
jmkni
When you are adding a new framework to render your single page app on a
server, that's the point to stop and re-evaulate your technical decisions
IMHO.

------
rchaud
As someone who's self-taught in Wordpress development, I tried to branch into
React but I had similar questions that stopped my progress. I'd always be
thinking "why are they setting it up this way"?

Are there any barebones tutorials out there for CRUD apps that don't require
Node.js, Python etc, and can be learned using PHP, MySQL and HTML?

------
Illniyar
Do we really need to defend SPA every other week? The market, users, product,
ui/ux designers and the vast majority of developers decided that SPA is a
better user experience.

Page loads greatly degrade the user experience, especially when you have long
lag (which for many of us the reoundabout time is longer then the download
time of 100k).

Even if you make your site extremely lean, it's still a worse experience, and
let not forget that for the majority of sites lean is far beyond them (not the
least because you must integrate third party code such as social and analytics
or fade into obscurity against those who do)

So some developers feel that the old way of doing things is just fine. There
are always some of those. Probably the same ones who surf the web with js
disabled. This is not even remotely what the average person expects and anyone
who thinks they can build a website like that and compete are delusional (and
hacker news is perhaps the exception that proves the rule. Even google is not
html only anymore)

~~~
whytaka
The phrase, "the exception that proves the rule" is not used properly here.

A proper example is something like: "Parking allowed on Fridays", which is an
exceptional case to a rule that is implied: "No parking any other days."

Just a heads up, feel free to ignore.

~~~
Illniyar
Properly is a very loose term. It is common in speech and literature to use it
to mean "an exception so rare that by virtue of it's rarity it strengthens the
general rule".

If we are going by wikipedia definitions, then: "A rural village is "always"
quiet. A local farmer rents his fields to a rock festival, which disturbs the
quiet. In this example, saying "the exception proves the rule" is literally
incorrect, but it is used to draw attention to the rarity of the exception,
and to establish the status of the village prior to the exceptional event. "

------
tripzilch
... I read this entire article and still don't know what a SPA is :)

Seriously, I've tried looking it up...
[https://acronyms.thefreedictionary.com/SPA](https://acronyms.thefreedictionary.com/SPA)

~~~
zakm
[https://en.wikipedia.org/wiki/Single-
page_application](https://en.wikipedia.org/wiki/Single-page_application)

------
spricket
I've found the most annoying aspect of using a SPA is having to consume your
own API's. Using Swagger or gRPC on both ends helps immensely.

These, combined with Angular CLI or Create React App, allow me to be just as
productive as the pre-spa days

~~~
5trokerac3
I think the beauty of SPAs is consuming your own APIs, because it makes you
realize that _your website is just another client application_.

Nobody worth their salt would recommend coupling display components and
database manipulation together in an iOS or Android app. A webpage is the same
thing, because it's not running on your server, it's running in the browser
_on the user 's computer_.

With this blog post, like most "I don't like X technology" blog posts, I find
myself asking, "does the author not like this technology, or has he not taken
the time to become a real SME in it?"

~~~
spricket
I guess another real advantage of SPA is that you get an API for free. Last
place I worked, the product people had a genius idea to "build a public API".
They decided to give us half a year to do it.

We had a SPA using OAuth.

I spent a few weeks adding docs, ran Swagger codegen, then declared it
finished. Every call our front-ends used was now part of an API. Then we just
trimmed out the parts we didn't want to officially support.

------
nickthemagicman
I don't like them because they're against the nature of the web.

They override routing, they override SEO, they make it hard to use build in
browser tools, etc, etc.

------
punnerud
Nr4. "people argued that it would be faster to only pass the data you need as
JSON than to render whole pages" \- This also kills your SE(O)-ranking

------
aagha
I gave up on the article as soon as I did a ctrl-f to find the definition of
an SPA and didn't see it.

------
rawoke083600
Is SPA with unique-urls (think angular-routing) still a SPA ? Most of my
websites+apps are done using Angular/PWA.

~~~
pas
Why wouldn't it be?

------
crimsonalucard
Nothing wrong with the concept of SPAs. It's just these modern front end
frameworks leave a lot to be desired. None of them simplify complexity and
modularity is an illusion. Most of your components can't be reused in another
project.

Additionally these frameworks are harder to debug thanks to leaky
abstractions.

The only front end abstraction I've seen do it correctly is Elm. I'm not
saying Elms' pattern or language is good or correct; (I have no comment about
that) I'm saying that the abstraction isn't leaky. No javascript errors in
Elm, just elm level errors. React Vue and all these modern frameworks need to
be handled the same way.

I know technically that react is just a framework and not an entire language
over javascript, but the ways and technology React is typically bundled with
makes it a leaky abstraction and the common use case should be handled.

