Thin Client
After working with React applications for almost 5 years, I have a certain morbid attraction to the idea that React - along with all other SPA libraries, development, and progress - is unnecessary.
Obviously React exists in a very complex ecosystem. To write the React applications the right way requires:
- javascript transpilers/bundlers
- hundreds of npm libraries,
- (potentially) SSR, SSG frameworks and tools
I can’t help but feel that the vast majority of web apps that use React do not actually need it. Most apps are just not that complex, and the amount of SPA features that most apps provide is actually pretty minimal.
Another feeling I can’t shake recently is that the robustness of React components, their reusability, is also not usually necessary.
Apart from the base UI components in whatever project I’m working on (buttons, modals, dropdowns, etc.), the vast majority of my components are not reused. Most web apps don’t really share that many features between different views, and if they do, it’s only in one or two other places. The cost benefit of React apps, considering the vast resources organizations spend to create them, just doesn’t seem worth it.
Then there’s the problem of AJAX.
When the backend of an application spits out JSON for the frontend to consume, only to convert it back to recreate the same types on the frontend (which is admittedly ameliorated by a NodeJs backend), there’s duplicated work - often very time-consuming work as well.
SPA frontends often end up resorting to something like Redux (or even the Apollo Client cache), as a global database. The problem is this frontend database needs to be kept in sync with the real backend database, which ends up being a cause for much of the complexity in these apps. Whenever I see Redux used in a project, I almost never see a well-laid out set of truly reactive data that percolates through the entire app. No, the store almost always becomes a sprawling hierarchy of nested data which inevitably ends up being used by a single page, and usually only a single component in a single instance. I’d estimate this is probably the case for 95% of the data in the Redux store for every project I’ve worked on. One could argue that the base domain objects (User, Cart, etc.) are invaluable pieces of global state usually kept in Redux state, so any changes to permissions for example would percolate through the app without the need for a refresh, but I wonder if that’s really worth it…
Almost all the features I see in the average SPA are actually reproducible with a simpler stack, and a little bit of conscientious page design, which is why I like to call them “SPA-lite” apps.
A lot of other people are noticing this too. The phenomenon is “SPA fatigue”, and it’s been stirring in the web development community.
There has been great progress over the last couple years in alternatives, like htmx
, supporting a true HATEOAS paradigm, and elixir
(especially paired with LiveView
), both of which provide almost all of the SPA features that most apps currently use.
GraphQL is almost the antithesis of the principles of htmx
, but it is still an improvement over the current state of REST-based SPAs.
Whereas htmx and elixir LiveView move most of the frontend’s responsibility back to the backend, graphql moves the most of the backend’s responsibility to the frontend.
As a frontend developer who works in an SPA-lite organization, I advocate for GraphQL so that my job (and my colleagues’) becomes easier.
As someone who is interested in building apps on his own, I reach for alternatives.
Because I’m the only developer, I need to use the simplest tools available that provide the most power, and htmx
fits the bill.
Over and over I see folks overestimating the resources their servers require, overestimating the power and complexity their frontend application necessitates, overestimating the scale to which their organization will grow, overestimating the number of customers they will be able to reach and convert, overestimating the valuation of their startup…
The tech world is obsessed with overestimating. If I’m going to be an anti-mimetic developer - if I’m going to be a 10x developer - if I’m going to be a solo developer - then I need to shrug the yoke of overestimation. I need to reach for the simplest tools available.