Oh wow! This is a huge honour, thank you so much! I definitely started writing a "lol HTMX is shit" post, but it just wasn't honest. HTMX is incredibly powerful - I am a fan of what you all have done with it. This attempt on my part to try and write something server-side rendered wouldn't have happened without the kick up the butt HTMX gives me (and all of us).
No problem at all. There are aspects of htmx that are good and bad depending on context and experience, and I like having different perspectives on it available for people to read, so thank you for taking the time to put together an in depth essay on it.
I was quite excited for Datastart until I saw that they keep a good chunk of the functionality behind a proprietary license [1]. It's not even about the price (it is a bit steep though, but I guess if you use it in a commercial project it will pay for itself), it's the proprietary part.
Yeah, in my (limited) experience, htmx works best to grease the wheels of an oldschool multi-page app.
I tried building something with SPAish drag-and-drop interactivity using htmx, and my ultimate conclusion was that functionality like that should either be totally encapsulated as one big htmx swap unit or be written as js "islands" outside htmx.
For my projects that require a distinct unit of functionality, I typically reach for a JS library that I can include as a payload (no npm, no deps, just a JS file). SortableJS is a good example, so is MarkdownJS if I want the browser to handle MD rendering.
This only goes so far, though. At some point, an app developer might want to integrate these distinct units of functionality, and I'm not sure how I would go about that. I haven't gotten to that point.
I would love to see cross browser support for forms encoded as application/json instead of url encoded. Additionally making name attributes in forms a query path selector to be able to nest JSON data structures would go a very long way.
Regarding web components and htmx: I kind of disagree with the server sided rendering approach there because I believe in local first web apps that use JSON or other data formats to communicate, but I'm pretty stubborn like that.
Don't have much to prove it yet, but I'm working on gooey, my bindings and components library for WebASM. Hopefully I'll get there in the next months, though Go has a couple of limitations due to how the type system works.
> I would love to see cross browser support for forms encoded as application/json instead of url encoded. Additionally making name attributes in forms a query path selector to be able to nest JSON data structures would go a very long way.
This would be simply amazing. Would so drastically reduce the JavaScript truly needed for basic CRUD stuff. Could even eliminate it if you don’t need variable-length arrays. Just the simplicity of POSTing forms…
The first principles thinking of projects like htmx and Datastar is sorely needed in web development. The field has been led astray far too long by blindly following trends that were poorly designed to begin with.
You're so right - React is overwhelmingly popular despite its horrid design of running things on the client. No one should ever do that. Make the server do all the work!
innerHTML was the default of htmx for historical reasons, Alex pointed out that anything that can be achieved with innerHTML (or the other swap styles) can also be achieved with outerHTML (albeit with more violence to the DOM) so we felt that was the simplest option for a more general proposal.
> MESH is based on a simple principle: one component = one endpoint. This is a powerful idea - it allows us to write a HTML-first back-end in such a way that it feels like writing an SPA.
Gotta admit, I'm still not completely grasping the hype around HTMX, but I thought one of the core ideas was that it decidedly should not feel like writing an SPA, but more like old-style PHP or ASP scripts again. (In the sense that the front end is driven by the back end instead of the other way around)
So wouldn't this give you sort of the worst of both worlds? The modeling overhead of SPAs + the tight coupling of HTMX?
> MESH is based on a simple principle: one component = one endpoint. This is a powerful idea - it allows us to write a HTML-first back-end in such a way that it feels like writing an SPA.
Yeah, I immediately could tell this is where the idea and HTMX collided.
In the worldview where HTMX shines, every page is just a document. HTMX is just a small library to add some capabilities for better interactivity. The goal is precisely to avoid what the author wanted.
> Gotta admit, I'm still not completely grasping the hype around HTMX
Right place, right time.
React, the darling of web dev, has become huge and unwieldy and complex. The newcomers haven't been able to unseat it due to sheer ecosystem advantage. And then comes HTMX with quirky marketing hitting all the right notes (and having some actual good ideas underneath all that).
> With this little helper, I can now start building out a very simple Trello clone to prove the concept.
It's probably worth reading hypermedia.systems before using htmx. The book itself says that for more interactive components, you should go ahead and use JavaScript and whatever interactive framework you want to use on top of that.
I use htmx with Django when:
- I want to have some assurance that I will only have to minimally upgrade dependencies over the next few years
I'm conflicted about this post. On the one hand, it's encouraging and cheerful. On the other hand, it pretends to evaluate HTMX by insisting on conventions which... have nothing to do with HTMX.
Spoiler: HTMX does not deliver under artificial constraints.
From "framework fatigue" to "new framework" in five paragraphs.
Personally, I find all these minimalist, back-to-the-basics frameworks a bit misguided. It's always reeks a bit of "well my farts don't smell" – other developers' frameworks are bloated, dependency-overloaded and too complex. My new framework is simple, based on a powerful idea, and just right.
Imo, the best way to build a truly good web app in 2025 is to embrace both server-side rendering and client-side rendering, by sharing the same rendering logic between client and server, like e.g. SvelteKit, Next.js and others do.
No, fameworks are relatively opinionated towards the goal the creator had, which is usually in a README.
They're all tools that need more context to decide on when you use them.
For example, in my use case (SaaS) I focus on something that makes refactoring a breeze. Type-safe end-to-end is important there, so I use orpc+react for most projects. If you don't like contract-first APIs you're going to hate this, but it makes me think out what I actually want in my frontend before I write the database. This kind of [mocking -> real data] way of coding makes you proactive when designing the app
I feel like this would have been a bit better with some sort of "recap" at the end, to summarize where he got to. The README on the MESH page is a good summary:
> MESH is a fun project intending to demonstrate the kinds of concepts embodied by HTMX - without using HTMX. Specifically, we're rendering modular elements on the server, and hydrating them on the client, swapping them out as needed instead of reloading the whole page. Component updates are swapped in place. Out-of-band updates are sent to all connected clients via SSE (server-side events), meaning all users see updates in real time.
(To expand that for people not familiar with HTMX's out-of-band updates: Basically, in MESH, on the client you hook up something listening to updates sent from the server via SSE. What the server sends are basically snippets of HTML with an ID in them; the listener on the client replaces the HTML in the DOM with that ID with the HTML sent over the wire. This allows the server to arbitrarily update the client's UI.)
So it shares one of the mechanisms of HTMX, which is to do SSR with the ability to replace individual elements.
The concept of MESH sits somewhere between course grain components and server islands.
React is for fine grain components and HTMX is for lightweight interactivity — update part of a page.
The classic React use case is an editable, filterable drop down. The classic HTMX use case is click a button and load some text.
The overlap comes in the middle, with a simple form validation. React says make each field a component that handles its own validation and error messages. HTMX says just return a re-rendered form with the error messages. MESH says make the form a component with its own endpoint.
> HTMX says just return a re-rendered form with the error messages. MESH says make the form a component with its own endpoint.
HTMX can do the same thing: you can do `hx-trigger="changed delay:500ms"`, and make an endpoint for that component that will do validation, update an error message status area (adding or removing an error as appropriate), and even potentially enable / disable the "submit" button.
It seems to me that the main difference in approach is whether the "source of truth" for the state of the page is on the client or the server. HTMX is designed to be flexible (which is one of TFA's complaints actually), but its primary vision is HATEOAS (Hypertext as the Engine of Application State); which to my understanding of reading HTMX's documentation, is meant to mean that everything important about the client state should be kept on the client; the server should be able to be entirely reactive. What I see skimming through MESH (and data-star.dev) is that the "source of truth" is on the server.
Not an authority in this area, so happy to be corrected on all those points. But I am in the middle of building a dynamic query form using HTMX, trying to design it with HATEOAS principles, so it is something fresh in my mind at any rate.
The hot one for me right now is C#'s Blazor, which is not too young, bout 8 years now? Basically you can either have it do all the back-end dynamic rendering with C# for your front-end (Server Blazor) or you can compile it to Web Assembly. I have not written any JS in over a year, and the UI is very similar to how Razor pages are made.
I'm of the opinion that this is the future of web development for numerous web frameworks should they invest in tech similar to Blazor. Phoenix's LiveView also comes to mind. I am hoping a brave soul builds something for Django (I've been meaning to try, but I have too many side projects going on atm) that is similar to Blazor.
> I'm of the opinion that this is the future of web development
Maybe but not with C#. Rust is a much better language for compiling to WASM. Leptos achieves something similar to Blazor with a fraction of the CPU and bytes.
I would love to be able to handle all my web stack with C# but unfortunately the WASM bundles are too heavy for most use cases. Plus the DX for frontend is not even as good as it was with JS and Webpack like a decade ago. And these days the bar is much higher with Vite.
Rust is unnecessarily low-level for the vast majority of things that a web app would be doing. There's no reason to struggle with the borrow checker in that kind of code when tracing GC is available and makes things so much easier.
At one company we had a contractor come in say I can totally build a simple IoT dashboard with a few buttons and wanted to use Blazor. I used Phoenix LiveView, on rpi3’s and later rpi4’s just fine. So Blazor sounded similar and figured it’d be fine.
However Blazor just totally tanked the RPi that had 4gb of ram. It took minutes to load a web page when it did load.
Of course that was years ago. Hopefully Blazor got better. Given that starting point I’d doubt it’ll ever match Elixir LiveView in efficiency.
IMHO, other systems will to struggle to replicate Elixir’s LiveView due to BEAMs design using preemptive actors. It’s not impossible, just that’d it’d take a lot of work to match the responsiveness and resource usage.
Currently I’m using Nim on backend and front end using a Karax SPA. It’s pretty nice sharing the same code on front end and backend!
> However Blazor just totally tanked the RPi that had 4gb of ram. It took minutes to load a web page when it did load.
Sounds like Blazor Server, if WASM was used, that shouldn't have been the case. I'm not very surprised considering how insanely efficient the BEAM is with memory.
Why anyone would choose to use the Razor syntax at any time is beyond me, let alone for the web. There is no need to make it so complicated, HTML is interpreted.
As the article says :
> HTMX leaves it up to the developer to impose discipline on their code, however they see fit.
He said that like it's a bad thing. I really dislike those frameworks like Angular for example who simply say "You need to do it the Angular way". That just slows down innovation or clever ideas that solve little problems. Instead if there is a slow framework (looking at some peoples react implementations, Cloudflare recently [0]) Well you probably wont consider it or just see it as a "quirk" of the framework.
There is no "blazor" way as far as I can tell, we've been rewriting our logic and structure since when everyone started on this project nobody knew how to structure Blazor, moving forward we are following best practices from React projects to an extent in order to better organize and keep components tidier.
Yeah, I'm very wary about putting all my eggs in Microsoft's basket after what I've seen.
They have a pretty extensive history of encouraging everyone to get on the wagon only to drive it straight into the nearest ditch. You can't trust a company that competes with its own customers.
I know all three, and I'm not seeing it dying any time soon. WebAssembly is not going anywhere, neither are dynamic back-end systems. I have drastically less issues with my front-end while using Blazor compared to just doing raw JavaScript. I've built everything from a PWA from scratch using Vanilla JS, to an iFrame Frenzy web app a client paid us top dollar to build.
Silverlight was proprietary, Blazor is MIT licensed and using open web technologies that are NOT going anywhere any time soon. We just had another major upgrade to Web Assembly's spec not that long ago.
Which is kind of return to WebForms, GWT and JSF ways of working, only the implementation is a bit different than on the 2000's.
We moved into MVC approach, because of the headaches that it used to be having to debug all the generated stuff from what the browser actually supports as built-in technology.
I don't see that bright future for Blazor, other than a few .NET shops that don't want to learn native browser technology.
The debugging experience and the lack of context shift when going from thinking about how C# works to JavaScript (and all its zillion quirks!) is insanely better. I can put a breakpoint for the front-end and debug it just fine withing VS. I do wish Microsoft would finally open source their debugger, since I've heard loads of complaints about it being proprietary still.
Blazor and Phoenix both seem the most intuitive for me also, especially when building complex frontends that require a lot of business logic. Being able to ditch the JS for that kind of work is amazing.
Blazor suffers from needing to lift the entire .net runtime into wasm. So first you download a gazillion resources that reimplement .net core/runtime/memory/garbage collector/whatever into the page. An eternity later your hello world can finally run.
Though they did manage to really shave the runtime off somehow. It used to load megabytes and megabytes of data.
> numerous web frameworks should they invest in tech similar to Blazor. Phoenix's LiveView also comes to mind.
Phoenix live view sends minimal diffs that get applied to the DOM. It doesn't have "components that run in the client and on the server". Everything is done on the server, with very specific extension points into JS
Definitely - I think what's really interesting is that there is clearly a kind of "attractor" which all of these frameworks are pulled toward. That's kind of mainly what I was trying to aim at with the blog post - MESH isn't a solution at all, it's more I built it to show why it would go that way, i.e. the same way LiveView etc. and of course Blazor went. My question is: is there a form of this that could be merged back into the HTML spec itself and supported by the browsers? My gut says there isn't, by the way.
There are definitely some parts that are common between these that it could be nice to propagate to the standard. https://alexanderpetros.com/triptych/ lists some of them but I'm not certain how specific to htmx it is or how much it apply to the different variants.
Yeah I wasn't trying to take away from what you wrote, just sharing my experience with a different framework. :) Please, use and work with what keeps you productive!
At a previous job they were moving away from Blazor (which bummed me out, I love the philosophy) because every time they deployed it broke sessions/disconnected all active users.
I've made some toys with Blazor; my teams are using Vaadin at a Java shop, now. Not exactly the same implementation, but a similar idea: express front end code using the backend language.
Blazor is fucking terrible. In principle it works in some use cases, the the library is designed horribly and it's very difficult to implement well behaved components. It's like a half-baked react 10 implementation.
I am torn about SSR. I see the advantages but I hate the workflow so so much... Also tightly coupling the views to your backend is something I really hate.
I want to stay flexible, a completely independent frontend and a completely independent backend.
I tried Phoenix for about 7 months this year and ultimately quit due to it feeling clunky and unintuitive, same with Livewire or any other SSR templating solution I've found.
If there's SSR templating that is actually enjoyable to work with (from a DX perspective), I'd happily try it. Sadly nothing feels as good as just building web components.
Try Datastar, it leans into web components, and they're working on a plug-in that integrates web components with Datastar. For example, I believe the star field on the front page of it's site is a web component.
We write only front-end logic on our Blazor components now, and use services to glue the front-end to the back-end which is the recommended way is my understanding. It's really nice, especially when you pull in something similar to MudBlazor.
One other comment, if you want to experiment w/different behaviors and defaults around the general concept of htmx (generalized hypemedia controls in HTML) you can fork fixi.js which is 89 lines of code (and uses `outerHTML` as the default swap strategy):
https://htmx.org/essays/#on-the-other-hand
Regarding the default swap behavior of "innerHTML":
https://htmx.org/quirks/#the-default-swap-strategy-is-innerh...
Our proposal to merge htmx functionality into the HTML spec uses outerHTML:
https://alexanderpetros.com/triptych/
Also consider datastar, it was written from an SSE-first perspective by a go engineer:
https://data-star.dev/
Super excited about triptych too! Thanks for pushing that.
- [1] https://checkboxes.andersmurphy.com
[1] https://data-star.dev/reference/datastar_pro
[1] https://andersmurphy.com/2025/04/07/clojure-realtime-collabo...
I tried building something with SPAish drag-and-drop interactivity using htmx, and my ultimate conclusion was that functionality like that should either be totally encapsulated as one big htmx swap unit or be written as js "islands" outside htmx.
This only goes so far, though. At some point, an app developer might want to integrate these distinct units of functionality, and I'm not sure how I would go about that. I haven't gotten to that point.
Dead Comment
I would love to see cross browser support for forms encoded as application/json instead of url encoded. Additionally making name attributes in forms a query path selector to be able to nest JSON data structures would go a very long way.
Regarding web components and htmx: I kind of disagree with the server sided rendering approach there because I believe in local first web apps that use JSON or other data formats to communicate, but I'm pretty stubborn like that.
Don't have much to prove it yet, but I'm working on gooey, my bindings and components library for WebASM. Hopefully I'll get there in the next months, though Go has a couple of limitations due to how the type system works.
[1] https://github.com/cookiengineer/gooey
This would be simply amazing. Would so drastically reduce the JavaScript truly needed for basic CRUD stuff. Could even eliminate it if you don’t need variable-length arrays. Just the simplicity of POSTing forms…
The first principles thinking of projects like htmx and Datastar is sorely needed in web development. The field has been led astray far too long by blindly following trends that were poorly designed to begin with.
https://htmx.org/examples/sortable/
But if you really want a component-based system then htmx can be a battle.
I outline when I think htmx is a good fit here:
https://htmx.org/essays/when-to-use-hypermedia/
Dead Comment
Might be beneficial to think the other way around, and rather think htmx was not a good fit for the app.
Gotta admit, I'm still not completely grasping the hype around HTMX, but I thought one of the core ideas was that it decidedly should not feel like writing an SPA, but more like old-style PHP or ASP scripts again. (In the sense that the front end is driven by the back end instead of the other way around)
So wouldn't this give you sort of the worst of both worlds? The modeling overhead of SPAs + the tight coupling of HTMX?
Yeah, I immediately could tell this is where the idea and HTMX collided.
In the worldview where HTMX shines, every page is just a document. HTMX is just a small library to add some capabilities for better interactivity. The goal is precisely to avoid what the author wanted.
Now? No one knows or can tell you what they are for (except leaf components and HTML Web Components maybe)
Right place, right time.
React, the darling of web dev, has become huge and unwieldy and complex. The newcomers haven't been able to unseat it due to sheer ecosystem advantage. And then comes HTMX with quirky marketing hitting all the right notes (and having some actual good ideas underneath all that).
Deleted Comment
It's probably worth reading hypermedia.systems before using htmx. The book itself says that for more interactive components, you should go ahead and use JavaScript and whatever interactive framework you want to use on top of that.
I use htmx with Django when:
- I want to have some assurance that I will only have to minimally upgrade dependencies over the next few years
- I'm doing something bog-standard (dashboard / admin UI)
Spoiler: HTMX does not deliver under artificial constraints.
Personally, I find all these minimalist, back-to-the-basics frameworks a bit misguided. It's always reeks a bit of "well my farts don't smell" – other developers' frameworks are bloated, dependency-overloaded and too complex. My new framework is simple, based on a powerful idea, and just right.
Imo, the best way to build a truly good web app in 2025 is to embrace both server-side rendering and client-side rendering, by sharing the same rendering logic between client and server, like e.g. SvelteKit, Next.js and others do.
They're all tools that need more context to decide on when you use them.
For example, in my use case (SaaS) I focus on something that makes refactoring a breeze. Type-safe end-to-end is important there, so I use orpc+react for most projects. If you don't like contract-first APIs you're going to hate this, but it makes me think out what I actually want in my frontend before I write the database. This kind of [mocking -> real data] way of coding makes you proactive when designing the app
> MESH is a fun project intending to demonstrate the kinds of concepts embodied by HTMX - without using HTMX. Specifically, we're rendering modular elements on the server, and hydrating them on the client, swapping them out as needed instead of reloading the whole page. Component updates are swapped in place. Out-of-band updates are sent to all connected clients via SSE (server-side events), meaning all users see updates in real time.
(To expand that for people not familiar with HTMX's out-of-band updates: Basically, in MESH, on the client you hook up something listening to updates sent from the server via SSE. What the server sends are basically snippets of HTML with an ID in them; the listener on the client replaces the HTML in the DOM with that ID with the HTML sent over the wire. This allows the server to arbitrarily update the client's UI.)
So it shares one of the mechanisms of HTMX, which is to do SSR with the ability to replace individual elements.
React is for fine grain components and HTMX is for lightweight interactivity — update part of a page.
The classic React use case is an editable, filterable drop down. The classic HTMX use case is click a button and load some text.
The overlap comes in the middle, with a simple form validation. React says make each field a component that handles its own validation and error messages. HTMX says just return a re-rendered form with the error messages. MESH says make the form a component with its own endpoint.
HTMX can do the same thing: you can do `hx-trigger="changed delay:500ms"`, and make an endpoint for that component that will do validation, update an error message status area (adding or removing an error as appropriate), and even potentially enable / disable the "submit" button.
It seems to me that the main difference in approach is whether the "source of truth" for the state of the page is on the client or the server. HTMX is designed to be flexible (which is one of TFA's complaints actually), but its primary vision is HATEOAS (Hypertext as the Engine of Application State); which to my understanding of reading HTMX's documentation, is meant to mean that everything important about the client state should be kept on the client; the server should be able to be entirely reactive. What I see skimming through MESH (and data-star.dev) is that the "source of truth" is on the server.
Not an authority in this area, so happy to be corrected on all those points. But I am in the middle of building a dynamic query form using HTMX, trying to design it with HATEOAS principles, so it is something fresh in my mind at any rate.
I'm of the opinion that this is the future of web development for numerous web frameworks should they invest in tech similar to Blazor. Phoenix's LiveView also comes to mind. I am hoping a brave soul builds something for Django (I've been meaning to try, but I have too many side projects going on atm) that is similar to Blazor.
Maybe but not with C#. Rust is a much better language for compiling to WASM. Leptos achieves something similar to Blazor with a fraction of the CPU and bytes.
https://leptos.dev/
Blazor is much slower client-side than even the worse JS solution. Scroll to the right to see it compares:
https://krausest.github.io/js-framework-benchmark/current.ht...
I would love to be able to handle all my web stack with C# but unfortunately the WASM bundles are too heavy for most use cases. Plus the DX for frontend is not even as good as it was with JS and Webpack like a decade ago. And these days the bar is much higher with Vite.
Same for on every WASM solution out there. I don't want to rewrite for the 1000th time a date picker, accordion, card, tab bar...
I just want to throw new Accordion() on my code and, optionally, override some CSS to make it match the customer palette and go solve hard problems.
This strikes me as a premature optimization. Most use cases? I'm interested if you have any examples.
> Rust is a much better language for compiling to WASM.
Why's that?
However Blazor just totally tanked the RPi that had 4gb of ram. It took minutes to load a web page when it did load.
Of course that was years ago. Hopefully Blazor got better. Given that starting point I’d doubt it’ll ever match Elixir LiveView in efficiency.
IMHO, other systems will to struggle to replicate Elixir’s LiveView due to BEAMs design using preemptive actors. It’s not impossible, just that’d it’d take a lot of work to match the responsiveness and resource usage.
Currently I’m using Nim on backend and front end using a Karax SPA. It’s pretty nice sharing the same code on front end and backend!
Sounds like Blazor Server, if WASM was used, that shouldn't have been the case. I'm not very surprised considering how insanely efficient the BEAM is with memory.
As the article says :
> HTMX leaves it up to the developer to impose discipline on their code, however they see fit.
He said that like it's a bad thing. I really dislike those frameworks like Angular for example who simply say "You need to do it the Angular way". That just slows down innovation or clever ideas that solve little problems. Instead if there is a slow framework (looking at some peoples react implementations, Cloudflare recently [0]) Well you probably wont consider it or just see it as a "quirk" of the framework.
[0] https://blog.cloudflare.com/deep-dive-into-cloudflares-sept-...
They have a pretty extensive history of encouraging everyone to get on the wagon only to drive it straight into the nearest ditch. You can't trust a company that competes with its own customers.
Silverlight was proprietary, Blazor is MIT licensed and using open web technologies that are NOT going anywhere any time soon. We just had another major upgrade to Web Assembly's spec not that long ago.
We moved into MVC approach, because of the headaches that it used to be having to debug all the generated stuff from what the browser actually supports as built-in technology.
I don't see that bright future for Blazor, other than a few .NET shops that don't want to learn native browser technology.
I've had more success with Phoenix/LiveView.
Though they did manage to really shave the runtime off somehow. It used to load megabytes and megabytes of data.
> numerous web frameworks should they invest in tech similar to Blazor. Phoenix's LiveView also comes to mind.
Phoenix live view sends minimal diffs that get applied to the DOM. It doesn't have "components that run in the client and on the server". Everything is done on the server, with very specific extension points into JS
I want to stay flexible, a completely independent frontend and a completely independent backend.
I tried Phoenix for about 7 months this year and ultimately quit due to it feeling clunky and unintuitive, same with Livewire or any other SSR templating solution I've found.
If there's SSR templating that is actually enjoyable to work with (from a DX perspective), I'd happily try it. Sadly nothing feels as good as just building web components.
https://data-star.dev/
https://github.com/bigskysoftware/fixi/blob/master/fixi.js
i created it as an experiment in minimalism:
https://github.com/bigskysoftware/fixi#-fixijs---it-aint-muc...