In Defense of Single Page Applications

The single page application is a flawed yet extremely useful tool for the majority of the projects that I work on.

photograph
Aug 2022

In nearly a decade of building web applications, I’ve worked on both backend and frontend projects, using languages such a PHP, Python, and Javascript for projects ranging small independent business websites to large news applications. As Javascript single page applications have become more popular, debates over the role of client-side Javascript versus server-side applications often appear in developer communities.

Critics of SPAs will conclude that “Javascript is too bloated, slow, and complex” and opt for some kind of backend language or framework for better performance and ergonomics. I won’t rehash all the arguments in this article, but for the most part, I agree with them: client side Javascript comes with significant performance and usability drawbacks and there are strong reasons to avoid the single page application architecture.

However, I still default to single page applications often for a simple reason: the ability to avoid running any server-side code entirely. For the large majority of projects that I work on, being able to build the application out to static files that are hosted on a service like S3 is not only cheaper, but has fewer moving parts and is more reliable as an application that I might touch once every few years.

The Pre-SPA Era

Before the single page application, virtually every website required some sort of backend server. Whether it was Wordpress running on PHP, a django app, or even a simple rails website, it required some kind server always listening for requests before executing code to generate the HTML served to the user. This pattern became so common that it became a baseline: start with a backend server to host the website, and start building from there.

After building a few small projects this way, I started running into similar issues with every single project built this way: they would all eventually stop working simply due to the fact that they weren’t being actively maintained. Whether it was suddenly running out of disk space, software versions becoming too old, a sudden surprise hosting bill, or simply an application crash that didn’t automatically restart, it soon became a headache trying to fix an old project that hasn’t been touched in years, trying to remember how it was built in the first place.

We’ve become so accustomed to having a backend for every single website no matter how simple that we don’t think about how single page applications give us a chance to move the complexity to the browser, an environment that is generally much more careful about maintaining backwards compatibility than software systems used in backend infrastructure. The truth is, most websites out there don’t need a backend.

Backend Complexity vs Frontend Complexity

In my experience, engineers begin to get frustrated with single page applications when they simultaneously try to run a complicated backend as well as a single page application on the front-end. Except in larger corporate products, this is the case that I try to avoid the most.

By default, I usually begin all my projects as a single page application that gets built out to static HTML, CSS, and JS files and hosted on a simple file hosting such as S3, Google Cloud Storage, Github Pages, or some other static hosting service. This not only is the cheapest option, it also shortens development time by completely skipping most of the challenging DevOps details such as kubernetes, docker, etc. Especially if the project has no long-term maintenance or support plan, doing it this way is likely to be the most resilient option. Once deployed, simple statically hosted single page applications are much more likely to stay up and operational for years and years to come.

Building a site as a single page application without a running a backend server gives me far more room for dynamic, interactive content than the extremely limited options of the jQuery era, allowing me to go a lot further before needing to spin up a backend. In fact, I’ve built complete CMS systems as single page applications without running a backend at all. And while you may argue that running any single page application at all is worse in terms of download size, performance, or SEO, I think it’s more than appropriate of a tradeoff to have a low maintenance, cheap infrastructure. Compiled frontend frameworks like Svelte and the modern trend of static-site-generators make this even more attractive, as they optimize the performance and bundle sizes of single page applications.

But of course, there will be times where you cannot avoid running a backend. Whether it be a database requirement, a custom user authentication system, etc, many of these larger applications will require you to build an API and maybe even render some HTML. At this point, I’d argue that there may not be any strong advantages in favor of the single page application, and that a more traditional multi page application could be more suitable.

Conclusion

Ultimately, I see the single page application as a flawed yet extremely useful tool for the majority of the projects that I work on. So much of the debate around single page applications has assumed a backend service as a given, and thus most of the arguments have failed to weigh the pros and cons of single page applications in light of whether a backend service needs to exist at all.