I am a “full-stack” developer, which means a lot of things. Specifically for the purposes of this post, if means that I work with every part of a web application, and those are traditionally divided into three layers. First is the front-end or client-side layer: that’s what you see when you visit the site in your browser. That client connects to the back-end or server-side layer to get and store its data and generally accomplish things. Underneath all that, the database keeps track of everything; it tends to be a special snowflake, so we’ll ignore it for the moment.
JSON the killer
It’s simple and even ingenious. The server just offers an API, so theoretically anybody could use it, and the client fetches data from that API, creating HTML on the fly based on a response in the form of JSON. (You could also use XML like in the old days, but…no. Let’s not go there.) Perfect separation of concerns, because why should the server care how the data is presented?
And we got some really great tools out of that, along with a whole new way of looking at the web as an application platform. Angular was the first to hit it big, while React and Vue are the top two now. All these share a focus on “reactive” programming, a style of event-driven programming where data changes automatically when its dependencies do. Very simple, fairly elegant, and…
Build me up, buttercup
…And a total mess to build. Angular, React, and Vue all share that problem, and it’s not getting any better. Building a web application using any of these frameworks is black magic, pure and simple. I’ve been doing this for 4 years now, and I still don’t think I’ve even scratched the surface of Webpack configuration. Seriously, I just use Laravel Mix, or copy a Webpack config file from somewhere else, because I’ve got better things to do with my time. Like, you know, writing the code!
There’s a reason why
node_modules is a meme. There’s no valid reason why it should be five hundred megabytes for a “starter” React app. Modularization and the borderline insane dependency lists of a web framework have turned the web dev environment into a mess. Not only that, but it’s nearly impossible to get an app built without running multiple processes simultaneously: Webpack, dev server, maybe a CSS postprocessor, and who knows what else. I understand that you do need a lot of tools to cover various use cases, but can’t we think about optimizing the developer’s experience a little, too?
Zero is better than nothing
When I wrote my first web page in 1996, it was easy. You didn’t need any specialized software, just a text editor, a browser, and maybe an FTP client. Sure, the internet has moved on since then, and pages are a lot more complex. They can do so much more that sites I use every day in 2021 would have been unfathomable to anyone 25 years ago, let alone a nerdy 13-year-old.
But does that increased complexity require a proportional increase in development complexity, or can we get back to making quality pages without all the cruft? In other words, can we make modern web applications without a client-side build process?
Until a few days ago, I didn’t think so. Because that was the received wisdom: modern apps are SPAs, and SPAs need a client framework. And that client framework just has to have a build step. Even Preact, the stripped-down cousin to React that boasts of being easy to install, requires a build step for its templates. Tailwind CSS needs one to cut its 1.7 MB of styling into something both manageable and incredibly sleek.
But…what if we didn’t use frameworks? What if we didn’t use JSON? What if the server sent back HTML instead? That’s exactly what I’m doing in the app I’ve been writing at my day job (as an aside, it still feels weird to write that), so what makes the SPA approach superior?
HTML over the wire takes us back to the simpler times of yore, while letting us use the tools we’ve invented in the meantime. From my perspective, that’s great, especially because it means that, in a lot of cases, you can get by with a front-end build process that looks like this:
- Add a script tag to your “base” HTML.
- That’s it. You’re done!
About as easy as it gets. So that’s why my redesign of Clave is going to use htmx and Alpine instead of a complicated SPA based on Vue. I’ll still have Tailwind for styling, so I don’t get away completely build-less, but you could swap in Bootstrap or Bulma or something and eliminate even that step.
The web is the center of many lives in this fallen time. We should be doing everything in our power to make it easier to contribute, and I think HTML over the wire is one way to do that on the development side. By making it easier to create complex applications, we’ll see more of them.
Most people would go to a spa for a vacation. I’m taking a vacation from the SPA, because the simpler life is so much better.