Hey, I created htmx and while I appreciate the publicity, I’m not a huge fan of these types of hyperbolic articles. There are lots of different ways to build web apps with their own strengths and weaknesses. I try to assess htmx’s strengths and weaknesses here:<p><a href="https://htmx.org/essays/when-to-use-hypermedia/" rel="nofollow">https://htmx.org/essays/when-to-use-hypermedia/</a><p>Also, please try unpoly:<p><a href="https://unpoly.com/" rel="nofollow">https://unpoly.com/</a><p>It’s another excellent hypermedia oriented library<p>Edit: the article is actually not nearly as unreasonable as I thought based on the just-f*king-use template. Still prefer a chill vibe for htmx though.
If you are comfortable building web apps like the early adopters did in 1999 that later got mainstreamed with Ruby-on-Rails and related frameworks, HTMX adds a wonderful bit of extra interactivity with great ease.<p>Want to make a dropdown that updates a enumerated field on a record? Easy.<p>Want to make a modal dialog when users create a new content item? Easy.<p>Want a search box with autocomplete? Easy.<p>As I see it the basic problem of RIA front ends is that a piece of data changed and you have to update the front end accordingly. The complexity of this problem ranges from:<p>(1) One piece of information is updated on the page (Easy)<p>(2) Multiple pieces of information are updated but it's a static situation where the back end knows what has to be updated (Easy, HTMX can update more than one element at a time)<p>(3) Multiple pieces of information but it's dynamic (think of a productivity or decision support application which has lots of panes which may or may not be visible, property sheets, etc -- hard)<p>You do need some adaptations on the back end to really enjoy HTMX, particularly you have to have some answer to the problem that a partial might be drawn as part of a full page or drawn individually [1] and while you're there you might as well have something that makes it easy to update N partials together.<p>[1] ... I guess you could have HTMX suck them all down when the page loads but I'd be worried about speed and people seeing incomplete states
HTMX Sucks<p><a href="https://htmx.org/essays/htmx-sucks/" rel="nofollow">https://htmx.org/essays/htmx-sucks/</a>
> No Jobs<p>> Another practical reason not to use htmx is that there are, rounding off, zero htmx jobs.<p>> I just did a search for htmx jobs on indeed and found a grand total of two: one at Microsoft and one at Oak Ridge National Laboratory.<p>> A search for “react”, on the other hand, gives 13,758 jobs.<p>> Seriously, developer, which of these two technologies do you want to hitch your career to?<p>I do not advocated for htmx; but this take is so bad!<p>Resume-driven development should not be a thing. If you are a professional developer, building a product for a user, your primary concern should not be the job market for when you quit the company you are working for, but rather making the best product possible for the user within the context of the current company. And if the product is such that it does not call for react, or some other javascript-rich client, then you shouldn't use it however many react jobs there may be on Indeed.
The evidence is so damning that htmx.org even opted to host it. That's not all- the author of the document is the one who developed HTMX!<p>(In all seriousness, this entire article is facetious and is highlighting the strengths of HTMX. They are not sincerely advocating for 'resume driven development'.)
The author of the article is the creator of htmx. There is some tongue in cheek here.
Right :-) That article did read as satire; but then, it is hard to tell what is satire anymore. I can hear people say the things he catalogues in the article; and I might agree with some of them, like the pollution of the window namespace, or the ancient syntax if this is indeed the case.
As I read, I thought, "I'm pretty sure I disagree with this guy" about once per paragraph. I didn't know. Thank you.
At this point, web design 'ecosystems' are essentially money whirlpools. They're complex, so they require programmers skilled in using them, who in turn make more sites which need more programmers, and so on, and the network effect takes over and cements this feedback loop in the structure of the jobs market.<p>And the frameworks are churned continuously and are also bug-ridden nightmares, so that continuous development and support is needed to keep websites functioning and secure.<p>Any reduction in framework complexity threatens the whole edifice.
I think the number of job postings is pretty related to factors that I do consider valid when selecting a piece of technology (eg: language, framework, etc):<p>- How easy is it to hire people with experience in this?<p>- Relatedly, how easy will it be for the org to maintain this software after I (or the original team) leaves?
> Resume-driven development should not be a thing.<p>Pretend this is not about library choice, but rather about language choice. One language has 2 jobs, and the other language 13k jobs. I doubt you'd think for more than a second.
> One language has 2 jobs, and the other language 13k jobs. I doubt you'd think for more than a second.<p>The Hacker News website runs on Lisp. How many jobs do you see on the market that ask for Lisp? And yet, for what it is, this site is amazing! I don't see them rushing to migrate to a python backend and a react-based frontend, no matter how many jobs there are for those.
This is all true. But then, if you ran HN and needed to hire new devs, you could find them extremely easily just by posting on your own site. HN is a well-known project that people would want to work on because it looks great on their resume and gives kudos when talking to other devs.<p>In other words, HN does not have the problem that you are going to have if you use an unpopular language for your project.<p>If you choose LISP for your not-HN project, then you have a problem. The chances are very slim of finding any experienced LISP devs who are also in your salary range, within commute distance, want to work on your project, are a good fit for the team, etc.<p>You're probably going to have to hire a dev who is a good match on all those other things and train them up on LISP. Unless they've had experience with other functional languages (not that unusual, but not common either) then they're going to have to learn an entire new paradigm. All of which means that they'll spend the first six months going slow while they learn, and needing support from the rest of the team.<p>And you'll need to convince them to join you (probably by paying them more money) because if they spend a few years on your project learning LISP, they probably won't be able to use those skills for their next gig, and their current skills in a popular language will go out of date.<p>LISP is a great language, and if used well it will probably give you an advantage over the competition using other, more mundane, languages. But is that going to be enough of an advantage to counteract your slower onboarding, higher salaries, and greater recruitment workload?
Not just Lisp, but Arc at that. That's about as niche as it gets.
I appreciate the idealism but I appreciate being able to pay my mortgage more.
so true
Everything in that resonated with me.
Damn, Unpoly looks great! Never tried HTMX but have been a fan of it, it solves a UX problem that frameworks like Django and Rails suffer from, without needing to bring in something heavy like React.<p>I'm currently working on a side project in Rails using Stimulus but sometimes I wonder if Stimulus is overkill with all of the controllers and stuff as well. Do you have an opinion on when you should reach for something like Inertia or Stimulus over htmx?
fwiw I'm the CEO of htmx, and I am a huge fan of these types of hyperbolic articles.
I love Unploy, the documentation as well, but I find it a bit too complex. For even simpler usecases I often use Alpine AJAX [1], which is an Alpine.js plugin giving your links and forms -- only, because progressive enhancement -- basic AJAX capabilities.<p>[1] <a href="https://alpine-ajax.js.org/" rel="nofollow">https://alpine-ajax.js.org/</a>
I first read about Unpoly in Stephan Schmidt's Radical Simplicity website[1], I liked it's value prop and decided to try it. I found it bit too complex just as you said. A long time later I came across htmx and decided to try it even after reading a side comment that the library was "like unpoly". 15 minutes later I had a simple to-do list running htmx ajax calls using php and mysqlite in the backend. It was so easy I could not believe such thing could exist. Then I decided to read the Hypermedia book and never stopped using htmx in my projects.<p>[1] <a href="https://www.radicalsimpli.city/" rel="nofollow">https://www.radicalsimpli.city/</a>
How does Unpoly and htmx differ?
unpoly is a more complete framework with concepts like layers and best in class progressive enhancement<p>htmx is lower level and focuses on generalizing the idea of hypermedia controls<p><a href="https://dl.acm.org/doi/abs/10.1145/3648188.3675127" rel="nofollow">https://dl.acm.org/doi/abs/10.1145/3648188.3675127</a>
LLMs know nothing about Unpoly, and quite a bit about htmx. This requires you to <i>actually learn</i> Unpoly, because, well, even pointing your LLM-of-choice at the Unpoly docs (which are quite okay!) makes it regress-to-the-ugly-Javascript-workarounds-mean pretty much on try #1.<p>I'm not yet sure whether this is a good thing or not -- I'll let you know once my latest iteration of my web framework is finally working as I envisioned, he-said sort-of-jokingly, which should be Soon Now.<p>But yeah, either alternative still beats React by a country mile, since everything related to <i>that</i> descends into madness <i>right away</i>.
I didn't find it too hyperbolic, I think they were very clear on where htmx can help, eg. the section "you're not building Google docs".
> Still prefer a chill vibe for htmx though.<p>Said the horse with laser eyes (¬_¬)
<a href="https://unpoly.com" rel="nofollow">https://unpoly.com</a> touts "progressive enhancement."<p>Third link on the page ("read the long story") points to <a href="https://triskweline.de/unpoly-rugb/" rel="nofollow">https://triskweline.de/unpoly-rugb/</a>, which renders as a blank page with NoScript enabled.<p>Sigh.
I haven't really tried htmx yet, but I used to love intercooler, and your essays are always a fun read. When I saw the title I thought it was some kind of joke from you, because it's like the opposite of your normal style.
here is the long-promised frontal assault on Big State: dataos.software
I'm curious if the author of the article is an HN reader, and if yes, how this comment is received.
You really need to shut this down dude. If HTMX becomes famous for having overbearing advocates that's a really bad look. Look at what happened with Rust.
"What happened to Rust" is that it got a lot of coverage for being good, then a few people were annoying about how good it is, and now a large number of other people have become annoying in their complaints about how annoying the first group was. Meanwhile, Rust & its community remain unaffected; adoption continues to grow, and Rust now used in the kernel, Windows, Android, AWS infra, etc.<p>The problem you've encountered is that people are annoying. I'm afraid that's not specific to any one technology or community. Fortunately, annoying blog posts are easily ignored and would never stop a useful tool from being adopted anyway.
Rust is doing great.
I am tired of people using the smallest "Hello World" example to demonstrate how something is better than React -- "See, you don't need all these things to get a website up and running!"<p>Of course it will work. I can vibe code the most terrible web framework you have seen within 20 minutes and claim it is better than React, but what does it prove?<p>> You write zero JavaScript
> The whole library is ~14kb gzipped<p>Oh sure, if there is nothing else in your UI, and if your Python/Go/whatever backend server has 0 dependency, which almost never happens.
To put a bit more colour on this, I think the fear of most devs with an ultra-simple framework like this is that eventually you hit a wall where you need it to do something it doesn't natively do, and because the only thing you know is these magical declarative hx-whatever attributes, there's no way forward.<p>I appreciate the basic demos, but I think what would really sell me is showing the extensibility story. Show me what it looks like when I need it to do something a bit beyond what it has in the box. Where do I add the JavaScript for that? Is it raw, inline, or are we back to packages and bundling and a build step? Am I building application JS, or some kind of extension or plugin to htmx itself? How chained am I going to be to its specific paradigms and opinions?<p>The page says htmx isn't for writing a true SPA like Google Docs, but where's the line? Show me an app that has pushed up against the limits of this system, and what happens in that scenario.
This is where I think Astro shines, with its "islands of interactivity" approach. Keep things as simple as reasonably possible, and provide an idiomatic, first-class mechanism for supporting more complexity where appropriate.
I overlooked Astro for a long time, I didn't really get it, and my journey back to it went something like this:<p>- 1 Getting burned out by Nextjs slowness in a complex production project that shouldn't be that complex or slow on the dev side, (this was 2022 approx)<p>- 2 Taking a break from React<p>- 3 Moving back to classic server side rendering with python and Go and dealing now with template engines. Hyped with HTMX and loving it, but my conclusion after so many years of react was that template partials don't feel right to me and templates engines are somewhat not maintained and evolved as used to be. I found my self not feeling naturally inclined to reach for the htmx way and just let the coding agent do it the way they wanted AND stating to notice again the burn out.<p>- 4 Looking with some envy to co-workers using shadcn how fast they are getting things done and how good they look.<p>- 5 Wondering would be a way to use JSX with HTMX server side, I miss components, I don't want partial templates.<p>And then I found Astro, ahhh now I get it, Astro prioritizes generation over run time, and that unlocks a lot of gradual complexity where you can choose how to mix things ( islands ) you get something way more interesting than a template engine, and it uses JSX so you can benefit from React ecosystem.<p>This where I am now, but yet I have to complete a side project with it to know if I fully get it and love it.<p>So far seems to me is the answer I was looking for.
This is what doesn't get discussed enough around htmx, in my opinion. So much of the difficult steps are left for the templating system, and template systems aren't great in general. You need to track a lot of identifiers for htmx to work properly, and your template and view logic needs to make that make sense. For the templating systems I've seen, that's not so simple to do.
1000% this. I actually am using htmx at ${JOB} and this is essentially the only downside to htmx. I want to know which template partial is getting swapped. My IDE doesn't know. I need to track countless html ids to know what will be swapped where... how? It hasn't been a big deal because I alone write the frontend code so I have all my hacks to navigate and my intimate knowledge of the code, but if we need more devs on the frontend, or if the frontend drastically grows feature wise, i will need to tackle this issue post haste. I think template partials could help, but then we also would end up with giant template files and that would also be annoying.
> 5 Wondering would be a way to use JSX with HTMX server side, I miss components, I don't want partial templates.<p>I'm playing with JSX, Hono, and Bun right now to do just that. It's early but will see how it goes.
Astro is great. If you are familiar with React, you can pick it up pretty much instantly. The design is simple enough to extend when needed as well for custom things.
Last time I dabbled in a front-end I tried out Astro but felt like it just added another layer of complexity without much gain when all my components were just wrapping React in different ways. I went with react router instead.<p>I can see the value of the "islands" concept when you have a huge front-end that's grown over generations of people working on it.<p>For my constrained front-end debugging Astro errors on top of React errors on top of whatever all the turtles down felt a like a step too far.<p>Am I in my Rust centered back-end driven brain missing something?
(Disclaimer: I haven't actually run into a case where I had to move from HTMX to a SPA framework, even partially, so this is largely an educated guess)<p>I think this scenario would either be very apparent early on in the project, or wouldn't actually be that challenging. There are a couple ways you could run into the limits of HTMX:<p>1. You require purely client side interactivity. The right (IMO) way to use HTMX is as a replacement for sending JSON over the wire and rendering it into HTML on the client, so if your app has features that _wouldn't_ be done that way, you should reach for something else. Fortunately there's lots of solutions to this problem. You can use built in browser features to achieve a lot of the basics now (e.g. the <details> tag means you don't really need custom scripts if you just want an accordion), write simple vanila scripts, or adopt light weight libraries like alpinejs or the creator of HTMX's (only slightly deranged) hyperscript.<p>2. Maybe your purely client side interactivity needs are complex enough that you <i>do</i> need a SPA framework. At that point you can adopt the islands architecture and create interactive components in your fraemwork of choice, but continue to use hypermedia to communicate with the backend.<p>3. If you can't easily separate client side state (handled with javascript, potentially with the aid of frameworks) from server state (handled on the server and sent to the client via hypermedia), you can again adopt the islands architecture and have your islands manage their own network requests to the backend.<p>4. If the above applies to <i>all</i> of your app, then hypermedia/HTMX is a bad fit. But this should generally be pretty obvious early on, because it's about the basic, fundamental nature of the app. You probably know you're building google docs when you start build google docs, not mid-way through.
multicards is almost purely client side interactivity. I STILL use htmx for a number of reasons:<p>- No JSON serialization: HTMX sends form data natively no JSON.stringify() needed
- Less JavaScript: Declarative hx-* attributes replace imperative fetch code. in my world declarative always wins.
- Automatic headers: HTMX handles X-User-Id and other headers configured globally
- Built-in error handling: hx-on::error instead of .catch() chains
- Swapping flexibility: Can show success/error feedback via hx-swap without custom JS
- Request indicators: Free loading states with hx-indicator
- Debugging: HTMX events visible in browser devtools; fetch requires console.log<p>and most all: performance. multicardz goes like stink. 100/100 lighthouse scores, First Contentful Paint 0.4 s, Largest Contentful Paint 0.5 s, Total Blocking Time 0 ms, Cumulative Layout Shift 0, Speed Index, 0.5 s<p>still prerelease, but cautiously hope to go general availability by and of year.
You won't keep those performance numbers if the network conditions are bad, unfortunately. For things that <i>require</i> a network round trip, that's fine, because doing it via JSON (or some other serialization format) won't save you anyway. On the other hand, if it can be done entirely on the client, adding network round trips will slow the interaction down. It sounds like you're mostly doing the former (otherwise loading indicators and serialization wouldn't matter), but it's a point that should still be emphasized.
I think you misunderstood me. I use htmx where most people would use fetch. I do not just use htmx willy nilly for no reason.<p>I use pure front end manipulation to set state, then I send the state to the stateless back end with pure functions, and I get amazing performance: www.multicardz.com public test bed, 1M records, round trip usually around 160 ms for anywhere between 1 to 100K hits
>Where do I add the JavaScript for that? Is it raw, inline, or are we back to packages and bundling and a build step?<p>That’s really your call to make. I’ve never went the full build step with it, but I’ve only built some internal dashboards and crud apps with it.
> To put a bit more colour on this, I think the fear of most devs with an ultra-simple framework like this is that eventually you hit a wall where you need it to do something it doesn't natively do, and because the only thing you know is these magical declarative hx-whatever attributes, there's no way forward.<p>I'm not sure "fear" is exactly the right word here, but it's something I consciously evaluate for when looking at any new framework or library. Anything that has a lot of "magic" or "by-convention" type config is subject to this.<p>You start with the "hello world" example, and then you hit that wall. The test of an awesome framework vs a fundamentally limited (or even broken) one is: can you build on what you have with extensions, or do you have to rewrite everything you did? There's a lot of these where as soon as you want to do something slightly custom, you can't use _any_ of the magic and have to redo everything in a different way.<p>This isn't just libraries either. Another almost worse example is AWS Elastic Beanstalk. Simple way to get an app up and going, and it handles a lot of the boilerplate stuff for you. The problem is as soon as you want to extend it slightly, like have another custom load balancer route, you actually have to completely abandon the entire thing and do _everything_ yourself.<p>This is a really hard thing to get right, but in my view is one of the things that contributes to a framework's longevity. If you hit that wall and can't get past it, the next project you do will be in something else. Once enough people start posting about their experiences hitting the wall, other people won't even pick it up and the framework dwindles to a niche audience or dies completely.
What I don’t get is why I’d use it if I can’t write a reasonable complex SPA with it.<p>React is easy for small websites so why would I use a separate framework when I can use one framework for everything?
What's your decision tree for when you feel you need a SPA in 2025?<p>At least some of what you may not be getting in this space is how many developers right now seem to be hugely deprioritizing or just dropping SPA from their decision trees lately. Recent advances in CSS and ESM and Web Components such as View Transitions and vanilla/small-framework JS (ESM) tree-shaking/"unbundling"/importmaps give MPAs more of the benefits of a complex SPA with fewer of the downsides (less of a "mandatory" build process, smaller initial bundle load). It is easy to feel less of a need for "complex SPA" to be on your architecture options board.
I recently tried a hello-world in react. It made ten network requests on page load and probably had a sizable first download. That’s why web <i>pages</i> are so slow today.
> What I don’t get is why I’d use it if I can’t write a reasonable complex SPA with it.<p>Because most webpages don't need to be SPAs.
I miss the days of jquery and html+css, where everything was snappy, and wasn't an SPA.
For what it's worth. Our intranet apps run on a combination of Python + HTMX. We haven't run in to anything we couldn't do yet. The paradigm of swapping parts of the DOM in and out is very easy to work with.
There's also the opposite camp: when you show very complex scenarios being simple in some technology but the hello world is harder.<p>e.g. effect-ts which makes error handling, dependency injection, concurrency, retries, stack safety, interruptions, etc, simple but the hello world already hits people with "wait, it's 6 lines of code to print hello world!? Trash".
Check out Fizzy from 37signals. They used a similar HATEOAS approach to build it with Hotwire<p><a href="https://www.fizzy.do" rel="nofollow">https://www.fizzy.do</a><p>source: <a href="https://github.com/basecamp/fizzy" rel="nofollow">https://github.com/basecamp/fizzy</a><p>I don't think this is a better approach than React. It's just <i>an</i> approach. It's viable. It's fine
Here's a real-time-ish planning poker written in Go + Htmx in ~500 LoC<p>App (can take a few seconds to spin up if dormant): <a href="https://estimate.work/" rel="nofollow">https://estimate.work/</a><p>Source: <a href="https://github.com/weiliddat/estimate-work" rel="nofollow">https://github.com/weiliddat/estimate-work</a>
DecisionMe is one the apps I created using htmx. I am not the owner of the company, so I cannot comp you, but I can promise in good faith: this is not a toy app.
In fairness, the article has a section titled “The Numbers” which links to this: <a href="https://htmx.org/essays/a-real-world-react-to-htmx-port/" rel="nofollow">https://htmx.org/essays/a-real-world-react-to-htmx-port/</a>
Different teams/projects have different needs and require different solutions. While it's good it worked in their favor, I am quite confident that someone else can tell a completely different story. In fact, there are some comments in this very HN discussion that detail their negative experience with htmx. I would not use one or the other to "convince" anybody to go with either solution like what this article attempts to do.
Right, it's also bothered me that the Vue docs spend so much time showing how it's a "progressive" framework. "Just use it for one component!" And show examples of how it can be lazy loaded in for your special complex spot that needs vue.<p>Like c'mon, if I'm using Vue, I'm using Vue. Same for React. Strap me into the native state management solution for your framework, your router, your preconfigured bundler. I'm not here to mess about or I'd have just stuck with vanilla.
I did.<p>My startup did.<p>And now we’re going to rip it all out and move to a React front-end.<p>HTMX makes response handling much more complex. Every endpoint returns 3–5 different HTML fragments. Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.<p>And HTMX is still a fairly obscure library. The documentation and examples are lacking, there isn’t a real set of established best practices at scale, and not for nothing, LLMs aren’t great at it.<p>React is mature, used at scale, provides separation of concerns, and is great for agentic AI coding. HTMX has its place for simple projects, but for anything non-trivial, it’s a no for me.
I was able to find architectural patters that work smooth as glass.<p>Here is what my htmx apps have:
- Single-purpose endpoints: Each endpoint returns ONE thing (a card list, a tag cloud, a form fragment)
- Optimistic UI: Preferences like font/theme update the DOM immediately; the save is fire-and-forget with no response needed
- Simple error handling: Most endpoints either succeed (return HTML) or fail (HTTP error code)
- No fragment orchestration: Not returning 3-5 fragments; using hx-swap-oob sparingly<p>Here is how I update fonts on screen in user prefs:
User selects font → JS updates body class immediately → htmx.ajax() saves in background → done<p>vs. the anti-pattern you're describing:<p>User submits form → backend validates → returns success fragment OR error fragment OR partial update OR redirect signal → frontend must handle all cases<p>No language or programming paradigm is perfect. All programming is an exercise in tradeoffs. The mark of a good CTO or architect is that ability to draw out the best of the technology selection and minimize the tradeoffs.
Please do a write up of the best practices you've found. I tried htmx a few years ago for a side project and while I appreciated the simplicity of a lot of it, I had trouble understanding how/when to use it and in what ways. I think I was trying to contort it too much into my understanding of api/spa. That or my interactivity needs were too complex for it, I can't tell.<p>These days, I admit, though, the ship has sailed for me and htmx. My main app frontend is React and since the LLMs all know much more than I do about how to build out UIs and are 100x faster than me, I'll probably be sticking with React.
I have never loved the idea of the server rendering HTML which is probably why I have such a hard time with HTMX. In every other paradigm you clearly separate your server API and UI rendering/logic. Web apps are the only place where it seems common to have the server render UI components. Imagine if you had a Java or Swift application and had the server sending your phone UI screens. I don’t even know how you would pitch that. About the only thing I have seen that makes some sort of sense here is video game rendering to be able to play on really limited devices with quick internet access.<p>The problem with SPAs is the ecosystem. I recently found packages like this [1] and this [2] in my node_modules and that is insanity. But the architecture honestly makes way more sense than any other paradigm: server side is a well defined API and the client renders UI and handles local state.<p>[1] <a href="https://www.npmjs.com/package/isarray" rel="nofollow">https://www.npmjs.com/package/isarray</a><p>[2] <a href="https://www.npmjs.com/package/is-string" rel="nofollow">https://www.npmjs.com/package/is-string</a>
How do you handle HTTP errors?<p>Just curious because when I used HTMX I didn't enjoy this part.
I like to return errors as text/plain and I have a global event handler for failed requests that throws up a dialog element. That takes care of most things.<p>Where appropriate, I use an extension that introduces hx-target-error and hx-swap-error, so I can put the message into an element. You can even use the CSS :empty selector to animate the error message as it appears and disappears.<p>Usually the default behavior, keeping the form as-is, is what you want, so users don’t lose their input and can just retry.
Honestly? I never think about it. I've never had to.
What did you run into? Curious what the pain point was.
I had a site where the user can upload a file < 5MB. There may be a way to check this on the frontend, but for security reasons, it has to be checked on the backend too.<p>If it exceeds it, I returned 400. I had to add an event listener to check for the code (htmx:afterRequest) and show an alert(), but this gets difficult to manage if there's multiple requests to different endpoints on the page. Looking at it now, maybe I should have configured HTMX to swap for 4xx.
I have something similar on my website, and my solution was to make server driven modal/toast responses.<p>Allow the server to return a modal/toast in the response and, in your frontend, create a "global" listener that listens to `htmx:afterRequest` and check if the response contains a modal/toast. If it does, show the modal/toast. (or, if you want to keep it simple, show the content in an alert just like you already do)<p>This way you create a generic solution that you can also reuse for other endpoints too, instead of requiring to create a custom event listener on the client for each endpoint that may require special handling.<p>If you are on htmx's Discord server, I talked more about it on this message: <a href="https://discord.com/channels/725789699527933952/909436816388669530/1239414033065443482" rel="nofollow">https://discord.com/channels/725789699527933952/909436816388...</a><p>At the time I used headers to indicate if the body should be processed as a trigger, due to nginx header size limits and header compression limitations. Nowadays what I would do is serialize the toast/modal as a JSON inside the HTML response itself then, on `htmx:afterRequest`, parse any modals/toasts on the response and display them to the user.
> Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.<p>Well, frontend and backend always need to agree on every scenario, that's why I prefer to do validation on backedn and frontend to just display it and not do any validation.
That makes for some nasty debugging and unsafety. Both sides should parse both times, unless you're encountering real (not imaginary) performance issues.<p>As someone who's been parsing everything entering the system from 2018, I don't believe you can have performance issues by parsing the data entering the system, the only exception I can name in a decade was real time trading app where the data coming in all time was just gargantuan that parsing it all the time was impacting UX and even then there should be an argument for the backend insisting on sending whole data instead of the latest value.
Frontend and backend will always diverge and 90% of your bugs will be around that. Mitigating the divergence is the primary goal of every web framework, both backend and frontend, when you sit back and think about it.
Real world examples with error handling would be great for HTMX. Now in the LLM era you might get away without those. I just don't understand why can't we have complete documentation for the most basic scenarios.
I found the book (hyper media systems) to be better at explaining full integration than the library site, which gives nuts and bolts and big picture, but not much intermediate info.
So first you choose a nicher solution you didn't fully understand and now you jump into another one (full of issues but popular) you likely don't understand the trade offs too?
> and is great for agentic AI coding.<p>Definitely sad to see this everywhere nowadays, tech choices made because of AI
Just to be completely clear... you do not need React just so you can turn JSON into HTML. HTMX can 100% can do that.<p>You're argument is fine assuming you wish to become another react frontend in a sea of react frontends.<p>But the documentation example is a terrible argument, the benefit of HTMX is it is easy to understand what is actually happening. There is no magic, you don't need to dive through millions of lines of code to figure out what this is doing like react. It's very basic javascript. Just read the library, frankly you don't even need any documentation. Just take 15 mins and read the entire library.
> Frontend and backend must agree on every scenario<p>When is this not the case?
I suspect the hidden assumption here is that frontend and backend are written by different people/teams with a narrow interface between them. Because they use different technologies and build tools it’s easy for them to end up being competely siloed, which IMO is one of the worst aspects of how webdev evolved in the last 20 years.<p>Thus, it’s considered normal that the backend team spits out some JSON and doesn’t know or care what the frontend team does with it.<p>With HTMX that distinction doesn’t exist so much (the frontend consists of fragments generated by the backend) so you will need a different organizational approach. The “frontend” folks will need to write a lot of “backend” code, but presumably in a separable layer.
When an API returns JSON, your JS framework can decide what to do with it. If its returning HTML that's intended to go in a particular place on a page, the front-end has far less flexibility and pretty much has to put it in a specific place. Hence why they said endpoints can return 3-5 different versions of HTML.
"framework can decide what to do with it" sounds like a feature (more flexibility) but is actually often the source of errors and bugs.<p>A single, consistent, canonical response, generated by the server, taking into account all relevant state (which is stored on the server) is much cleaner. It's deterministic and therefore much more testable, predictable and easier to debug.<p>For pure UI-only logic (light/dark mode, etc) sure you can handle that entirely client-side, but my comment above applies to anything that reads or writes persistent data.
> When an API returns JSON, your JS framework can decide what to do with it.<p>The JS framework is the frontend, so you're still coordinating.<p>> If its returning HTML that's intended to go in a particular place on a page, the front-end has far less flexibility and pretty much has to put it in a specific place.<p>Well yes, because presumably that's what the app is supposed to do. If it's not supposed to put it in that place, why would that be the specified target?<p>If this kind of static assignment of targets is not flexible enough for some reason, then use OOB updates which lets you replace fragments by id attribute. That lets you decouple some of these kinds of decisions.<p>Although "endpoints can return 3-5 different versions of HTML" is also a bit of a red flag that you're not using htmx correctly, generally endpoints should be returning 1, maybe 2 fragments in unusual cases.<p>In any case, you might find DataStar more to your liking, it's partway between React and htmx.
To clarify, there's nothing React or SPA about datastar. Moreover, HTMX v4 is essentially Datastar-lite (but heavier, and less capable)
There is, Datastar has expressive client-side rendering based on signals [1]. Datastar is also very explicitly designed to be modular and extensible, so you can extend the client-side with more features, as they've done with Web Components.<p>[1] <a href="https://data-star.dev/guide/reactive_signals" rel="nofollow">https://data-star.dev/guide/reactive_signals</a>
It's terrible, why would I want my endpoints to return random HTML fragments? I realize thats how you did it in the JQuery times, but I was never in those - at that time we simply had template engines in the backend so this HTML slop wouldn't contaminate everywhere..<p>Most of the frontend stuff I do is for internal pages on embedded devices, and I'm very happy with a structure where I have the frontend being a full React fancy component lib SPA that is eventually just compiled down to a zip bundle of files that the backend needs to know nothing about and can serve as dumb files. The backend is a JSON API of sorts that I would need to build anyway for other use cases.
Returning HTML sounds like a styling nightmare, if anyone changes the structure, unintended consequences. Plus it’s difficult to reason possible states of the UI with fragments sitting on the server, possibly dynamically built on the server. Very jquery/PHP ish. I had my fun and don’t want to go back.
To "get" HTMX, you have to think server-first. State is persisted on the server and all state-change logic is performed on the server (often triggered by http requests from a "dumb" client).<p>If you hang on to "possible states of the UI" that are client-side only then yes you'll have some difficulty implementing server-generated HTMX responses but more importantly, when your client has state that sometimes isn't in sync with, or shared with, or validated by your server, you're setting yourself up for errors and bugs that will exist regardless of framework.<p>In short, HTMX forces you to apply "single source of truth" concepts to your application.
Clearly you haven't used something like HTMX. Do you understand what "returning HTML by the server" mean? You are basically sending back a view, like you would in any other framework actually. This would be the exact same pattern as displaying or dynamically adding a new component from either React or Vue. It doesn't create any styling issue at all, nor any unintended consequences.
I’ve used jquery which is very heavy into html fragments. It can get unwieldy compared to keeping all your rending logic in one place and applying data to it like in React. Other comments here validate the suspicion that HTMX can fall apart in large systems.<p>Unless you’re saying the components returned by HTMX are using the shadow dom for isolation, you can very easily run into styling problems by changing a style and not realizing some injected fragment of HTML somewhere relies on it being a certain way. I hope you’re using a monorepo because unlike typescript APIs, those HTML fragments and CSS styles are not type checked.
That's because jquery takes a very global approach to the DOM, which will naturally lead to spaghetti code.<p>Every backend framework, be it dotnet or Symphony or Rails, has a concept of components. It's a non-issue.
Well yeah, HTMX wouldn't be a good fit for micro-frontends, but I didn't think many people were actually using those. You have to write all your html in accordance with a single stylesheet, but that strikes me as the least of HTMX's impositions.
The HTML fragments aren't random.
> It's terrible, why would I want my endpoints to return random HTML fragments?<p>What would you return instead? It's easy to generate HTML, because that's what your server is already generating (and that's about all it should generate).
HTML is the last thing I would ever want to generate on my embedded device, it's a terribly verbose string-based mess invariably coupled with stylistic choices. Which is why my servers don't generate any of that, they <i>serve</i> static files - and any interactive information in something that looks a lot more like an interface definition.
I don’t get what you’re saying (maybe there’s a typo). With React, generating HTML on the embedded device is exactly what you’re doing — twice (virtual and real DOM).
Okay, so what do you your servers actually serve stuff to?<p>I kind of don't get why if you want to display something in a web browser you'd generate anything other than HTML.
I think the parent's point is that when you have a react front-end, your back-end basically just deals in structs of data. There's no HTML or templating to think about. It's just JSON-serialisable structs. That makes the code on the back end much simpler, which makes it easier to run in a resource-constrained environment.<p>The only exposure the back-end has to HTML is streaming the static files to the browser. Which can be done in small chunks.<p>If your back-end is rendering HTML with every request, it has to do a lot more work. It has to load HTML templates into memory and insert strings into them.
> It has to load HTML templates into memory and insert strings into them.<p>In practice, I doubt this is much slower than serializing JSON. Keeping a couple kilobytes of HTML templates in memory is nothing. Conversely, running a whole vdom on the frontend (typically more resource-constrained than the server) is a much bigger performance issue.
Three levels down and people have entirely forgotten what my post was. My "server" is some anemic ARM core built into real physical hardware with 64M of read-only storage. I don't want it spending its time "hydrating" some DOM, I don't want to bring any of this frontend insanity on there at all. No code hosted on npm shall ever run on that processor or I can't go to sleep in peace.<p>So how do we still get a fancy SPA website? Build it all down to a simple zip bundle, the ARM can serve those static files just fine. The SPA talks to the ARM via a few JSON APIs. Very nice clean boundary.
My understanding is that HTML templating is often cheaper server-side than JSON serialization.
Yes, if your server is a weak, limited processor, you want to keep the demands on it as low and lean as possible, and let the client do the heavy lifting. HTMX is not a good fit for this scenario, just like PostgreSQL is not a good database to embed on your devices.<p>This isn't a controversial idea and nobody would try to sell you on HTMX for your use case.
1. No, templating strings is actually quite cheap. I'm doubtful that you could benchmark any substantial difference between templating html and serializing json.<p>2. Who has a server with a weak, limited processor? HTML templates power Django, Rails, and PHP. This paradigm worked fine on the servers of 20 years ago, in the slowest languages we use. I could serve a Django app on my phone and see reasonable performance.
Okay, so how do you actually show the stuff to the end user?<p>Just raw structs of data? Or do you turn that back into HTML?<p>Now you've got two sets of templates to cope with...<p>Why would I care about how much effort it is for the server to generate? It's already generating HTML from templates, and it's more-or-less infinitely capable of doing so.
This is plain false.
> Every endpoint returns 3–5 different HTML fragments. Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.<p>And why would that differ from React?<p>When I was building a website with React, I needed to model a "apply coupon" endpoint with different states (coupon applied, coupon does not exist, coupon exists but has reached its max usage limit) and it was <i>so annoying</i> because you needed to<p>1. The backend route that returns JSON with a different model depending on the coupon state<p>2. The JSON models for each response type<p>3. And then on the frontend you need to load the data, parse the JSON, figure out which "response state" it is (http status code? having a "type" field on the JSON?) convert the JSON to HTML and then display it to the user<p>In my experience it added a lot of extra "mental overhead". It is something that should be extremely simple that ends up being unnecessarily complex, especially when you need to do that for any new feature you want to add.<p>When using htmx, a simple implementation of that would be<p>1. A backend route that returns HTML depending on the coupon state<p>2. Some htmx attributes (hx-post, hx-swap) on the frontend to make the magic happen<p>Don't get me wrong, there are places that you wouldn't want to use htmx (heavily interactive components) but that's why htmx recommends the "islands of interactivity" pattern. This way you can make the boring things that would add unnecessary complexity when using React with htmx, and then you can spend the unused "mental overhead" with the interactive components. (which, IMO, makes it a more enjoyable experience)<p>At the end of the day it is just choices: Some people may prefer the React approach, some people may prefer the htmx approach. All of them have their own upsides and downsides and there isn't a <i>real</i> answer to which is better.<p>But for my use case, htmx (truth to be told: I use my own custom library that's heavily inspired by htmx on my website, but everything that I did could be done with htmx + some htmx extensions) worked wonderfully for me, and I don't plan on "ripping it all out" anytime soon.
I always thought the GWT->react branch of the webdev family tree was an inbred, unecessarily cumbersome compromise bred from JavaScript and performance metrics rather than descending from the beautiful code family we used to have with Rails and Django.<p>The only reason react seems to look beautiful is because it's compared to custom JavaScript state management rather than the server-state paradigm that probably makes most sense for over 90% of apps.<p>The only real place it makes sense is when you're Google or Facebook and those 15 milliseconds actually translate to quantifiable lost user attention.<p>If your app is actually useful and not just an attention farm, those 15ms are almost never worth your engineering team's sanity.
The thing is React is usually fine, and even if you don't have to build _this_ thing in React due to simplicity, why bother learning two paradigms when you can just use the heavier one for everything and most likely never encounter any real practical showstopping issue?
> why bother learning two paradigms<p>Objection. Your React is ultimately turning into HTML so you DO have to learn HTML + CSS. You just have an abstraction over it.
That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.<p>Yet I know roughly what it is, but I couldn't begin to actually write the stuff myself.<p>Good abstractions mean you don't have to worry about the layer below.<p>Now of course it's not really the case that React holds up to being a good abstraction, especially when it comes to CSS and styling, but I don't think it's a forgone conclusion that abstractions force you to learn the level below.<p>Otherwise we'd all spend half our time learning assembly.<p>I do have sympathy though for a developer who just wants to focus on the higher level paradigm and let the library maintainers worry about the innards.
React is an abstraction over UI state, not the platform (ie HTML/CSS). This is by design and non-parallel to C#/CLR case. If you want something akin to this, then Flutter is what you should be looking at.
> That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.<p>For a good part of your career this is true, but eventually you will need to justify your senior salary by being able to debug react via looking at library code itself, or understanding the event bubbling under the hood, or figure out why the output css isn't working.<p>Saw a video, wish I could remember who, someone developing a game in c-something. There was some bug they couldn't figure out so they jumped into I guess the assembly for that block of higher abstracted code, and was able to find some kind of memory issue. Vague, sorry, but point is I remember being really impressed, thinking oh shit yeah if I really want to be an expert in my field I better be able to really understand my stack all the way to the bones.
> That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.<p>That's not a valid analogy, 99.99% of C# developers never see or touch CLR bytecode, where every React developer is still working with HTML+CSS.
That's possibly true, but I wonder why react as an abstraction fails to deliver that kind of independence.<p>In theory, react developers ought to be able to code against the react API in typescript, without seeing the "raw" HTML+JS that gets delivered to the browser.<p>So what's failing those developers? Is it the tooling, the abstraction itself, or something else?
> So what's failing<p>You're failing to understand the difference between react and react-dom.<p>> be able to code against the react API in typescript<p><a href="https://github.com/chentsulin/awesome-react-renderer" rel="nofollow">https://github.com/chentsulin/awesome-react-renderer</a>
Off the top of my head, C# is both the language & the runtime. React only throws things over the fence to browsers.<p>Probably helps a lot to keep abstractions from leaking.
That seems like an odd take. I don’t know that anyone ever intended React to completely insulate you from the actual UI framework (HTML/CSS in this case). You’d have to reinvent a whole new set of layout and styling features. Why would you bother? React is for orchestrating your use of the UI framework, not for replacing it.
That just makes HTML/CSS part of the React paradigm though. You can still use all those features in a React app, after all. The 'new paradigm' to learn with HTMX is how it does reactivity/interactivity.
honestly both the react haters & the htmx haters are wrong on this<p>if you care about have a solid UI, you should learn everything<p>you should learn css, react, svelte, vue, rails, tailwind, html<p>if you don't and you say you actually care about your UI, your opinion is actually irrelevant
The reality of React is that you have to keep re-learning and un-learning stuff if you want to keep up with React's ecosystem, because the surface area of the libraries is so large. (see "JavaScript fatigue")<p>Whereas with HTMX you learn a very, very basic concept in 15mins, and you're good to go for the next decade(s), and it will be more than enough for 80% of your projects.<p>Same as with vim and Emacs vs. proprietary IDEs and text editors.
React (and Angular) is an MVC framework pushed on top of a MVC framework in the backend. Why make things so complex?
> you can just use the heavier one for everything<p>Because people don't like using heavyweight solutions needlessly. That's the logic that begat C++ and Ada and Multics and ASN.1 and CORBA. All of which were good solutions useful for "everything" in their domain. But people hate them, mostly.<p>Historically big "everything" solutuions end up losing in the market to lighter weight paradigms with more agility and flexibility. Almost every time. React[1] <i>was</i> such a solution once!<p>[1] Which really is a shorthand for "modern node-based web development with tens of thousands of npm dependencies and thirteen separately-documented API and deployment environemnts to learn".
The thing is most of us have jobs where we can't unilaterally switch to the 'cooler' solution, and I value my own context-switching overhead much more than I value a slightly smaller bundle or dep tree. I'll much sooner optimize the former than the latter and so the general purpose solution that will solve both my own projects and the work ones typically wins.
> most of us have jobs where we can't unilaterally switch to the 'cooler' solution<p>Which is exactly why the uncool solutions persist in the market. They're useful and practical! If they weren't they never would have been successful at all. I'm just saying that that this is fundamentally the logic of the frumpy old curmudgeon, and the kids will always have something better to offer along with their confusing new ideas.<p>And to be clear, I'm also just saying that as someone looking in from the outside (I do firmware!) the front end webdev developer onboarding story has <i>long</i> since jumped the complexity shark and things are quite frankly an impenetrable disaster ripe for disruption.
Performance
Not HTMX but Alpine.js has been a complete revelation to me. What clicked for me was that you're enhancing server-rendered HTML, not replacing it. Need a dropdown menu? Add x-data="{ open: false }" and you're done. Want to show/hide elements? x-show does exactly what you expect etc.<p>No bundler required, no compilation step.
Alpine even has a plugin to perform the same function as Htmx if you need it<p><a href="https://alpine-ajax.js.org/" rel="nofollow">https://alpine-ajax.js.org/</a>
Same here, using Alpine.js is a breeze and it made working on frontend fun again, everything is so easy and intuitive to implement and manage, even on large projects. It's definitiely my favourite frontend framework right now and a default for new projects.
I worked on a large commercial AlpineJS app and grew to really, really hate it. It's great for smallish projects where the limits of the tool are known, but it is in no way a drop-in replacement for something like React (and I am no fan of React). People like to throw around how easy it is to do basic things, but building a real app using Alpine is an absolute nightmare.<p>Alpine data objects can grow to be quite large, so you wind up inlining hundreds of lines of JS as strings within your HTML template, which often limits your editor's ability to do JS checks without additional config.<p>State management in Alpine is implicit and nested and not a serious solution for building commercial apps IMO.<p>And don't even get me started on unsafe-eval.<p>If it's your hobby app and you are the developer and the product owner, go for Alpine. If you're working at a company that is asking you to build a competitive web product in 2025, use a more robust tool. Hotwire and Stimulus has scaled much better from an organization standpoint in my experience.
Have you tried the CSP build of AlpineJS? It takes the code out of the template into a proper JS file, no unsafe-eval. Isn't state management mostly handled on the backend when you use AlpineJS?
On the contrary, I've built some very complicated apps with Alpine and it handled the use cases every time. You are right with string methods creating it hard to click to go to the function in your IDE, but I'vd never had a problem with state management. Perhaps it depends on the setup.
Declarative is the way.
I've used HTMX on a personal project of mine. Other than HTMX itself, it used Go templates + Tailwind for CSS. As a backend dev with almost no professional frontend experience, I was able to replicate a fairly large and feature rich React app (which I was inspired by) using htmx in a matter of weeks in free time.<p>The main problem for me was storing/passing state between too many fragments. At some point some pages can become too complex to be manageable by HTMX, unfortunately. Lots of little fragments depending on each other, I began struggling to maintain a clear mental map of what was going on.<p>I'd say if React is more like functional programming, HTMX sometimes feels like GOTO programming.
Ultimately the complexity does have to live somewhere.<p>The idea that HTMX removes all the complexity is false. However it does remove some of it, and moves the rest onto the backend.<p>I find the backend easier to work with, so that's a win for me.<p>And a batteries included framework (like Laravel or Django) makes HTMX even more appealing. They already have everything you need! :)
The proselyting over frameworks is the worst bit of the web ecosystem.<p>If your solution is actually good, it will get adopted eventually...<p>Forget React, there's still stuff written in jQuery and JSP.<p>Why the rush to convert everything - you're not a missionary on a mission, just build your stuff in stuff you like?<p>The attack on npm is ridiculous, when (apart from introducing a permanent vulnerability in the form of a runtime dependency on a third party site), you still need npm for htmx.
You definitely don't need npm for htmx, it's one file with no dependencies.
For all of the esoteric talk about hypermedia and things like this, this is the greatest advantage of HTMX, why I use and, and also why GP is dead wrong.
> If your solution is actually good, it will get adopted eventually...<p>This has never been more incorrect. The entire world of software is people using garbage solutions because the CTO is convinced Oracle/Microsoft/what ever new random software is the best thing since sliced bread. In no fashion has the best software solution ever been a factor.
> If your solution is actually good, it will get adopted eventually...<p>I wish this were true.<p>Unfortunately, often the things that get adopted are the things hyped up the most, not the ones which are technically superior.<p>Popularity, marketing budgets and inertia often dictate what's popular.<p>As with all biases, we need to actively and deliberately work against these forces, if we value craftsmanship and professionalism.
Man I did try htmx, and I was hopeful, right until I saw how it polluted my codebase. I can't say I have the answers, but writing a pure Go app, I'm currently using one giant css file, custom styling and inline html.<p>And now I'm at the breaking point. So I'm planning to move to tailwind and Go templates, but honestly, i was hopeful for htmx, so I need to properly see the usecase. Which i don't know is this. It reminds me of Angular a lot...
This is the thing. Htmx is great if you only consider the frontend. But it does require fixing up the backed to match. A framework like that needs to integrate the front & back ends fairly tightly to have good UX. You may be interested in Datastar which does this better IMHO<p><a href="https://data-star.dev/" rel="nofollow">https://data-star.dev/</a>
My current plan is to switch to Datastar too, although the devs seem a little odd. The guys writing HTMX seem like a more professional bunch.
Thanks I'll look into it, but on first glance I feel like I just got space blasted by the website! What happened to simple websites eh
I assume youre referring to the "starfield" on the home page. That's just showcasing their "Rocket" webcomponents tool, which makes it vastly simpler to make WCs.<p>It is otherwise a very simple website, and the framework and its SDKs are much simpler, yet more powerful, than HTMX
Lol, it's ... a feature ... I think
Turbo with a small sprinkling of stimulus may be closer to what you are hoping for - turbo especially is a lot more opinionated than htmx.
> it polluted my codebase<p>HTMX is less noisy if you integrate it into your backend framework.<p>A contact of mine build a python/flask app. To simplify coding, he wrote a file to extend the flask framework to support the HTMX patterns he needed with just a single line of boilerplate. Took him about a day, his team is happy with the results.
> polluted my codebase<p>I'd love to hear more about that.
Well listen, we have two modes of operation. It's either html/js/css in the classic sense, or Go templating with some tailwind and JQuery (or whatever the kids are calling it these days). In the case of react, something totally different. But essentially when you try to go that middle path with something that defines its own syntax, it starts to bleed into everything. It's not self contained. I'd argue maybe tailwind is like that as well, so you want to put it in templates or something. But if your htmx code lives in your actual code the way it does with Go a lot of the times because they promote building these partial functions, it looks horrible, very hard to reason or manage. I'm not talking one or two snippets, I'm talking when you have a full blown web app.<p>The reality is it's going to suit some people and some languages really well and others not so well. I think I like html/css/js and using AI to generate that. But I also like Go templates and trying to isolate that in a programmatic way. I find htmx in principle, a good idea, but when I actually tried to use it, fundamentally the wrong tool for me.
> After the user downloads 2MB of JavaScript, waits for it to parse, waits for it to execute, waits for it to hydrate, waits for it to fetch data, waits for it to render... yes, then subsequent navigations feel snappy. Congratulations.<p>In my experience, a lot of SPAs transfer more data than the front-end actually needs. One team I worked on was sending 4MB over the wire to render 14kb of actual HTML. (No, there wasn't some processing happening on the front-end that needed the extra data.) And that was using graphql, some dev just plunked all the fields in the graphql query instead of the ones actually needed. I've seen that pattern a lot, although in some cases it's been to my benefit, like finding more details on a tracking website than the UI presented.
even for "downloads 2MB of JavaScript", it is often simply because the site is badly written (e.g. not careful about managing dependency), not necessarily because "JAVASCRIPT BAD".<p>Just look at the source code of amazon.com. It's a mess. But I bet it is more of an organizational problem than a tech stack problem, for a website worked on by literally hundreds of teams (if not more) where everyone crams their little feature in the website home page
> it is often simply because the site is badly written<p>I find that some techs tend to cause badly written code. I have junior coworkers that can write clear Python after a short intro, but can't write clean R after a year using it daily. I don't know if it is caused by the philosophy behind the language, the community, the tutorials and docs...
I’ve been a fan of this philosophy since the Intercooler.js days. In fact, our legacy customer portal at bomquote.com still runs on Intercooler. I spent the last year building a new version using the "modern" version of that stack: Flask, HTMX, Alpine, and Tailwind.<p>However, I’ve recently made the difficult decision to rewrite the frontend in React (specifically React/TS, TanStack Query, Orval, and Shadcn). In a perfect world, I'd rewrite the python backend in go, but I have to table that idea for now.<p>The reason? The "LLM tax." While HTMX is a joy for manual development, my experience the last year is that LLMs struggle with the "glue" required for complex UI items in HTMX/Alpine. Conversely, the training data for React is so massive and the patterns so standardized that the AI productivity gains are impossible to ignore.<p>Recently, I used Go/React for a microservice that actually has turned into similarly complex scale as the python/htxm app I focused on most of the year, and it was so much more productive than python/htmx. In a month of work I got done what took me about 4-5 months in python/htmx. I assume because the typing with go and also LLM could generate perfectly typed hooks from my OpenAPI spec via Orval and build out Shadcn components without hallucinating.<p>I still love the HTMX philosophy for its simplicity, but in 2024/2025, I’ve found that I’m more productive choosing the stack that the AI "understands" best. For new projects, Go/React will now my default. If I have to write something myself again (God, I hope not) I may use htmx.
This got me thinking: I am not about to fight windmills and the future will unfold as it will, but I think the idea of "LLM as a compiler of ideas to high-level languages" can turn out to be quite dangerous. It is one thing to rely on and not to be able to understand the assembly output of a deterministic compiler of a C++ program. It is quite another to rely on but not fully understand (whether due to lazyness or complexity) what is in the C++ code that a giant nondeterministic intractable neural network generated. what is guaranteed is that the future will be interesting...
The way I'm keeping up with it (or deluding myself into believing I am keeping up with it) is by maintaining rigorous testing and test standards. I have used LLMs to assist me building C firmware for some hardware projects. But the scale of that has been such that it can also be well tested. Anyway, part of the reason I was so much slower with python is I'm an expert at all the tech I used, spending literal years of my life in the docs and reading books, etc., and I've read everything the LLM wrote to double check it. I'm not so literate with go but its not very complex, and given the static nature, I just trusted the LLM more than I did with python. The react stack I am learning as I go, but the tooling is so good, and I understand the testing aspects, same issue, I trusted the LLM more and have been more productive. Anwyay, times are changing fast!
It feels like the worst of both worlds, what am I missing?<p>I get server-side rendering. I can boot my server, and everything is there. If my model changes, I can update the view. It's cohesive.<p>I get client-side rendering. The backend returns data, the frontend decides what to do with it. It's a clear separation. The data is just data, my mobile app can consume the same "user" endpoint.<p>This seems like a worst-of-both-worlds paradigm, where the backend needs to be intimately aware of the frontend context. Am I not getting it or is there a massive implicit coupling?<p>Now if I need to display the same "user" data twice, in different formats, on my website. Say, as a table in "My account", and as a dropdown in the menu bar. Do I need to write two endpoints in the backend, returning the same data in two different formats?
Yep. And that’s a good thing:<p><a href="https://htmx.org/essays/splitting-your-apis/" rel="nofollow">https://htmx.org/essays/splitting-your-apis/</a>
Splitting application API and generic data API is orthogonal to HTMX. You still have issues compared to plain JSON, don't you?<p>Imagine you need firstName/email in once place, firstName/email in another, and firstName/D.O.B in another.<p>In a plain JSON world, I'd craft a single "user" endpoint, returning those three datapoints, and I would let the frontend handle it. My understanding is with HTMX, I'd have to craft (and maintain/test) three different endpoints, one per component.<p>I feel like you would quickly end up in a combinatorial explosion for anything but the simplest page. I really don't get the appeal at all. Of course everything can be very simple and lightweight if you hide the complexity under the bed!
> n a plain JSON world, I'd craft a single "user" endpoint, returning those three datapoints, and I would let the frontend handle it.<p>The main problem is that this is extremely, extremely expensive in practice. You end up in Big Webapp hell where you're returning 4mb of data to display a 10 byte string on the top right of the screen with the user's name. And then you need to do this for ALL objects.<p>What happens if a very simple page needs tiny bits of data from numerous objects? It's slow as all hell, and now your page takes 10 seconds to load on mobile. If you just rendered it server-side, all the data is in reach and you just... use what you need.<p>And that's not even taking into account the complexity. Everything becomes much more complex because the backend returns everything. You need X + 1, but you have to deal with X + 1,000.<p>And then simple optimization techniques just fall flat on their face, too. What if we want to do a batch update? Tsk tsk, that's not RESTful. No, instead send out 100 requests.<p>What about long running tasks? Maybe report generation? Tsk tsk, that's not RESTful. No, generate the report on the frontend using a bajillion different objects from god knows where across the backend. Does it even make sense with the state and constraints of the data? Probably not, that's done at a DB level and you're just throwing all that away to return JSON.<p>I mean, consider such a simple problem. I have a User object, the user has a key which identifies their orders, and each order has a key which identifies the products in that order. Backend-driven? Just throw that in HTML, boom, 100 lines of code.<p>RESTful design? First query for the User object. Then, extract their orders. Then, query for the order object. For each of those, query for their products. Now, reconstruct the relationship on the frontend, being careful to match the semantics of the data. If you don't, then your frontend is lying and you will try to persist something you can't, or display things in a way they aren't stored.<p>The backend went from one query to multiple endpoints, multiple queries, and 10x the amount of code. The frontend ballooned, too, and we're now essentially doing poor man's SQL in JS. But does the frontend team gets the bliss of not dealing with the backend? No, actually - because they need to check the database and backend code to make sure their semantics match the real application semantics.
¯\_(ツ)_/¯<p>any factoring you do on the front end you can do on the back end too, there's nothing magic about it and you don't need different end points: that can be a query parameter or whatever (if it's even a request, in most hypermedia-based apps you'd just render what you need when you need it inline with a larger request)<p>it's a different way of organizing things, but there are plenty of tools for organizing hypermedia on the server well, you just need to learn and use them
> let the frontend handle it<p>via 3 different rendering logic, (such as JSX templates) same as the server<p>> if you hide the complexity under the bed!<p>which is what you just did by dismissing the reality that client-side requires the same 3 renderers that server-side requires! (plus serialization and deserialization logic - not a big deal with your simple example but can be a major bottleneck with complex, nested, native objects)
This isn't about the number of rendering logics. You'll have as many as you have variants, that's tautological. This is about where they happen.<p>In a classic app, there's one entity that keeps the state (the server), and one entity that keeps how it is rendered. This is very easy to reason about, and the contract is very clear. If I want to understand what happens, then I can open my frontend app and see "Hello <b>{{name}}</b>".<p>In HTMX, the logic is spread. What I see is a construct that says "Replace this with the mystery meat from the backend, whatever that is".<p>Assume there's a styling issue. The name looks too big. Is it because the frontend is adding a style that cascades, or is it because the backend returns markup with a class? Now any issue has an extra level of indirection, because you've spread your rendering logic into two places.<p>> which is what you just did by dismissing the reality that client-side requires the same 3 renderers that server-side requires!<p>But what's complex isn't the number of renderers, it's where the logic happens. The HTMX website is full of examples where the header of a table is rendered in the frontend, and the body is rendered in the backend. How's that considered sane when changing the order of the columns turns into a real ordeal?
You need to get out of the mentality that there have be two states.<p>Ultimately the frontend state cannot exist without the backend, where data is persisted. Most apps don't need the frontend state, all it really gives you is maybe a better UX? But in most cases the tradeoff in complexity isn't worth it.
This isn't about state, is it? In a classic react app, if I need to display the name of a user, then I fetch it (from the server) once, and display it as many times as I need, in as many forms as I need. There's only server state.<p>I don't see how it's any simpler to shift partial presentation duties to the backend. Consider this example:<p><a href="https://htmx.org/examples/active-search/" rel="nofollow">https://htmx.org/examples/active-search/</a><p>The backend is supposed to respond with the rows to fill a table. You have an extremely tight coupling between the two. Something as simple as changing the order of the columns would require three releases:<p>- A new version of the backend endpoint
- A frontend change to consume the new endpoint
- A version to delete the old endpoint<p>I'm not trying to be obtuse, but I fail to see how this makes any sense.<p>Consider something as simple as an action updating content in multiple places. It happens all the time: changing your name and also updating the "Hello $name" in the header, cancelling an order that updates the order list but also the order count ...<p>There's _four_ ways to do it in HTMX. Each "more sophisticated" than the previous one. Which is one really wants, sophistication, isn't it?<p><a href="https://htmx.org/examples/update-other-content/" rel="nofollow">https://htmx.org/examples/update-other-content/</a><p>I really struggle to decide which example is worse. Not only the backend needs to be aware of the immediate frontend context, it also needs to be aware of the entire markup.<p>In example two, a seemingly innocuous renaming of the id of the table would break the feature, because the backend uses it (!) to update the view "out of band".<p>I'm really trying to be charitable here, but I really wonder what niche this is useful for. It doesn't seem good for anything complex, and if you can only use it for simple things, what value does it bring over plain javascript?
> This isn't about state, is it? In a classic react app, if I need to display the name of a user, then I fetch it (from the server) once, and display it as many times as I need, in as many forms as I need. There's only server state.<p>No, there's two states here: the frontend state, and the backend state.<p>The name example is trivial, but in real applications, your state is complex and diverges. You need to constantly sync it, constantly validate it, and you need to do that forever. Most of your bugs will be here. The frontend will say the name is name, but actually it's new_name. How do you do fix that? Query the backend every so often? Maybe have the backend send push updates over a websocket? These are hard problems.<p>Ultimately, there is only one "true" state, the backend state, but this isn't the state your users see. You can see this in every web app today, even multi-billion dollars ones. I put in some search criteria, maybe a check a few boxes. Refresh? All gone. 90% of the time I'm not even on the same page. Push the back button? Your guess is as good as mine where I go. The backend thinks I'm one place, but the frontend clearly disagrees.<p>SSR was so simple because it FORCES the sync points. It makes them explicit and unavoidable. With a SPA, YOU have to make the sync points. And keep them in sync and perfect forever. Otherwise your app will just be buggy, and they usually are.
> These are hard problems.<p>I fail to see how HTMX helps. I fail to see how SSR necessarily helps too. You could be serving a page for an order that's been cancelled by the time the user sees it.<p>> I put in some search criteria, maybe a check a few boxes. Refresh? All gone<p>You could see that 20 years ago too, unless you manually stored the state of the form somewhere. Again, what does it have to do with HTMX, or Rect, or SSR?
Not a problem with Jinja (or any server-side templating). Both the table and dropdown render from the same context variable in one template pass. One endpoint, one data fetch, two presentation formats.<p>The "two endpoints" concern assumes you're fetching fragments independently. If you're composing a full page server-side, the data is already there
So now you have presentation logic, tightly coupled, spread over two places. You need to jump between two codebases to even have a clue about what is rendering on the page.<p>There's an example on their website where the header of a table is defined in the frontend, and the body is returned by the backend. If I wanted something as simple as switching the order of the columns, I'd actually need to create a new version of my backend endpoint, release it, change the frontend to use the new endpoint, then delete the old one. That sounds crazy to me.
I use nested templates the same way React uses nested components. The key is cascading the context (like props) down the hierarchy. Column order change? One edit in the table template; everything that includes it gets the update.<p>The "header frontend / body backend" split is a choice, not a requirement. I wouldn't make that choice.
So what if you have presentation logic in two places, if it isn't necessary, remove the second instance?<p>There are so many gains by not using a frontend. You've greatly reduced your site size, removed duplicated logic, a shitload of JS dependencies, and an unnecessary build step.
But I don't want SSR, period. My backend is an HTTP API that speaks JSON. My frontend is whatever thingimajig can talk to an HTTP API in JSON. That's it. I love it this way and see no reason why I should blur the lines between frontend and backend.
HTML over the wire frameworks like HTMX, Hotwire (rails), LiveView (phoenix), Livewire (laravel), LiveView (django), etc. They all have the same basic idea with differences in how they achieve it. I feel this approach is overlooked, and it drives me crazy. There is a huge complexity cost attached with JS frontend app + backend that everyone seems to have accepted as reality. HTML over the wire (really need a catchy acronym maybe HotW) can greatly simplify and speed up development with pretty much the same end user experience as a react app.
Datastar has been garnering my attention
<a href="https://data-star.dev/" rel="nofollow">https://data-star.dev/</a>
My company makes a few products - one of them is just forms, lists, and links. When the codebase was really small we tried using htmx, then alpine ajax, then datastar. We stuck with datastar and I really enjoy it for projects that don't have a highly complex client state. Overall it's a really simple build and deploy process. I find it easier to secure and to reason about. Additional bonus: I'm able to lint the whole thing with biome since it's just typescript and jsx templates.
I just don't like having to send HTML and have the backend deal with what are really frontend problems. Sending JSON is great since you can serialize most reasonable data types into it and then the backend has no responsibility for how it is rendered which helps for having mobile apps use the same backend as the website. Sending HTML just seems nuts since if you change your design you would have to change the backend too.
Threads like these make me glad I’m not a frontend dev. Just looking at the comments it’s clear there is no cohesive view or vision or agreement. One giant Tower of Babel
I've had good success with Turbo (previously Turbolinks). The newer versions (ie. Turbo) really fixed up the shortcomings of the older versions (ie. Turbolinks) and I enjoy using it.<p>Any big reason to use HTMX instead? Is Turbo not really discussed much because of it's association to RoR?
This evangelism around HTMX is bit misplaced.<p>First - simple use cases sure great. But imagine you have to update some element out of the from tree. Now you need to have OOB swaps and your HTML must contain that fragment.<p>Not just that your server template code now has to determine if it is HTMX request and only render OOB fragments if so.<p>Even at decent size app, soon it turns super brittle.<p>Yet to talk about complicated interfaces. Let's not go complicated just think of variants in an E-commerce admin panel.<p>3 variants with 5 values each these are 125 SKU rows that must be collapsed group wise.<p>htmx can do it but it's going to be very very difficult and brittle.<p>So it is surely very useful but it is NOT the only tool for all use cases.
This incredibly simple text-based website doesn't work without enabling JavaScript and allowing XHR in uMatrix.<p>Why not "just use HTML"?
htmx led to spaghetti code for me. react is too much to learn. using vuejs these days.
> The server just returns HTML (not JSON, actual HTML)<p>Thats the thing I don't like. I don't want parts of the structure of my page coming from the backend server. I just want that to send data, as JSON and for the front end to handle that into whatever structure it deems suitable.<p>That way all of the front end code is in one place.
But the front end code is in one place, and that place is the server. It is true, though, that the experience greatly benefits the easier it is to manage and return partials from backend code. Some frameworks make it harder than others.
In the simplest web server, the server returns HTML. Having the backend return JSON is where you're adding complexity. Your front end code won't even work without some base HTML.
I like HTMX, I use it on my blog. But I will say, in the niche where I need some dynamic DOM changes without needing a full-blown SPA, raw JavaScript with some basic utilities like jQuery is not so bad.<p>The issue with htmx is that it is fairly prescriptive of how one should go about building dynamic interactions, and it becomes complex quickly if the dynamic interaction is more than trivial. I don't disagree with its philosophy at all (as I say, I use it for my own site) but it becomes an issue when my product owner tells me that I need to do some funny dynamic thing because it will make the business or clients happy (for some reason), and then it becomes a mission to wrangle it with htmx attributes. And I have to follow that, because as much as it pains me to say it, making stuff pretty and dynamic on the UI is an easy way to score points. It is one of those areas of enterprise software development which seems like a huge upgrade to non-technical people whilst not requiring too much effort.<p>The one thing raw JavaScript is quite well suited for is hacking together some DOM manipulation. I dislike JavaScript in every other domain except this - its in this arena where its leniency is very useful.
I would even say that even "just html" is enough for most website/app. We've been using "just html" at my company ( rosaly.com) for 5 years, we've raised 10 million, have hundreds of customer, and nobody ever complained. And the Android/Ios applications are 234 lines of React-Native which is just embedding a webview , a bit of error screen when there's no internet connection , and intercom library for notification.
I haven't used htmx, but I've given turbo a fair shake. I've only worked on server side rendered apps for my whole career, and they are generally they way to go. But just like react, or anything else, you throw enough engineers at it and it becomes a mess. But also you'll only find a handful of engineers who understand it compared to react, so that makes it worse. I think the bottom line is creating web UI is just as unsolved today as it was 20+ years ago, and nobody can make any headway - it suggests the fundamentals are totally wrong - after all - this isn't what http and html were even built for.<p>Given sufficient time and money (20+ years, and billions (trillions?) of dollars - which is what we've thrown at web apps) you could build GUI apps using the IRC protocol, but it will never work well.<p>LLM generated code probably tips the scales toward using react though. You can have the bots churn through all that boiler plate, it won't be any worse than what human react devs write, and keep the bots away from your mission critical code because it isn't all munged together like in a SSR app.
Can someone who's adapted HTMX for a larger app report about front-end-server costs?<p>HTMX serves fully baked HTML that needs to be created on the back-end (or front-end-facing servers)<p>That is more processing than sending the raw data to the front-end and baking the HTML there.<p>It is also more bandwidth (unless the JSON is more verbose than the HTML generated).<p>Lastly, I can generate different HTML fragments on the front-end from the same client-side state with the data only being transported once.
How is that working out?
> That is more processing<p>Not necessarily. Often it is less. Template engines can be very, very efficient and fast.<p>Returning JSON almost always requires data/object serialization on the server, this is often slower than direct data/object -> template rendering.<p>Further, it's not your server but keep in mind the client must de-serialize JSON and render some HTML every time.<p>Modifying layouts as a result of non-persistent state (light/dark mode, sorting, etc) can usually be handled relatively easily with styles and data- attributes and sprinkles of JS. HTMX works very well with Alpine.JS and similar libraries for more complex situations.<p>HTMX isn't for every scenario, but it works very very well in many scenarios.
The Demo 3 Live Search example has really nasty scroll jank issues. I’m guessing it’s caused by the results being inserted inline in the document (and thus redoing the layout of much of the page) instead of being placed in some sort of overlay.
> No fetch(). No setState()<p>Just pure eval(). [1]<p>1. htmx.config.allowEval: defaults to true, can be used to disable htmx’s use of eval for certain features (e.g. trigger filters)
> That's HTMX. I didn't write JavaScript to make those work. I wrote HTML attributes.<p>Well you didn’t write standard HTML attributes, you wrote custom attributes that are picked up by a JS framework, so potentially the worst of both worlds depending on your problem space.<p>Having tried HTMX a few times, the problem is firmly in creating a backend that feeds it properly. It’s a disjointed experience for anything more complicated than updating content.
I would recommend <a href="https://data-star.dev" rel="nofollow">https://data-star.dev</a> over htmx. It is more complete. But it depends on what you are building. Datastar does everything that htmx can do and much more.
What I don’t like with HTMX and the like is that you basically don’t get any help in the backend. It also introduces implicit coupling between the frontend and backend which is very much the worst kind of coupling you can have. While this is fine for small to medium projects it is terrible in the long run.<p>To be honest this might be a skill issue or something I haven’t understood properly with these frameworks.
The big problem I have with HTMX is the same one I have with React server components and similar concepts; I really like being able to just serve static files. Plus the clear separation of server and client really makes reasoning about a lot of different problem cases a lot easier, that's not something to dismiss lightly. (It's a bit of a 'ship your org chart' case, though)
I keep seeing articles religiously pushing htmx, what I'm not seeing are sophisticated examples or apps written with it, just more basic example and interaction examples.<p>I personally prefer UIs with great encapsulation/composition, which used to be Vue, but with AI starting to write more of my UIs now I've switched to React/Next.js for new non-progressive UIs.
> Option B: React (or Vue, or Svelte, or Angular if you're being punished for something).<p>> And suddenly you've got:<p>> A package.json with 847 dependencies<p>> A build step that takes 45 seconds (if the CI gods are merciful)<p>> State management debates polluting your pull requests<p>> Junior devs losing their minds over why useEffect runs twice<p>> A bundle size that would make a 56k modem weep<p>No? React is surprisingly small, and if you're in dependency hell then fix that. The alternative is another idiom.
React only renders. You need a lot more than that for an app.<p>And if you glue packages together you're basically reinventing frameworks. This can be a good thing or a bad thing.<p>Regardless of your choice between glueing libs or a framework, you'll end up with tons of dependencies for most non-trivial projects anyway.
Please install a TLS certificate to the site so people can view the content.
The author seems to have some beef with angular, which I have found lighter and more pleasant to use compared to react.
Same here. Modern angular is pretty nice to work with.<p>Yes It has a "learning curve" but so does everything (even React).<p>Also Angular is now about twenty thousand times simpler than it was in the past as you can use Signals for reactivity, and basically ignore Observables for 95% of things.<p>Angular also removes the a lot of the negatives outlined in the page - no npm, no node_modules, no ecosystem fatigue, no debates on state management etc etc. Everything you need is included in one dependency you can load from a CDN.<p>I never liked that in react you are mangling the presentation and business logic in one tsx file (separation of concerns? React ignores that lesson for some reason). Htmx feels even worse in this way because now you also have html snippets and templates in your backend code too! Nightmare! Angular let's you leave the templates as standalone files and not mushed into your typescript like react (although you can inline them into the typescript if you want to, but obviously no one does that for anything apart from the most trivial of components)
So we are almost back to using XSLT (and this is a good thing)
No, and it wouldn’t be, respectively.<p>(Also, I don’t think we can go back to XSLT in the same sense that I can’t go back to the moon.)
Sorry, I'm struggling to see the comparison
Does XSLT support making HTTP requests to load new content into an existing page?
My first reaction, having done a fair bit of XSLT in ancient times, was "I hope not".<p>After a bit of searching all the examples I could see use JavaScript to glue the HTTP request making part and then invoke the XSLT processor so it looks like the answer is "no".
I have used HTMX extensively with AI agents. It is fantastic for dynamic views.<p>Agent one: handles the request and does tool calls<p>Agent two: reads the result and decides on quality vs a re-drive if it’s low quality<p>Agent three: decides how to present the information to the user, creates a collection of HTMX elements<p>HTMX hx-get is reliably, and beautifully rendering the result of the Agentic Workflow without any react, etc.<p>Very happy and passing quality gates. I love not having security alerts every week to patch because of some buried react dependency library
My main use of HTMX is to hack the Django Admin here and there. It works great for that. I’ve tried to use it in a moderately complex app and it became such a mess so quickly. I’m sticking with React for frontend stuff for now. Works well enough and I’m used to it now.
Can highly recommend HTMX with Astro[1] for pages that are mostly static.<p>[1]: <a href="https://astro.build/" rel="nofollow">https://astro.build/</a>
I did. I found it to have quite a few problems with bugs, docs, and web page lifecycle.<p>I switched to Hotwire/Stimulus and found it to be a significantly better implementation of the same core concepts. I'd highly recommend checking them out.
To prove the point, author mentions company that went from React to Htmx and saw positive change in relevant metrics. When you do that, it usually means your app has matured in a sense and you can be sure that htmx will be sufficient to handle all the functionality<p>I'm however more curious about going the other way, i.e. you start a project with Htmx which happily grows but after a while, a large feature is requested which inevitably changes the direction of the app into React use-case territory. I can't think of concrete example but you now have to work around it with htmx or commit to rewriting to React (or alternative). Wonder what are thoughts of people who had to deal with this
For those who build in Ruby on Rails, does htmx have an advantage over Turbo/Stimulus? For me, the sense that it doesn't is why I've been avoiding it. Prefer to stick with vanilla stack unless there's a very compelling reason not to.
> But sometimes—and here's where it gets uncomfortable—you actually do need a button that updates part of a page without reloading the whole damn thing. You do need a search box that shows results as you type. You do need interactivity.<p>You can do this with plain old Javascript. Make a request, swap out the [inner | outer]HTML with the result. If you want a nice visual transition, wrap the swap in a startViewTransition(). Obviously, you need to be extra careful if you're using user-submitted HTML. Otherwise, it's fairly straight forward.
Isn't this what html-over-the-wire/turbo/stimulus is? [1]<p>[1] <a href="https://hotwired.dev/" rel="nofollow">https://hotwired.dev/</a>
<p><pre><code> <button hx-post="/clicked" hx-swap="outerHTML">
</code></pre>
You know, I see logic/"programming" inside of templates and I'm out, gave up that life many years ago and never have I been eager to go back to it.<p>No, I'll keep using hiccup and similar things that are just <i>data</i> and nothing more, no syntax, just functions and built-in data structures, then give me HTML as a string which consumers can do whatever with, and we're golden.
> Or are you building another dashboard, another admin panel, another e-commerce site, another blog, another SaaS app that's fundamentally just forms and tables and lists?<p>Install an open source admin panel and call it a day.
> You do need a search box that shows results as you type. You do need interactivity.<p>You can use JavaScript for it.<p>I've been trying lately ruby templates with some occasional JS for this and it works great.<p>Or implement a straight forward web component.
No, I'm sorry. Life is too short to write code inside of HTML attributes.
I love HTMX. It felt like a rebirth of PJAX. Server side template rendering is simply the best.<p>Too bad that the world insists on going nuts with JS everything.<p>Oh as a plus, AI agents are a lot more productive when dealing with server side logic.
HTMX is a great choice for an app that <i>only</i> needs forms, validation and partial template rendering, though CSS view transitions are making partials less relevant for server side web applications.<p>For things with heavy interaction (drag and drop, chat etc.), I find the code to make it work with HTMX is just too clumsy to work with as a mental model.
multicardz is heavy drag-drop ui. totally based on htmx (I still need to get data from a backend, I use htmx to do it for a number of reasons.)
That's exactly what the article is saying.
This guy lives in extremes! His option 1 is pure HTML the only other option 2 is React! But it seems he never heard about VanillaJS to drive a button click.
> Any HTML element can make an HTTP request<p>> The server just returns HTML (not JSON, actual HTML)<p>I like to separate presentation HTML from the data (returned from HTTP request). Some like to make backends that do nothing but serve the (singular) frontend, even running templates to make the HTML they return for easy consumption. That's not where I draw the line.
As the op may read along the other comments, we are tired trying the new shiny thing. Now it is AI's turn to get tired or never.<p>Dx resources must aim AI's attention having enormous technical documentation and be AI efficient in order to become mainstream.<p>I believe no other shiniest thing will ever make cognitive nest in humans. We are overloaded.
><i>The "server" (mocked client-side for this demo</i><p>Hmmm.... I wonder why that is......
I mean, I guess it's fine to mock stuff here, but when I tried clicking the button, I first opened the network tab of devtools, and was confused by the lack of any request being made. (The console explained, showing "[HTMX Demo Mock] fetch: POST /demo/clicked" and "[HTMX Demo Mock] Returning mock for: POST /demo/clicked")<p>Your demo shouldn't have <i>explicit</i> lies, such as "It worked. That was an actual HTMX POST request. The "server" returned this HTML and HTMX swapped it in."<p>I mean, I guess maybe it made an HTMX POST request, not an HTTP POST request? But this does reduce my trust in the article.
I liked the idea that htmx is good for those middle of the road cases where you're not doing anything fancy but I didn't end up using it very often though because if I'm not doing something fancy then I'm not going to ask my user to leave their terminal anyhow.
The framework has been built into the browser for a while now.<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guid...</a>
I'm a big fan of returning html instead of json when possible and I've been htmx curious for a bit.<p>With all the examples people keep using, I assumed it would be way smaller. 16kb minified is a lot.<p>Looking at the docs just now the core api seems reasonable, but it a lot larger than I'd assumed.
our minimalist version of htmx is fixi.js:<p><a href="https://github.com/bigskysoftware/fixi" rel="nofollow">https://github.com/bigskysoftware/fixi</a><p>1181kb brotli'd (no minification)
Look into DataStar and Alpine Ajax then, they're much smaller and more targeted.
Read DATAOS.software for an in depth analysis of bundle sizes and impact on performance.
It's much smaller than the final bundle size that most sites will end up loading.
For those wanting different colored pills, there are<p><a href="https://justfuckingusereact.com" rel="nofollow">https://justfuckingusereact.com</a><p><a href="https://justfuckingusetailwind.com" rel="nofollow">https://justfuckingusetailwind.com</a><p><a href="https://www.justfuckinguserails.com" rel="nofollow">https://www.justfuckinguserails.com</a>
> Junior devs losing their minds over why useEffect runs twice<p>Oh now now, even senior devs do this too :)
I would recommend <a href="https://data-star.dev" rel="nofollow">https://data-star.dev</a> instead.
SimpleUI helps address the endpoint issue by autogenerating routes for HTMX. It's like a simulation of the frontend running on the backend.<p><a href="https://simpleui.io" rel="nofollow">https://simpleui.io</a>
No. Why the hell would I use Angular 1.x style directives in 2026? For the simple contact form and todo apps, why would I even use client side scripting? Go away.
Are there any server-side frameworks that look like HTMX in the browser but allow writing functional-style code for managing all that HTML mutating itself?
I would say please just try Web Components.<p>They are standard, they work, they're great.
I'm a big fan of it for building micro websites with LLMs, since it can keep pretty much the entire thing in context (even including the docs) it seems to perform pretty well.
What are some large websites using HTMX? I'd like to check them out.
Ofc if you <i>really</i> want to lose bloat, there's always Htmz<p><a href="https://leanrada.com/htmz/" rel="nofollow">https://leanrada.com/htmz/</a>
Sorry, but it's a no from me.<p>htmx is a great idea, but it's not necessary anymore. We're very close to invokers being baseline (and even that is just an extension of the "composedPath includes -> invoke" pattern), and that will take care of plenty of what htmx was designed to do. Between features like that, and web components, I'm very happy to stick with "plain HTML" (no frameworks; my web components do not draw from a core module or anything).<p>Also, just a suggestion because it's not <i>technically</i> wrong:<p>The example of sometimes needing an auto-completing search box is probably not the best one to use. I'm sure it's meant to say "you want the results to be queried from a server/database on every input", which you would certainly need javascript for. But the specific example of just having a search box autocomplete can actually be fulfilled with a datalist element. It won't dynamically re-query results, but it will filter based on input. So it's a muddy example, at best, and that's probably not great for the point trying to be made.
> We're very close to invokers being baseline, and that will take care of plenty of what htmx was designed to do.<p>From what I've seen, invokers <i>without extra code</i> are designed for client side interactivity (e.g. showing a modal), which is orthogonal to the (correct, IMO) use case of HTMX. You shouldn't use HTMX to turn every custom user interaction into a network round trip, you should use it instead of fetching JSON. If a user interaction wouldn't trigger a network request if you built your app with react/vue/svelte/{insert_framework_of_choice}, then it shouldn't trigger one if you build it with HTMX either.<p>You can add custom commands with invokes and custom JS, but at that point you're basically re-implementing HTMX yourself, and I'm not sure what the advantage of that would be over hx-trigger="command" (especially when you also consider using fixi if you don't need all the features of HTMX). There's also the triptych proposals [2] from one of the HTMX maintainers which <i>would</i> add some of HTMX's behaviors to HTML, but those are a <i>long</i> way from being baseline, and may get there.<p>[1] <a href="https://github.com/bigskysoftware/fixi" rel="nofollow">https://github.com/bigskysoftware/fixi</a><p>[2] <a href="https://alexanderpetros.com/triptych/" rel="nofollow">https://alexanderpetros.com/triptych/</a>
> You can add custom commands with invokes and custom JS, but at that point you're basically re-implementing HTMX yourself[...]<p>Exactly. So why use a library? If it's that simple, the suggestion is akin to using a library for a toggle, when a checkbox would do. Yes, there are reasons to do it, but no, it's not what I'm going to do most of the time.<p>ETA: sorry; I should have mentioned, I'm ignoring server stuff because it's not my use case. I don't hydrate code on a server and send it down to people. I just write HTML or let javascript compose it in the browser. Since I don't use frameworks, that's the way I've developed to be efficient. Since I can't speak to how useful htmx is for server-rendered stuff, I'm staying out of it. Just talking about what htmx can do for me, which is very little.
Invokers don't give you what htmx gives you out of the box. If you want to, for example, have an invoker command to fetch a resource and swap it in to the page, you have to write custom JS for that. That's the thing that htmx gives you out of the box, along with error handling, progress indicator support, history support, animated transitions, and a host of other features.<p>If you don't need or want all these and are happy with the worse UX, then of course you don't need htmx.<p>Re your suggestion: datalist makes you select an option, then fills in an input with the value of the option. Then you have to submit the form to actually get the resource you just searched for. Active search gives you the links to the resources directly in the search results, so you can load them with one click. There's a big UX difference.
As you should be able to tell from the other comments, this is not a library for me. If I had ever looked into it past trying to actually implement it, I would have realized that it's actually specifically for server-rendered content and using it for front-end development doesn't actually add much. The author made that very clear in the supporting documentation, I just never bothered to check.<p>So I relayed my personal experience with it and then, because of this great comment section, I became aware that I was trying to use it for things that it isn't helpful for. Because, yes, I would have to write custom JS for the functions I would try to invoke with invokers, but I would <i>also</i> have to write custom JS for the functions I would try to invoke with htmx. There's no change, for me, other than including 14kb that I do not need to run a PWA.<p>So you can take whatever issue you want with my impatience and my myopia in disregarding it as not useful, but my complaints are not immaterial. It doesn't do what I said it doesn't do, and you seem pretty happy to confirm that. I shouldn't have expected a cat to bark, and I regret it. Hell, I'd apologize if someone felt mislead, or if someone feels I'm misleading people in my aspersions. But - like any app - my apps swap out html all of the time and there's nothing that htmx provides that helps me with that in a way that's worth the weight.
> it's actually specifically for server-rendered content and using it for front-end development doesn't actually add much<p>It's for server-rendered content that can be used to build a frontend app. I know because I've done it several times.<p>> I would <i>also</i> have to write custom JS for the functions I would try to invoke with htmx<p>The difference is with invokers you would have to re-implement <i>everything</i> from scratch and with htmx you typically only need to implement some parts that it doesn't handle, like eg listening to a DOM event and doing some action in response.
> We're very close to invokers being baseline<p>Well why not have the benefits of invokers, but today - with HTMX?<p>HTMX could eventually switch its implementation to use invokers under the hood in the future, and you'd have the convenience of using declarative behaviors on your buttons, today.<p>> autocomplete can actually be fulfilled with a datalist element<p>I wish that the spec would cover more use cases, but last time I tried to use it, I couldn't, because it has really bad UX, and is inconsistent across browsers.<p>Also, like you mentioned, it only works for small data sets that you can deliver with the initial HTML, not large amounts of data which reside on the server.<p>You could argue that these are use cases where you wouldn't require an auto-complete in the first place, because the data set is too small.
> Well why not have the benefits of invokers, but today - with HTMX?<p>Because I already have the benefit of invokers, today, using the composedPath method. And a map to some functions is usually less, in my experience, than 14kb of js.
The standard invoker commands deal with the display of already loaded page content in the DOM.<p>HTMX deals with loading content into the DOM, not managing display of the DOM.<p>They serve two different roles and together should handle the majority of javascript framework use cases.<p>Web Components does cover some of the same use case as HTMX, but is intended for when a server is returning data rather than HTML. It is both more powerful and more complex.<p>> the specific example of just having a search box autocomplete can actually be fulfilled with a datalist element. It won't dynamically re-query results, but it will filter based on input. So it's a muddy example, at best, and that's probably not great for the point trying to be made.<p>A prefilled list is never an acceptable solution for a search box. A search box is meant to capture arbitrary input. A filterable datalist is not a search box.
> A prefilled list is never an acceptable solution for a search box.<p>Yes it is. When the query is more expensive than the entire dataset included in some other query, a static list built from previously queried content is the more performant search, even if you want to classify it as a filter. I, as a user, am still searching through this list of unknown nodes even if you, the program, are just filtering what your nodes are for me. All searches are filters; hard lines for best practices only matter insofar as they engage with their practical application.
Has anyone tried using HTMX + some realtime query layer like Convex?
> The ecosystem is why your node_modules folder is 2GB. The<p>And every months a few of those modules try to exfiltrate your credentials…
There is inherent risk of such low level frameworks over React, that is they allow you to easily blow your foot off, by injecting raw unsanitized HTML back for dynamic execution. A thing that would not work in React apps by default. Even on those demos, you can XSS yourself with the simplest payload, confirming my point.
Latest iOS Safari: the viewport jumps around on all those demos. Really hurts your case.
iOS Safara user here. The viewport jumped for me only on the active search demo and only the first time when the result content was initially loaded. This can be easily fixed by having a fixed-size results box loaded from the beginning.
my htmx apps have 0 cls. You just have to care enough to do something about it.
Mitrhil.js is 8.8 kB gzipped.<p>And you can just return JSON from your API.<p>And you can add JSX later if you want.
What you need is more f-bombs in your article.
I don't get why people don't just use vue... with no build step, just including it.
> Honor obliges me to admit this is not literally true. bettermotherfuckingwebsite.com is a fucking pedagogical masterpiece and reshaped how I built my own site. But let's not spoil the bit...<p>> Inspired by (and in joyful dialogue with) motherfuckingwebsite.com, justfuckingusehtml.com, bettermotherfuckingwebsite.com, and justfuckingusereact.com. Extremism in defense of developer experience is no vice! This site made by me. Does this all sound a bit like shallow slop? Yup, please help make it better.<p>I agree with you, and wrote a similar one for Markdown that you might enjoy. Same overall naming scheme. (Note: open the comments before you judge the use of a Web Component for rendering purposes.)
14kb gzipped file? sorry no.
Just use the CHAMP stack. Like it's 2005 again.<p>CSS, HTML, Apache, MySQL and PHP.
To be honest, none of these new-ish frameworks are good because there’s not enough data to train LLMs. React/NextJS is great because I can 80% get there with LLMs.
> <i>The whole library is ~14kb gzipped</i><p>That'll be item #848 in my 847 line package.json.
This is a retarded advice. Author clearly never tried to develop any serious web development.<p>> the build time is over 30 seconds!<p>that's silly. 30 seconds building time is nothing compare to the accumulated time you wait for micro changes to your frontend.<p>for typical web development using react/vue/svelte you have hot code reloading, which can reload the current website < 1 seconds after you hit [Save] on your favorite editor.<p>for htmx to update, you have to wait for your whole server to reload (which can be way slower even you use interpreted languages like ruby or python, due to complexity of the framework you use).<p>not to mention it does not keep any state of the current website, make debugging way more troublesome compare to a js mature framework.<p>only people who never have to improve their website incrementally think htmx is a viable option. or insane people.<p>obviously, for some small websites with minimal interactions or no need to change the content very often, then htmx can be good, but for that case, vanilla js also works, and they do not need 14kb of excess baggage.
Was hoping for a sandbox so I could actually try it!
You don't need React or HTMX; just put onclick= on your element and make your call with vanilla javascript. Use these frameworks if you want, as they're both neat, but frankly I think people forget that there are other options
No
> When you click it, HTMX POSTs to /clicked, and whatever HTML the server returns replaces the button. No fetch(). No setState(). No npm install. No fucking webpack config.<p>Can someone explain something to me?<p>To my view, the single best idea React has is that it forces you to encapsulate the full set of states in your component - not anywhere else. For instance, if you have a "Comment" button that becomes "Submitted" after you click it, you must include that state inside the comment component. You can't hide it somewhere else (i.e., in the input field after you press cmd-enter). This is a huge thing for managing complexity - if you spread state updates to a number of different places, it becomes significantly harder to reason about how the button works.<p>Replacing the button with whatever the server responds with may sound simple, but it really makes it hard to answer the question of "what are all the states this button could be in". I mean, what if the server returns another button... which hits another API... etc?<p>The weird thing is that HTMX talks about Locality of Behavior (yay!), but doesn't seem to practice it at all?<p>BTW, one other thing:<p>> The ecosystem is why your node_modules folder is 2GB. The ecosystem is why there are 14 ways to style a component and they all have tradeoffs. The ecosystem is why "which state management library" is somehow still a debate.<p>> HTMX's ecosystem is: your server-side language of choice. That's it. That's the ecosystem.<p>Really? Python is my ecosystem. You know that people add stuff to their node_modules because they need it, right? It's not like we do it for fun. Where am I going to find a date-time picker in Python? Am I going to build it from scratch? Where is an autocomplete component in Python? Or mentions?
To your last point: If you're making an HTMX app, you're probably using built-in browser inputs instead of custom JS-based ones like react-select. If you NEED react-select, you probably should just use react. But if your site is mostly just displaying data with html and updating that data with forms, htmx will work great with much less complexity and effort.<p>I've only toyed around with htmx, but it really is refreshing. Of course you can't do <i>everything</i> that you can do with a fully-fledged client side framework. But once you try it out, you realize that more of the web is just markup + forms than you realized. I wouldn't build a live chat app with htmx, but I would totally build a reporting dashboard.
The state encapsulation concern is exactly what DATAOS addresses: dataos.software<p>The premise is that React's "UI=f(state)" creates a synchronization problem that doesn't need to exist.<p>If the DOM is the authority on state (not a projection of state held elsewhere), there's nothing to sync. You read state from where it already lives.<p>I built multicardz on this: 1M+ cards, sub-500ms searches, 100/100 Lighthouse scores.<p>If you have time to read, I would very much like to hear your thoughts; genuine technical pushback welcome.
I would be happy to discuss more. I am genuinely curious (though I do hold a pretty strong belief that React is a good abstraction).<p>When you say that the DOM is the authority on state, I’m not sure if that addresses my concern. Let’s revisit my example of the button. Image I look at the DOM and see that it’s in a “Submitted” state, and I think that’s a bug. How can I determine how it got into this buggy state? The DOM can’t answer that question, as far as I can see, because it is only an authority on the current state of the system <i>at this exact moment</i>. The only way I see you answering this question is by scanning every single API endpoint that could have plausibly swapped out the button for its new state - which scales at O(n) to the side of your repository! And if one API could have added HTML which then added more HTML, it seems even worse than that.<p>The advantage of React is that you get a crisp answer to that question at all times.<p>> I built multicardz on this: 1M+ cards, sub-500ms searches, 100/100 Lighthouse scores.<p>I believe you! But I am more concerned about readability. React makes some tradeoffs, but to me readability trumps all.
The debugging question has a direct answer: when you capture User State from the DOM (via manifest) and send it to pure functions on the backend, you get a perfect event source pattern.<p>Not only can I can tell you exactly who and what triggered any piece of HTML being sent to screen, I can rewind and replay it like a tape recorder.<p>The broader philosophical difference: I don't treat "state" as one thing. User State (what the user sees and expects to persist across refresh) lives in the DOM.<p>Auth state, db cursors, cache: backend concerns. Pure functions on the backend are deterministic; same input, same output, trivially testable.<p>I have no hate for React; I was a core member of the React Studio team. But for my use cases, this model gives me better debuggability, not worse.
This fucker didn't even bother showing us some real POST requests. And he actually wrote JavaScript to make those work.<p>Why would you mock it on the client-side if HTMX makes it so simple??
> Most teams don't fail because they picked the wrong framework. They fail because they picked too much framework. HTMX is a bet on simplicity, and simplicity tends to win over time.<p>I've built enough stuff in my time to know this is hyperbole at best and an outright lie at worst. I've never seen a team fail due to complexity. Team fails because the thing they built was wrong.<p>You should spend 99% of your time paranoid that the thing you're building is useful enough to justify its existence. Whatever tool you use along the way makes up the last 1%
But how to <i>actually</i> manage non trivial state? URLs get big pretty fast
please, just use html/css and some javascript where applicable.
Do not use HTMX for anything other than very simple CRUD apps. The vast majority of the time you'll be wishing you had client side two way data binding and state management. If you want "simple and not React", just use Alpine.js. It has way better ergonomics and features than HTMX and can do essentially everything HTMX can do.
No huge JS frameworks, no build steps, no state hell
I'm the CEO of HTML. I approve of unpoly. A+++++
Even if you do have complex client-side state: dataos.software
I haven't used HTMX but the author doesn't make a very convincing case. On the one hand they say,<p>> "But what about complex client-side state management?"<p>> You probably don't have complex client-side state. You have forms. You have lists. You have things that show up when you click other things. HTMX handles all of that.<p>On the other hand,<p>> I'm not a zealot. HTMX isn't for everything.<p>> Genuinely complex UI state (not "my form has validation" complex—actually complex)<p>But my interpretation is that any UI which displays the same data in just two places (like a "new notification" indicator as well as bolding new messages in an inbox, or a list of articles which can change dynamically as well as a count of the number of articles) is "complex" enough that you'll need client side state.
If you never seen HTMX it is a small js library that lets you swap some part of your dom with the responses from your webserver.<p>This means that in theory you (as a dev) don't need (to write any) js, nor do your users need to download a full page (for any interaction) like it's 1999. Your webserver replies with fully server-renderd HTML but just for the dom node (say a div) that you want to replace.<p>It's fun for very simple things, even great for extremely simple interactions modes. For interactive products, anything beyond simple CRUDs, it's madness.<p>Whenever you want to sprinkle a tiny bit of interactivity you'll have to choose between the path of least resistance (a small hack on HTMX) or a proper way. State management gets out of control real fast, it's the opposite of UI=f(state).<p>I've seen it go bad, then worse with alpine-js, and then completely ripped in favor of something where people can let the browser do browser things.<p>[edit for clarity]
> it is a small js library ...
This means that in theory you don't need js<p>I assume I'm not the only person left a little puzzled.<p>Do you mean "don't need JS" as in like, a full-fledged JS framework?
See the quickstart from htmx.org<p><pre><code> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
<!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>
</code></pre>
When the user clicks the button the browser will take the result of the request to `/clicked` and swap the whole button dom node for whatever the server sent.<p>As a dev you get to write HTML, and need to learn about some new tag attributes.<p>Your browser is still running js.
They mean that you don't need to <i>write</i> JS, you can just add a script tag to your page
Sorry I know other people have responded already, but it means you don't have to write any client side javascript at all. You can just skip along with a server that returns html. Just throw the script tag in there, and you're done.<p>The magic of this is that it's pretty easy to make SPA-like webapps with no javascript or complex client side framework. You can write your server in python, rust, clojure, whatever. If you don't need a lot of state management, it's really simple and awesome.
> If you never seen HTMX it is a small js library that lets you swap some part of your dom with the responses from your webserver.<p>> This means that in theory you don't need js, nor do your users need to download a full page like it's 1999. Your webserver replies with fully server-renderd HTML but just for the dom node (say a div) that you want to replace.<p>You got this backwards. With HTMX you need js. But just to swap a div, you can use link target + iframe, like it's 1999.
> "I'm not a fucking saint"<p>You're not a fucking person, this is LLM output.<p>It starts with the overdone sweary thing then mentions it's overdone and says it's not gonna do it, and it's almost enough to make me think the article is going to offer someone's point of view. But once again the LLM has erased any point of view the author may have had going in (or prevented them from developing it) and replaced it with a mediocre infodump.<p>I think this is the 5th slop I've seen atop HN in 24 hours.<p>> This site made by me, with tongue firmly in cheek.<p>Well, the LLM ruined it, and you didn't even tell us it participated.
Do you have evidence, or is it mostly vibes?<p>EDIT: Decided to dig up the source: <a href="https://github.com/algal/pleasejusttryhtmx/commits?author=algal" rel="nofollow">https://github.com/algal/pleasejusttryhtmx/commits?author=al...</a><p>Looks like the initial commit might well have been generated, and then the document touched up in several following commits.<p>But there's clearly a person behind it: algal.
There's a person behind all of these bad posts that are making it here. What I've said is that their perspective has been erased by the garbage the LLM put together from whatever inputs they gave it. OK - OK - I did say "you're not a real person" which is maybe what you're responding to here; I did not mean algal is not a real person, I meant algal didn't write the line I was quoting.<p>But yes, it's "vibes" - although extremely obvious IMO. Extreme usage of headings for paragraphs, which are often just a bullet list or a string of short marketing-speak fluff statements.<p>That's all aesthetic though and not the offensive part, it's just what makes it obvious. The offensive part is you can read the whole thing and come away with little more than the title. The author's perspective and voice is lost, beyond "they want you to try htmx" I can't tell what they care about or why, I can't tell what it is they were excited to try to convey.<p>Btw they did <i>just</i> add this to the footer.<p>> Does this all sound a bit like shallow slop? Yup, please help make it better.
I appreciate the discussion that this post sparked. But it is so lame that something like this is LLM generated. It's a perfect setup for some fun creative writing, what is the need to pour slop all over it??<p>Also the lack of comments calling out the obvious AI style is confusing to me. HN usually jumps on this stuff. Are we just getting tired of calling it out? Or have we just accepted that we're going to read slop sometimes? Or I guess the opportunity to talk about HTMX was probably more important than the post content
My theory is that a lot of people skim articles and then go to comments, or even just skip to comments once there are a few, and that these are "good enough" when skimming to produce a jumping off point for some commentary.<p>But now that it's very easy to produce articles that pass that test but don't have much value beyond that, we're seeing a lot of low quality stuff make it.
I don't think this is straight LLM, it's probably an homage to a line of websites like <a href="https://thebestmotherfucking.website" rel="nofollow">https://thebestmotherfucking.website</a>
For sure the author had an idea and went to the LLM to produce the post. And I'm aware of those prior sites (some of which are linked at the bottom.)<p>I mean nothing is straight LLM, you must prompt them and people are putting their ideas in and linking to other sources and getting stuff like this out. And hopefully editing or iterating, but not enough it would seem most of the time.<p>I'm saying their perspective doesn't shine through the crap and I'm sick of reading mediocre infodumps from LLMs.
The author has never heard of jQuery
please just try TLS
Can we see a styled date-time picker in htmx?
_another fucking framework_
Yet another thread of React vs the rest of the world. Each has its use case, and most of the time, React/Vue are largely overkill. Personally, I would never, ever, ever start another React project again. The nightmare of the horrible JS ecosystem, build steps and tooling is behind me.
All my projects now use either HTMX or Alpine Ajax - and for web apps that are actually pretty large. It works perfectly fine. Add Turbo to the mix and you almost have the feeling of using a real SPA, without the headache and large bundled JS files. Feels refreshingly simple. Still have to figure out the no-build step so I can completely drop Bun/Yarn/Npm, and life will be a wonderful thing.
[dead]
[dead]
[dead]
[dead]
..and be unemployed.<p>The article doesn't define any target audience in specific, so there you go.
I don't think learning a new tool will cause you to be unemployed.
yeah, <i>I</i>'ll try htmx if <i>he</i> will maintain the resulting pile of goo lol
what is the use case. I did not read the page. Can you tell me where stars live?