i decided to use htmx for a frontend for myself and it was a pretty fun experience. even got tailwind involved pretty easily with my rust+maud backend.
It’s funny to equate JS with SPA. We’ve had JS on the web since day 1 to add interactivity to otherwise static pages. SPA only became a thing decades later.
Sorry but you must have read with your eyes closed. Here’s a quote from the HTMX website:
”After all, both htmx and hyperscript are built in JavaScript. We couldn’t have created these libraries without JavaScript, which, whatever else one might say, has the great virtue of being there.
And we even go so far as to recommend using JavaScript for front-end scripting needs in a hypermedia-driven application, so long as you script in a hypermedia-friendly way.
Further, we wouldn’t steer someone away from using JavaScript (or TypeScript) on the server side for a hypermedia-driven application, if that language is the best option for your team. As we said earlier, JavaScript now has multiple excellent server-side runtimes and many excellent server-side libraries available.”
> HTMX is neither a meme nor is it anti-javascript, it is literally written in js.
Java is written in C++, but it is clearly "anti-C++" for any reasonable interpretation of the term. (Java historically replaced C++ as the most popular language, as far as I remember.)
More importantly, HTMX could have had native support without requiring an implementation in JavaScript.
> Why not just write the js yourself? It's really not that complicated. The people who keep pushing for htmx are weird.
HTMX is great. We use it as a middle ground for mildly interactive parts of the app. Places where jquery/vanilla would get annoying but going full React isn’t worth it. Admin interfaces in particular are a great fit – lots of CRUD, mildly interactive, very repetitive.
Adding `hx-get` to a button or div is way way quicker than writing all that boilerplate javascript yet again for the hundredth time.
Extra bonus: it encourages you to write small self-contained composable endpoints instead of massive kitchen-sink pages.
> Admin interfaces in particular are a great fit – lots of CRUD, mildly interactive, very repetitive. Adding `hx-get` to a button or div is way way quicker than writing all that boilerplate javascript yet again for the hundredth time.
Yes. Then imagine you have a massive legacy codebase and a control panel of something has a ton of data and buttons and inputs and all kinds of nonsense. Say you have a weight and dimensions of a package of a product... you'd like to make it so you can edit these in-place and when you do, a package volume (and/or volume sum of all packages) gets updated somewhere else on the page (along with some other info... I don't know, an estimate of product delivery cost based on volume, which delivery methods are now un/available etc.)
Like... you already have ways to calculate and show these in your server side logic. With HTMX you reuse these, add a sprinkle of hx-get and add some OOB updates and you're done. You can do the same with ajax, but not nearly as fast as with HTMX and much more annoyingly...
Why should I write it myself? Sure, I could do that, but then every time I want to have that sort of functionality on multiple pages I would have to write the JavaScript code multiple times. I could then roll it into a library. Maybe make the library work with custom HTML attributes. And now I've just reinvented HTMX. So I might as well use HTMX instead of reinventing it.
Such a weird question. You could ask that about any library ever.
there's a fair bit of functionality in htmx that isn't trivial: history support, event debouncing, etc. you can certainly write it yourself, but there are advantages to having existing functionality that is well tested and fits together reasonably
Because with HTML you get static, non-flashing, intstantly rendered without load times. So smart developers actually want less Javascript, because the browser already implements most of what Javascript does, why reinvent the wheel?
Why would I write React components myself when I the Javascript isn't really that complicated?
It is bizarre that ONLY HTMX gets these weird "DONT USE THAT ITS NOT POPULAR ENOUGH" criticisms.
XML, XLST get these criticisms except for the XQuery and XPath components because HTML fanatics need that to make their hybrid HTML/JS garbage apps work.
But really the ultimate goal for any good website engineer should be to offload as much logic and processing to the browser, not rewrite everything in JS just because you can.
> But really the ultimate goal for any good website engineer should be to offload as much logic and processing to the browser, not rewrite everything in JS just because you can
Why? This makes for a horrible user experience. Things like TicketMaster, and in recent years GitHub, slow my machine to a crawl sometimes. I much prefer mostly static content. This is a well-made website: https://www.compuserve.com/
Which isn't JavaScript's failure per se. I wouldn't wat to use a Google Maps like thing, with full page reload each time I scroll or zoom or check details of a place.
The issue is of "plain" websites for bad reasons add dynamic stuff.
Big fan of htmx here, so thanks for opening my eyes to a new way of using it with service workers.
But man, 10MB Go WASM download? That's a no go. It's not only about downloading it but executing on a clients machine over and over again. But I guess you can handle those requests perfectly fine just in service worker using pure JavaScript.
Go and even TinyGo aren't a great fit for Wa because they have to bring along their own runtime including a GC. Go can't use WasmGC because it lacks support for interior pointers and unboxed heap primitives: https://github.com/WebAssembly/gc/issues/59
So you'll never get Go Wasm binary sizes down to something reasonable, alas.
I did a bunch of game jams in various wasm langauges last year and what I got out of the experience was that you can do anything if you set your mind to it, but unless you have a good reason to use WASM (e.g. the performance?) you're generally going to be adding headache (build tooling, wrangling data between languages and runtimes, etc.) rather than removing it.[0]
(Some languages in particular are remarkably inflexible regarding how they want you to use them in this context.)
So seeing no real benefit. I ended up switching back to TS. I became depressed shortly afterwards, but that's probably unrelated ;)
Still, wasm game dev was a delightful experience in many respects and I would recommend it to anyone who's interested. ("Elimination of headache" is not necessarily an unambiguous good. Some headaches are genuinely worth it! Just depends on your taste and your goals.)
[0] My "favorite" bug was spending the last day of a game jam stuck on a bizarre compiler bug that would only manifest in the wasm version of the game... but I got it figured out in the end!
Using Rust instead of a Go would provide a smaller binary since it doesn't need a runtime. Compared to JavaScript apps, it's not terrible but also not great. One thing WASM has over JS is that it can decode and compile code in parallel across multiple threads as it streams in.
For comparison, opened a random NY Times article. It downloaded 19MB before the page loaded, and then tried to show me an ad (it failed to load, for some reason), and then refused to actually show me the article.
I know it's "whataboutism" but I thought it was pretty funny.
The geneal idea of HTMX is that your HTML will be rendered by the backend — à la Server Side Rendering.
To me this phrase makes no sense, what's the thought process behind this meaning of "render"? The only place HTML is "rendered" is in a browser (or in a user agent, if you prefer).
It's really cool to see someone else gravitate toward this idea. I think there might be some real potential in the future. I wrote about a similar idea in 2022 [0] and 2023 [1]. The service worker approach was heavily inspired by Richard Anaya's work [2]. HTMX migrating to fetch [3] makes this even easier. I had to create a xhr-fetch-proxy [4] to intercept requests with htmx today. I'm not the author, but would be happy to answer any questions.
Really enjoyed this article … thanks for opening my mind wider.
In case anyone thinks this idea is serious, my strong like of vanilla HTMX came from the realizations that (i) state management can revert to the ur-web model and avoid all the complexity of browser / server state synch and (ii) I can use anything I damn well like on the server (I wrote https://harcstack.org to optimize for expediency).
Wow I am loving this. I had a very related question on the htmx discord (ie can we load content from "any function" instead of an endpoint. My use case was that I used the FE (in typescript) in a very stateless way and had most of the logic driven by a go-wasm binary (the binary was pretty much the "M" and "P" in MVP). When I saw the Wasm binary here in the post it gave me a bit of relief. Cant wait to see this direction take off!
Local first is really relevant if you have the potential of users losing connectivity or is building some sort of collaborative workflow and want updates to happen automatically (like Linear or Google Docs).
Latency is not a real issue with SSR apps, there are a bunch of solutions to place servers and data closer to your users (within a few tens of ms). Plus you can prefetch and cache content very easily without using service workers. That’s not the reason Jira or GitHub feel slow; in fact GitHub was quite fast a few years ago when all it did was render pages from the server.
Interesting article, but isn't the main HTMX use-case mostly where you want to make server do most of the work, that is Remotely? As you literally render its responses directly - HTMX pages and fragments - instead of doing HTML -> JSON -> HTML gymnastics. Using paradigm of this kind to build local/client-first apps sounds weird.
This is interesting exactly because making everything come from the server (like htmx) saves oneself from having to do another frontend, but it has a disadvantage: it does not work offline. While many traditional SPA fail miserably at working offline, there is no such limitation in SPA land. It is a valid concern for htmx, and it is good that there are options. Addressing the limitation is precisely the point.
I think it would be nice to be able to use APIs that only return JSON, and be able to hx-swap in some text that comes from a specified JSON object/key... but the htmx developer has made it very clear to me that they are intentionally, ideologically allergic to JSON.
So far, all of the comments are taking this far too seriously. It's literally just: "htmx is supposed to be great" and "Local first is supposed to be great" so lets combine them in the dumbest way possible.
The WASM component just seems like a way to avoid writing models? Or is it demonstrating that you can run your server in the browser? Why is WASM needed then if it's just handling simple internal requests. WASM adds a layer of Golang which would be nice if the server needed to be portable from the local, but then why run the server locally at all if you need it in remote contexts? If you're trying to build a simple local JS app, why not just write it all in JS?
The author explicitly states that he likes to write Go and that’s why he picked it in this example, which in my opinion makes this article more interesting. The main benefit is that the 'local server' within the service worker mimics the 'real server,' which effectively means you only have to write the code once.
But I generally agree that a 10MB download on first load is not something that I’d be happy to serve to users, especially to those who are using their mobile network.
HTMX is neither a meme nor is it anti-javascript, it is literally written in js.
It does not aim to remove js from your code, it simply adds more features to HTML by default, like making any element able to trigger an web request.
When you write a real world app with HTMX, you inevitably end up writing some js, which is totally fine.
i decided to use htmx for a frontend for myself and it was a pretty fun experience. even got tailwind involved pretty easily with my rust+maud backend.
Nor is it "local first". It works by remotely pushing HTML into the DOM. It's really a form of push technology.
htmx isn't local first. this blog post is about trying to make it 'local first' by introducing a service worker.
It is definitely "anti-javascript" or more precisely "anti-SPA". I've read the blog posts.
htmx is pro-JavaScript:
https://m.youtube.com/watch?v=9ZhmnfKD5PE
It is not anti-SPA, but pro-hypermedia for the right problems:
https://htmx.org/essays/when-to-use-hypermedia/
htmx is a front end library of peace
JS != SPA though, no matter how many frontendies want to believe it is equivalent.
It’s funny to equate JS with SPA. We’ve had JS on the web since day 1 to add interactivity to otherwise static pages. SPA only became a thing decades later.
I was there on day 1 of the web and js was not yet even a twinkle in anyone's eye.
https://en.wikipedia.org/wiki/Dynamic_HTML
?? Since day1?
Day 1505 by my count. Say, does anyone know Javascript's birthday?
There was a pretty long gap between JS being created and people making significant use of it.
Sorry but you must have read with your eyes closed. Here’s a quote from the HTMX website:
”After all, both htmx and hyperscript are built in JavaScript. We couldn’t have created these libraries without JavaScript, which, whatever else one might say, has the great virtue of being there.
And we even go so far as to recommend using JavaScript for front-end scripting needs in a hypermedia-driven application, so long as you script in a hypermedia-friendly way.
Further, we wouldn’t steer someone away from using JavaScript (or TypeScript) on the server side for a hypermedia-driven application, if that language is the best option for your team. As we said earlier, JavaScript now has multiple excellent server-side runtimes and many excellent server-side libraries available.”
https://htmx.org/essays/hypermedia-on-whatever-youd-like/
It is definitely meant to provide an alternative to JS, obviously
It's more like a JS-heavy library that allows you not to write JS, or write it as little and as rarely as possible
> HTMX is neither a meme nor is it anti-javascript, it is literally written in js.
Java is written in C++, but it is clearly "anti-C++" for any reasonable interpretation of the term. (Java historically replaced C++ as the most popular language, as far as I remember.)
More importantly, HTMX could have had native support without requiring an implementation in JavaScript.
we are working towards incorporating some of its ideas into the html spec:
https://alexanderpetros.com/triptych/
Thank you
Why not just write the js yourself? It's really not that complicated. The people who keep pushing for htmx are weird.
> Why not just write the js yourself? It's really not that complicated. The people who keep pushing for htmx are weird.
HTMX is great. We use it as a middle ground for mildly interactive parts of the app. Places where jquery/vanilla would get annoying but going full React isn’t worth it. Admin interfaces in particular are a great fit – lots of CRUD, mildly interactive, very repetitive.
Adding `hx-get` to a button or div is way way quicker than writing all that boilerplate javascript yet again for the hundredth time.
Extra bonus: it encourages you to write small self-contained composable endpoints instead of massive kitchen-sink pages.
> Admin interfaces in particular are a great fit – lots of CRUD, mildly interactive, very repetitive. Adding `hx-get` to a button or div is way way quicker than writing all that boilerplate javascript yet again for the hundredth time.
Yes. Then imagine you have a massive legacy codebase and a control panel of something has a ton of data and buttons and inputs and all kinds of nonsense. Say you have a weight and dimensions of a package of a product... you'd like to make it so you can edit these in-place and when you do, a package volume (and/or volume sum of all packages) gets updated somewhere else on the page (along with some other info... I don't know, an estimate of product delivery cost based on volume, which delivery methods are now un/available etc.)
Like... you already have ways to calculate and show these in your server side logic. With HTMX you reuse these, add a sprinkle of hx-get and add some OOB updates and you're done. You can do the same with ajax, but not nearly as fast as with HTMX and much more annoyingly...
Why should I write it myself? Sure, I could do that, but then every time I want to have that sort of functionality on multiple pages I would have to write the JavaScript code multiple times. I could then roll it into a library. Maybe make the library work with custom HTML attributes. And now I've just reinvented HTMX. So I might as well use HTMX instead of reinventing it.
Such a weird question. You could ask that about any library ever.
there's a fair bit of functionality in htmx that isn't trivial: history support, event debouncing, etc. you can certainly write it yourself, but there are advantages to having existing functionality that is well tested and fits together reasonably
fixi.js is a more minimalist take on the same idea: https://github.com/bigskysoftware/fixi
agree that htmx users are weird
Because with HTML you get static, non-flashing, intstantly rendered without load times. So smart developers actually want less Javascript, because the browser already implements most of what Javascript does, why reinvent the wheel?
Why would I write React components myself when I the Javascript isn't really that complicated?
It is bizarre that ONLY HTMX gets these weird "DONT USE THAT ITS NOT POPULAR ENOUGH" criticisms.
XML, XLST get these criticisms except for the XQuery and XPath components because HTML fanatics need that to make their hybrid HTML/JS garbage apps work.
But really the ultimate goal for any good website engineer should be to offload as much logic and processing to the browser, not rewrite everything in JS just because you can.
> But really the ultimate goal for any good website engineer should be to offload as much logic and processing to the browser, not rewrite everything in JS just because you can
Why? This makes for a horrible user experience. Things like TicketMaster, and in recent years GitHub, slow my machine to a crawl sometimes. I much prefer mostly static content. This is a well-made website: https://www.compuserve.com/
Which isn't JavaScript's failure per se. I wouldn't wat to use a Google Maps like thing, with full page reload each time I scroll or zoom or check details of a place.
The issue is of "plain" websites for bad reasons add dynamic stuff.
Because I don't know js and don't want to touch it
Big fan of htmx here, so thanks for opening my eyes to a new way of using it with service workers.
But man, 10MB Go WASM download? That's a no go. It's not only about downloading it but executing on a clients machine over and over again. But I guess you can handle those requests perfectly fine just in service worker using pure JavaScript.
Go and even TinyGo aren't a great fit for Wa because they have to bring along their own runtime including a GC. Go can't use WasmGC because it lacks support for interior pointers and unboxed heap primitives: https://github.com/WebAssembly/gc/issues/59
So you'll never get Go Wasm binary sizes down to something reasonable, alas.
I did a bunch of game jams in various wasm langauges last year and what I got out of the experience was that you can do anything if you set your mind to it, but unless you have a good reason to use WASM (e.g. the performance?) you're generally going to be adding headache (build tooling, wrangling data between languages and runtimes, etc.) rather than removing it.[0]
(Some languages in particular are remarkably inflexible regarding how they want you to use them in this context.)
So seeing no real benefit. I ended up switching back to TS. I became depressed shortly afterwards, but that's probably unrelated ;)
Still, wasm game dev was a delightful experience in many respects and I would recommend it to anyone who's interested. ("Elimination of headache" is not necessarily an unambiguous good. Some headaches are genuinely worth it! Just depends on your taste and your goals.)
[0] My "favorite" bug was spending the last day of a game jam stuck on a bizarre compiler bug that would only manifest in the wasm version of the game... but I got it figured out in the end!
Using Rust instead of a Go would provide a smaller binary since it doesn't need a runtime. Compared to JavaScript apps, it's not terrible but also not great. One thing WASM has over JS is that it can decode and compile code in parallel across multiple threads as it streams in.
https://hacks.mozilla.org/2018/01/making-webassembly-even-fa...
IIRC wasm will get a GC soon, so i assume the tinygo project can produce way smaller binaries for wasm.
For comparison, opened a random NY Times article. It downloaded 19MB before the page loaded, and then tried to show me an ad (it failed to load, for some reason), and then refused to actually show me the article.
I know it's "whataboutism" but I thought it was pretty funny.
Oh and it does this even when you have a subscription.
I built something with Service Workers a few years ago. It's similar in concept, but I never got around to syncing with a server.
Instead of a WASM backend, I used react-dom/server to generate the HTML.
https://github.com/michaelcpuckett/listleap?tab=readme-ov-fi...
I have an issue with
To me this phrase makes no sense, what's the thought process behind this meaning of "render"? The only place HTML is "rendered" is in a browser (or in a user agent, if you prefer).>, what's the thought process behind this meaning of "render"?
It's another use of "render" relative to the server such as converting non-HTML data inside database tables, json, etc --> rendered into HTML:
https://www.google.com/search?q=SSR+server+side+rendering
Many different perspectives of "rendering":
- SSR server-side rendering : server converting data to HTML
- CSR client-side rendering : e.g. client browser fetching and converting JSON/XML into dynamic HTML
- browser-engine rendering : converting HTML to operating system windowing GUI (i.e. "painting")
"render" as in being templated with server-side data/logic.
See also Server Side Rendering (SSR) which uses the term rendering in the same way.
Django uses a render() function to convert a template to HTML, then return it as an HTTP response.
One of the many dictionary definitions of the word also appears to be to "give an interpretation or rendition of" something.
It's really cool to see someone else gravitate toward this idea. I think there might be some real potential in the future. I wrote about a similar idea in 2022 [0] and 2023 [1]. The service worker approach was heavily inspired by Richard Anaya's work [2]. HTMX migrating to fetch [3] makes this even easier. I had to create a xhr-fetch-proxy [4] to intercept requests with htmx today. I'm not the author, but would be happy to answer any questions.
[0] https://logankeenan.com/posts/a-rust-server-app-compiled-to-...
[1] https://logankeenan.com/posts/client-side-server-with-rust-a...
[2] https://github.com/richardanaya/wasm-service
[3] https://news.ycombinator.com/item?id=45803358
[4] https://github.com/logankeenan/xhr-fetch-proxy
Really enjoyed this article … thanks for opening my mind wider.
In case anyone thinks this idea is serious, my strong like of vanilla HTMX came from the realizations that (i) state management can revert to the ur-web model and avoid all the complexity of browser / server state synch and (ii) I can use anything I damn well like on the server (I wrote https://harcstack.org to optimize for expediency).
Wow I am loving this. I had a very related question on the htmx discord (ie can we load content from "any function" instead of an endpoint. My use case was that I used the FE (in typescript) in a very stateless way and had most of the logic driven by a go-wasm binary (the binary was pretty much the "M" and "P" in MVP). When I saw the Wasm binary here in the post it gave me a bit of relief. Cant wait to see this direction take off!
In htmx 4.0 you are able to do pretty much anything, up to and including replacing `fetch()` with your own implementation on a per-request basis.
So you should be able to achieve pretty much anything at that point. A nice side-effect of moving to fetch.
oooh nice. We are truly going to a fucntional world! The (pesky) "http fetch" is now just a detail it sounds like?
Local first is really relevant if you have the potential of users losing connectivity or is building some sort of collaborative workflow and want updates to happen automatically (like Linear or Google Docs).
Latency is not a real issue with SSR apps, there are a bunch of solutions to place servers and data closer to your users (within a few tens of ms). Plus you can prefetch and cache content very easily without using service workers. That’s not the reason Jira or GitHub feel slow; in fact GitHub was quite fast a few years ago when all it did was render pages from the server.
I'm not a web dev but isn't the initial page load going to be a bitch if you have to ship a whole ass web server with it?
Interesting article, but isn't the main HTMX use-case mostly where you want to make server do most of the work, that is Remotely? As you literally render its responses directly - HTMX pages and fragments - instead of doing HTML -> JSON -> HTML gymnastics. Using paradigm of this kind to build local/client-first apps sounds weird.
This is interesting exactly because making everything come from the server (like htmx) saves oneself from having to do another frontend, but it has a disadvantage: it does not work offline. While many traditional SPA fail miserably at working offline, there is no such limitation in SPA land. It is a valid concern for htmx, and it is good that there are options. Addressing the limitation is precisely the point.
I think it would be nice to be able to use APIs that only return JSON, and be able to hx-swap in some text that comes from a specified JSON object/key... but the htmx developer has made it very clear to me that they are intentionally, ideologically allergic to JSON.
So far, all of the comments are taking this far too seriously. It's literally just: "htmx is supposed to be great" and "Local first is supposed to be great" so lets combine them in the dumbest way possible.
This architecture looks perfect, for the locally inclined. Waiting for episode 2.
The WASM component just seems like a way to avoid writing models? Or is it demonstrating that you can run your server in the browser? Why is WASM needed then if it's just handling simple internal requests. WASM adds a layer of Golang which would be nice if the server needed to be portable from the local, but then why run the server locally at all if you need it in remote contexts? If you're trying to build a simple local JS app, why not just write it all in JS?
WASM is not needed.
The author explicitly states that he likes to write Go and that’s why he picked it in this example, which in my opinion makes this article more interesting. The main benefit is that the 'local server' within the service worker mimics the 'real server,' which effectively means you only have to write the code once.
But I generally agree that a 10MB download on first load is not something that I’d be happy to serve to users, especially to those who are using their mobile network.
why we even need a backend. just run it in the browser. is there a framework for that?