A Response to "Have Single-Page Apps Ruined the Web?" (2021)
htmx.org
htmx.org
HTMX really shines in a few areas for me.
1. Async loading of things (ex: render a dashboard and THEN load the chart data) to prevent blocking page loads.
2. Lazy loading of things (ex: Instead of rendering a modal for every row in a table, fetch and display the modal when the row edit button is clicked).
3. HX-Boost is nice. I have always been a fan of Turbolinks (classic) and preventing full page loads and allow permanent page elements. Boost makes it possible out of the box.
4. It leaves wiggle room for progressive enhancement. For example, if you are lazily loading a modal but JS is disabled, you could open a separate page for the modal/form instead of lazily fetching and displaying in-page. It's more work, but at least it's _possible_.
Alpine on the other hand is nice for different things. I mainly use Alpine for things like handling a dropdown, slideout, animating things, etc.
All of this is done without writing any JavaScript. I am able to stay in my HTML templates or backend (in Golang) without ever touching JavaScript. I also adopted Tailwind for the same reason. I essentially write the CSS in the HTML (with classes) and let tailwind compile and generate the CSS for me... no more unused CSS. No more CSS clashes, naming conventions, etc.
It's a great workflow.
edit:
I just wanted to say I use HTMX with the head-support plugin bundled together. @recursivedoubts, hoping for 2.0 soon to come with support built in :)
one thing that I didn't note in that section regarding edge computing is that if the data store isn't edge, then putting compute on the edge doesn't help that much, which vercel has started to admit (https://twitter.com/t3dotgg/status/1781881405397442947).
i'll state my position again: htmx makes hypermedia a more competitive approach for many web applications, but it isn't right for everything. i'm not puritanical about approaches and agree strongly w/ Rich's take on "transitional apps" where you use the right tool for the given job.
where i'd probably disagree w/ Rich is where the line is: i think w/ things like htmx (or unpoly or hotwire or datastar, etc.) the total space of problems that can be effectively addressed with hypermedia expands significantly
It pretends to not be a JS library/framework while it is. It tilts at windmills that are badly structured/built apps.
I agree that most webapps are built on too large libraries. I agree that the dependency chains are crazy. etc. etc.
But the solution proposed by htmx is IMO bad and the self-righteous tone is even worse.
Seems to me like htmx tries really hard to market as "just hypermedia" and it's not. Besides things like 'hx-ws' or 'hx-on' we've already talked about the normal cases where you need custom scripting like normal error-handling.
Just hypermedia (as both the UI and API) has been around for 3+ decades. htmx isn't that and should not claim to be that.
Sse and web sockets are extensions. Hx-on is to address the fact that standard on* attributes can only handle fixed events, but I agree it is wandering away from the core hypermedia functionality of htmx. I was on the fence on adding it, but relented when we found a good mechanism for supporting it (xpath) and some long time users expressed that they wanted to avoid needing something like alpine for the simple scripting use cases of their apps.
Htmx also fires a lot of events and I don’t make a secret of the fact that scripting is part of fieldings description of the web and perfectly acceptable in a hypermedia driven application:
Besides memes I don't see this at all. The htmx project doesn't shy away from what it is: javascript.
Hypermedia has stagnated for 2+ decades. Asserting that hypermedia cannot be more than what current implementations have delivered is stolid and myopic.
htmx represents a vision of: 1. What is the core idea of hypermedia? 2. What would hypermedia look like if the core idea was logically extended to be more useful than the original implementations? and 3. How can you use javascript to fill the gap between the html+http that we have, and this expanded idea of what hypermedia could be?
Obviously it has to do this as a javascript library because that's the only possible path. And it's great that existing web technologies are flexible enough to explore interesting ideas like this. But it's silly to discount a project because it's based on a particular vision of how to add life back to older technology.
I've worked with some newish developers that know of no other way than to bring in a frontend framework for the simplest of things. E.g. adding a carousel (don't ask) to an existing site that has no need for a build step and the first thing they want to do is bring in node and react.
Going without a buildstep meant remembering the last 2-5 versions of JS and then having to write in the lowest common subset for your browser compatibility requirements. Speaking for myself: being able to keep up with the language evolution and transpile to that compatible subset automatically saved way more pain than configuring a build step cost me.
I don't think it's unreasonable to only want to have to write and read a single dialect of JS across projects. Nevermind all the polyfilling we had to do to get common compatible APIs.
Nowadays, the most recent crop of browser versions are a lot more similar to each other than they used to be.
Maybe your colleagues don't know the DOM APIs or are less comfortable with finding some random jQuery plugin to do a carousel but I can't really begrudge anyone for wanting to have the full capabilities of a modern frontend stack.
We had a 2 two-week sprints where they couldn’t decide on a date selector and had to build our own. Then there’s this huge GraphQL monstrosity we have to support the front end - but it’s better than REST, I think?? Ah I could rant..
i have my own morphing algorithm (and a corresponding htmx plugin that allows you to use it) called idiomorph:
https://github.com/bigskysoftware/idiomorph/
i've also been working with the chrome team to get a feature added they are calling "atomic moves":
https://github.com/whatwg/dom/issues/1255
this would allow us to move elements around in the DOM without losing things like play state or focus or whatever
very excited for this last idea, I think it will be a huge boon for the web in general, not just for htmx
the first option isn’t bad once you get the htmx mental model, but preserving video elements is on the edge of what htmx is a good fit for
otoh, when it’s a good fit you can simplify your app a lot:
With htmx, you plan and prepare partial page updates yourself and htmx swaps them in for you.
With React, you get to maintain the entire npm toolchain that your app depends on, including fun things like 'React 19 will no longer patch the fetch() function, so you have to handle double-fetch manually'.
But then on the other hand, the picture that builds in my mind turns more and more into "SPA, but everything is declarative" (except for extensions to the declarative toolkit that are easy to keep separated from domain code), and that could really be quite awesome. More so when you come from an MPA background anyways. (or when your codebase comes from an MPA background!)
that's the core difference w/ other SPA approaches
I love it, but it takes some time to get used to.
It is a new way to think compared to the "modern js framework" craze over the last 10 years.
But, you're right, it is the "old" way of using the browser/html with sprinkles of new interactivity.
Didn't even think about that.
But, HTMX fits very well together with the traditional server-side rendered websites and probably you wont need to do much cognitive rewiring
see if it makes sense or not
I like to sprinkle a little alpinejs in whenever I need some client-side things.
Many times 3 lines of simple to understand htmx code will be equivalent 200 lines of VueJS code - and with a lot less bugs. It is insanely productive.
Can you tell me why you think so? I love Go, but their templating is not my favorite.
Reasons:
1. It's...already happening. (See: job listings, big web platforms, popular desktop apps.)
2. Deploying one unified codebase on the web, mobile, and all major desktops is a phenomenal value. Nobody cares that HN people hate the lack of native controls, slower performance, memory usage, whatever. Good enough is good enough.
3. Vastly less friction hiring from the world's largest dev pool and onboarding them to codebases written with familiar tech.
4. TypeScript's system blow away most other type systems, and sharing them between front/backends is a big deal.
5. Node.js can do nearly anything, is fast (enough), and pulls tools from the largest community of packages on Earth.
6. UI frameworks often heft around piles of heavy abstractions. Nobody wants to learn yet another awkward, shitty programming language that you invented with your templating system. Or the heap of classes needed to do basic things "properly." React avoids this junk and stays simple -- write everything in pure TypeScript (no templates!), declaratively, with a minimal lib. KISS.
To save time replying to common misconceptions: No, JSX is not templating; Yes, tech/tool competitor ABC exists -- TS/Node/React's momentum will slowly kill it; If you like kitchen-sink frameworks, plenty of extremely popular/polished/active ones exist for making SPAs, MPAs, and mixtures between using React; Yes, programming problem space XYZ won't adopt this stack due to particular constraints, you're missing the point;
There, hopefully I pissed off everyone with my overly snarky and opinionated position. I deserve the hate. (I'm still right, tho.)
This is not a controversial take, it is just the status quo.
> Deploying one unified codebase on the web, mobile, and all major desktops is a phenomenal value.
Yeah, except when it doesn't work because of fun cross-platform incompatibilities like 'React Native Toast library doesn't support web'.
> Vastly less friction hiring from the world's largest dev pool and onboarding them to codebases written with familiar tech.
Sure, if you don't have to think about legacy codebases full of class components, hooks, Flow.js, and other technologies, and only have to care about the latest and greatest React version, it's all good.
> TypeScript's system blow away most other type systems,
In complexity, and compile times, sure. There are simpler and more powerful type systems out there, eg ReScript.
> Nobody wants to learn yet another awkward, shitty programming language that you invented with your templating system
Agreed, and it's my opinion that everyone should use HTML rendering libraries in their chosen programming language.
> React avoids this junk and stays simple -- write everything in pure TypeScript (no templates!)
Sure, if you don't count JSX as a 'template' with some 'awkward' syntax, like `className` etc.
> No, JSX is not templating
...