439 comments

[ 0.23 ms ] story [ 384 ms ] thread
(comment deleted)
I am still trying to get HTMX adopted in a ~ 800 employee software development company. And while we do not yet have a project using HTMX in production, I like to use it a lot in thought experiments with mentees: Could you do it with HTMX / Fragments? If yes, how would you design it? Do we REALLY need an SPA?

Kudos to the developers.

I do think "use HTMX" is a tough sell for a 800 employee company, just because it doesn't really solve issues on it's own. (Imagining the pitch is "add HTMX to an existing project") Going all-in on hypermedia definitely means the service that serves your application needs to be more than just a JSON parrot. Templating HTML and sending the right chunks back is hard to do if those services aren't built around being hypermedia services.

I really like turbo-rails [0] (the ruby gem that Rails 7+ bundles in for turbo support, meaning helpers that make turbo frames/responses a native "thing" rails understands) because it's a complete solution. There's at least some obvious structure to build off of, and I'm not stuck trying to build up my own framework on the BE for my newly simpler FE.

django-htmx [1] also fits in this case too. I feel like any honest pitch of HTMX should involve some BE solution as well.

[0] https://github.com/hotwired/turbo-rails

[1] https://github.com/adamchainz/django-htmx

I dont intend it to be an all-in, but I do believe it could do the job in 50% or more cases just as well as any SPA framework. A lot we do is "just crudl" with some sprinkles on top.

A large chunk of our business comes from Spring Boot, so we are experimenting with JTE - looks decent so far (Thymeleaf feels just old nowadays).

My sell is pretty simple: You have regulations coming up in europe which will require you to keep applications up-to date and secure. Extending your SBOM by 1k NPM libraries is a huge cost. I want to get rid of that.

I tried to get HTMX adopted for a new project but the unanimous response was "what is this? why not React? everyone knows React. period" and most of my arguments for HTMX were ignored, because to most people, HTMX looked like some obscure, yet another JS framework created last week, with questionable future.
To be fair, it's not an unfair response. Being able to hire for a technology, and having a large community around the tech stack you use has tangible value.

HTMX might not be something that will vanish in a week, but it's also nowhere close to a mainstream framework.

Very anti React person went for Svelte but the kind of modularity React offers, HTMX can't hope to match especially on larger projects.

Modern React is too simple. A component is just a pure function taking arguments and returning UI as JSX. The only other thing you need to know is few hooks.

> Modern React is too simple. A component is just a pure function

React is simple only in some mathematical theoretical sense, but not for understanding by human minds which fundamentally operate imperatively ("if I click on this, load data X from the server and show them to the user...").

You can get some hello world example relatively easily, but you hit the complexity wall quite quickly (need to know "some hooks" - some, like useEffect() are very complex, yet often needed for basic things). The worst of all is debugging with stacktraces making no sense with it all being from the React itself, not your code, not tracking some logical pathway.

(I'm saying that as someone who generally likes React and would choose it for a new project)

useEffect is simple. If I recall correctly, with no arguments it is like onMount and with the dependent variables listed in array, it would be executed every time any of the listed variables change.
> The only other thing you need to know is few hooks.

...and then draw the rest of the owl.

> The only other thing you need to know is few hooks.

And where you can't use them. Hopefully there are zillions of YT videos from experts teaching you all react gotchas.

try passing state around the component hierarchy and see how simple it is. HTMX makes it easy but centralising the state in one place ie the server. try coming back to your code base in a year or two and see how simple it seems then :D
You pull the state up. Props down.
Except when your state appears in many parts of the page, HTMX makes it hard to keep everything updated.
agreed: htmx is good for "swap out this one element and its children". It is not good for "and these other related elements need to update"
To a certain extent, it works, but there's definitely a point of complexity that you can hit in the app at which it becomes painful. Those are the kinds of apps where htmx is just not a good fit.
> It is not good for "and these other related elements need to update"

That seems a bit backwards, no? Why can't those other elements manage their own updates? You can have the server respond with an `HX-Trigger` header to dispatch an event and any elements that care about that event can listen for it. Far simpler than trying to coordinate surgical DOM updates in a single HTTP request.

Events form the backbone of the browser environment and leaning into that model makes a lot of things much easier

Fully ack. But this can actually be turned into something good imho: I try to challenge all layers (Analysis, UI / UX design) on simplicity: "Do we really need X parts of the page all be affected / updated by something? How could we design it differently with locality in mind? Can we simplify the state somehow?" -> I think that the resulting solutions are often simpler, cheaper, and work just as well.
Not any more complicated than passing parameters to a function.

If that is actually the case, there is an issue with your component design.

maybe you can send me to the right tutorial. I'm a backend, distributed systems engineer. I have worked on eye-watering scale. React is anything but simple to me.

I tried create-react-app, the thing built and downloaded for several minutes, and then there was a nest of file relationships that I didn't grok. It seemed like any change required three files to be updated. Lots of ancillary things like bundlers, packers, tree shakers, lions, tigers, and bears, oh my. After an hour, I didn't get what I was doing. Somehow, altering this function over here made this other thing over there go "moo."

I used to do web development back in like 2001. I understand the web, http, css, html, and basic js. I'm not up on all the latest, but I have a very firm base.

I got htmx working and pretty much fully digested in the same amount of time I wasted on React and have produced a working prototype. I find htmx to be like how the web used to be. It makes sense.

FWIW, create-react-app is overloaded with every package you could ever potentially want to use for some weird reason. It's way overkill and I wouldn't recommend using it.

It's much better just to use Vite with React as a plugin. Then you only need to install three React packages to get your app going.

The best tutorial I've used was "Road to React" by Robin Weiruch. His example app you learn is how to build a Hacker News front page. Very clear and it goes step by step.

Most of the tutorials online are all over the place, or mix Class tutorials with Hooks tutorials, or starts adding in things like Redux (which aren't needed).

The person you're responding to is correct, at it's core React is very simple, especially if you just stick to hooks. Most of my code is just bog standard HTML (as JSX), CSS and JS with a few React hooks thrown in.

FWIW, I've been doing frontend dev since '94 and personally find React jives the most for me and how normal HTML/JS/CSS work. I can see why people would like HTMX, but I've never liked overloading HTML attributes as some strange event model. But it's good there are choices.

React has very good documentation and an excellent tutorial. Here is a link to it: https://react.dev/learn . I recommend doing the exercises. They really help you learn React.
Create React App should not be used because it is no longer maintained. Here is its GitHub repro: https://github.com/facebook/create-react-app/commits/main/ . It has had very few updates since July 2022. This is bad because it needs constant updates because it depends on a large number of packages and those packages are constantly releasing security updates.
That doesn't sound like a good selling point for react.
create-react-app is not react
While true, if cargo was exploitable we'd say it was rust.
To be fair, this would be more analogous to some random person creating a crate called 'create-rust-app' and then abandoning it. Hardly a signal that Rust is dead.
Never said it was saying react/rust were dead, I said it "doesnt look good". Those words were not in my mouth.
I understand your confusion and dismay over React because I'm myself a backend developer and the kind of complexity doesn't exist in backend tech stack.

But this all or none of it has anything to do with React rather with a broken language design which never imagined anyone would write JavaScript worth more than a few paragraphs in a single file.

That's where tons of bundlers come into play from parcel and webpack to vite.

But then there are some language extensions that must be transpiled before they can be bundled. Your JSX comes to mind.

Typescript can be considered in the same league.

Minus all that - Modern React has a very minimal surface area, very few concepts and that's about it.

The reason is because all new technology is a staffing and training problem management needs to solve. Someone has to maintain your thing after its built and be ready when you leave the organization. If React can solve the issue in a similar timeframe and level of effort and it is easy to source React developers then obviously your proposal will be rejected because React is simply far easier to deal with from a training and staffing perspective for what you are trying to do. You need more merits to warrant the introduction of new languages and frameworks.
Same story here, although the poison of choice is angular.
Of course you get pushbacks. Is there any *real* advantage, technical or otherwise, at an organization level, of adopting this new model of creating web pages, other than your personal preferences? You are moving away from an established system with tools that everyone is familiar with, to a system that much fewer people use, with no clear performance/maintenance/management benefit (at least not demonstrated). Maybe you don't like writing JS/TS, but plenty of other people do, and they don't need to cater to your preferences.

People need to spend time learning this tool. They need to be proficient with it. Your new stack might need to still work with existing code at some point. That means training, overhead, ramp up and potential risk in a less established area. Why would people do that?

You should be thankful you didn't get warnings from your boss for messing around instead of actually pushing features out.

I built an HTMX fragment framework for Django. It allows you to render a fragment, and automatically serves the fragment separately for live-updates. I'll open source it tonight and post back.

In my opinion, HTMX + custom elements does everything React does but better, and is a billion times cleaner.

> I'll open source it tonight and post back.

Would be interested in seeing this

Is jquery something people start projects with today? If so, what is the motivation?
Start? Not generally I don't think.

That said, back in the day it provided functionality that JS just didn't, or was quite cumbersome.

With recent JS versions, JS can do a lot of what JQ did for it, but JQ's API or "surface area" is still syntactically smaller and (IMO) more sane than those JS improvements.

Wordpress Themes/Plugins are still all over it.
You saw 'jquery' in the second sentence of the text, immediately closed the link and started a comment with this question?
I have, many times in the last 2 or 3 years... I still do... It's cheap and easy to implement, it's easy to use and it ads just as much cruft as I'm willing to tolerate. I build boring software, average CRUD applications for government departments, people in this line of work don't give a shit about millisecond delays or reactivity, hell, they don't even care about responsiveness... jQuery facilitates high speed development, provides neat functionality that doesn't get in the way, it's easy to maintain, and keeps people happy.
Even if you did give a shit about those things, all that can be achieved with jQuery. IMO the real downside of jQuery is not being as opinionated as other mentioned "technologies", which leaves too much room for thinking
If you haven't started your dev journey with React or some other framework like it, you actually know for a fact that they are not necessary an probably an overkill for a lot of web apps. Websites were built with interactivity, were lighter and worked better, before the dawn of slop-assisted SPAs and developers who don't even know how the browser and hypermedia actually works.
Yep, works great for simple projects.
Start? Not really. However that doesn't mean there isn't active development and new features happening on projects that are already using jQuery, and so the expectations from that library matter.
I dunno, but it is included in many commercial libraries (free ones tend to be less reliant on large dependencies); a lot of people know it and a lot of people don't even know how to start bundling a node (or dino? what are people using now?) project; and it has a lot of extensions that really impress some people.

Besides it having a way more convenient API than bare JS. (That honestly, I only don't use because bare JS is conveniently documented by MDN, otherwise I think I'd be fully on it too.)

I use jQuery when I want to finish a web project, not leave it in perpetual development.
"I know it well" is really the only motivation you need. Why learn a new tool when you have used this one a hundred times before and know it'll get the job done?

If you are brand new to the space and looking to learn, then yeah stay away from jquery.

Off topic but the other day I tried again to build a vanilla JS application.

By the end of the day having built quite a lot I then converted the entire thing to react within half an hour stopped wasting my time and got in with the job of building the thing.

I like to try library free JS every now and then and yet again it was not competition for react.

I know react, it makes sense to me, I find it easy and powerful, I know how to fix most issues and probably most importantly Claude is able to write react for me almost without me intervening at all.

I’m not saying react is for everyone but for me it’s a power tool that I know and the AI knows very well and it gets big stuff built quick.

That’s great for you. But every single react project I’ve seen or inherited has been a steaming pile of shit.

All these new front end developers who jumped in on react with no other experience have no idea how web works are struggle to build without react.

Anyone competent in web development prior to react could build with htmx or even vanilla js just as fast without react as they could with react. Won’t stop the brainwashed react devs coming out defending their only source of income tho.

That's the fault of bad developers, not React. There are bad developers for each and every language, library, framework, and stack.
There are no good react developers because react encourages you to abstract things into 1000s is tiny files.
Isn't that like saying that a "competent" woodworker has to know how to use handtools first before trying to build anything with power tools?

What's the problem with starting from an elevated starting point?

Question is, can you have a super thin layer that gives you the reactivity we all crave and don’t want to reimplement in vanilla ourselves without using legacy tech React.

In a way, it’s depressing that the thing that holds developer minds hostage gets even more hold over devs, because the frickin AI knows it best.

Just a reminder: React was created as a not-a-framework-but-a-view-library but everybody writes React apps, not JS apps.

> React was created as a not-a-framework-but-a-view-library

Honestly, I think this was the biggest mistake the React team made. It was never intended to be this way. It was just marketed this way in order to convince people to try it.

Once you started to use it you could very easily tell how it never fit in the traditional MVC model.

You didn't really set the scene. What kind of application was it? If it's a fully interactive rich application with real time multi user handling, then sure. If it was a static page blog, then that's a problem (yet I see people do that anyway). There's a whole spectrum of interactivity and expectations here.
I did something similar but I took it entirely the other way, I built a full CRUD application with no javascript.

The app is fully SSR and integrates with a fairly complex inline data enrichment and analysis system. I used Tailwind alongside regular CSS for the layouts and some visual enhancements. Eventually, I gave in and added a bit of JavaScript to submit a form when a dropdown is selected—usability is important to me. Other than that, everything works as needed.

I value the hard stance on stability and backwards compatibility over the constant churn that some JS libraries/frameworks have. I understand the need both approaches, but this is a breath of fresh air.

I also happen to think that most web apps have no business being so complex, and that too much work goes into dealing with the added complexity of running SPAs where an SPA is not needed.

Why is the added complexity of running HTMX better than the complexity of an SPA?
Because then I can keep the bulk of the logic in a language that’s better designed than JS. Not having to write JS is a huge feature. The added complexity of HTMX is abstracted behind a single library, and the bulk of the logic stays in a better-designed language—Go, Python, Java, Kotlin, Rust, Zig, C#, anything.
None of those languages can do anything in the browser.
With HTMX they can, because they make server rendered pages more viable.
When someone swipes a carousel, how will C# update the dom attributes and labels on the fly?
I’m very grateful for how htmx by focussing on a very specific part of “interactive JavaScript on the page” was able to shift a whole bunch of similar JavaScript actions into an elegant abstraction that rested so neatly on all the existing work that had/has gone into developing html. And even for having the clarity to name it as such.

In a way it’s a bit of a lesson in managing complexity, rather than seek to be “the next JavaScript framework to replace all the others with its theory of the universe”, it instead carved off a smaller slice and said these Thich are related, we’re just for dealing with these thing, nothing more.

In one swoop a whole raft of manual developer programming workload was packed up with a new easier to understand abstraction.

Kudos to the team, I’m grateful for the considered way you’ve developed this tool for the rest of us.

how do you feel about its adoption in things like https://fastht.ml/ ? i was open to the idea at first esp with jeremy howard's endorsement, but once you start updating multiple things on a page at once i felt like i was fighting htmx rather than it helping me. components are a really neat paradigm and just bc react is currently in a complexity upswing doesnt mean we want to throw the baby out with bathwater
You can build your own python component implementation on top of htmx, like in the example you show. That is not a failing of htmx IMO.
thats not what the js world traditionallyunderstands as a component - eg - it doesnt take an argument that, when the argument value changes, the component rerenders. you still have to wire all that up with htmx (again, as far as i undersatnd it, having spent a week with htmx)
I think web components would be an excellent pairing with htmx. You get some kind of component abstraction (admittedly janky in some ways, though libraries like lit or atomico make this much better). But crucially you get automatic upgrade/initialize behaviour whenever the browser encounters a custom element. So the backend can just send down the custom elements as plain html, you don't need to wire anything up, the browser will bring them to life.
The problem is web components (which are great) are not so good for seo. You would be losing the auto SSR benefits of using your own component abstraction in any backend language.
You can do that with HTMX through events and hx-trigger but it just sounds like HTMX isn't the right tool for what you're trying to do. I've seen a lot of instances of people trying to use HTMX to replace react/vue/etc. and not understanding that they're trying to solve for very different things.

HTMX highly encourages client side scripting for dynamic updates if that's what your UI needs. It's very pro-JavaScript even though a lot of people get confused and try to use it to fully replace JavaScript

That to me sounds external/additional to the idea of a component.

You can do the component side on your backend language of choice, and output html like htmx likes it, and it works (have done it in Python, for example).

It is extra work, but it works with a bit of programming.

I feel this article makes the same mistake many technical articles make.

What does it do? After reading a large chunk of the article, I have no idea. No, wait it "enables behavior".

Maybe it's only relevant to people that are already familiar with it. But it would seem that a hacker news front page would be a great opportunity to let more people know about your product.

This isn't an announcement of a project. This is more a statement of their philosophy and what they are doing. This is targeted towards people familiar with the project.
As a React developer, I love that HTMX is trying to aim for stewardship and "No new features as a feature". IMO, page router NextJS is perfect (and in line with the original API it pitched), and the bifurcation to app/page router has been complicated. Yes, I am fully aware that NextJS works with both app/page. I just find it mentally confusing to wrap my head around both worlds.

I feel this way about base React too, including -- functional/class components, hooks/non-hooks, and more recently, RSCs/Client components. Although I'm more willing to see React as an evolving research project, as contradictory as this may sound.

I’ve been bitten so many times with the app/page router thinking I was looking at docs for one but I was actually looking at them for the other. So annoying.
I really wish htmx would use fetch rather than xhr, and now it looks like that won’t happen. Fetch is easier to proxy, so it would open up a lot more possibilities for backends, like ones running in browser or a native process. I had to hack together a xhr fetch proxy to make this happen.

https://github.com/logankeenan/xhr-fetch-proxy

we've looked at doing it but unfortunately fetch() doesn't fire upload events which would make implementing some events triggered by htmx possible

it's too bad the two APIs have overlapping but not contained functionality.

Are the upload events specifically used for files or for most server interactions. I haven’t noticed any issues with my proxy yet…
Greatly appreciate this philosophy and what htmx brings to the table. It is very simple and quick to pick up, and the longterm stability and simplicity are major advantages for web development.
I've created a Django application using HTMX. Usually I'd jump to React or Vue. It was a great exercise and I can see where HTMX would be a great fit.

1. If you consider yourself a "backend developer" only and want to write the minimum amount of JS/TS.

2. If your application is simple. Yes you can do more complicated interactivity with oob swaps, but you end up with more complexity than you chose HTMX for.

For my next projects, I will still use Django but with React/Vue for pieces that need interactivity. As an example in my HTMX app, I wanted to add a profile image uploader. Lots of great frontend libraries exist to resize / modify your image before even uploading it to your server.

Finally, HTMX is just not testable the same way modern frontend libraries are. I've managed to write some decent tests using beautifulsoup, but it's night and day compared to vitest or jest.

IMHO one of the biggest advantages of using HTMX is not having to maintain three layers of test suites (backend, frontend, end-to-end). You just need to test that your endpoints return the right HTML piece. You don't need unit testing the frontend since you don't have that much logic there. Just rely on end-to-end tests as a complementary tool to check small pieces of logic on the HTMX code.
That honestly sounds like a downside. Having to verify HTML as an output (in comparison to e.g. JSON) is brittle since it will often change just for presentation reasons. Having a clear and somewhat stable API (which is a boon for testing) is IMHO a strong reason for the SPA model.
htmx moves the data -> html transformation to the server side and thus should be more testable
Not really unstable since you generate it and there's no browser modifying it. However you'd still lack client functionality testing.
> Having to verify HTML as an output (in comparison to e.g. JSON) is brittle since it will often change just for presentation reasons.

For HTML tests, if you target elements by their ARIA role, semantic tag, or by matching against the text/label/title the user would see, it should be robust to a lot of presentation changes (and does some accessibility checks too). It's much more robust than e.g. `body > div > div .card > h2` which are sure to break in tests and slow you down when you make changes later.

See Playwright locators for example:

https://playwright.dev/docs/locators

Not sure if this is what you meant, but you can't rely on only the JSON because you can't assume it's been properly transformed into the expected HTML.

It's standard practice in the frontend world https://jestjs.io/docs/snapshot-testing
In my experience snapshots have largely fallen out of vogue, at least as far as them blocking deploys goes. They're usually flaky, change often, are slow to test and it's way too easy to have false positives which lulls people into complacency and just regenerating the snapshots as soon as they reach a failure. I'm guilty of that myself, unless I can spot the breakage immediately I pretty much just regen the snapshot by default subconsciously because of how often I've had to do that for false positives
Then what's to stop you from making any unit test pass by just changing the expectations? The best testing technique in the world can't save us from developer error.
The problem with snapshot tests is that they tend to fail when something is changed.

One property of good tests is that they only fail when something is broken.

Snapshot tests aren't really automated tests, because you have to manually check the outputs to see if failures are genuine. It's a reminder to do manual checking but it's still not an automated process.

> The best testing technique in the world can't save us from developer error.

Sure, but using a testing technique that increases developer error is unwise, and snapshot testing has done that every time I've seen it used, so I don't use it anymore.

> they tend to fail when something is changed.

Then fix the test so that it fails only when something breaks? Do people not fix flaky, overly broad, or incorrect unit tests? How is a snapshot test any different?

A fix here would be to drop snapshot testing altogether, since being flaky and overly broad is a natural result of dumb diffing of your app's output.
I'm not sure you understand what snapshot testing is. It's a form of testing where you render frontend components and take a "snapshot", storing the output and saving it for later, then on the next test run, the component is rendered again and compared to the saved snapshot.

Any change that modifies the rendering of any component under test will break snapshot tests. It's literally just a test that says, "Is this render function still the same as it used to be?"

I'm not sure you understand how to capture snapshots at the correct level of granularity. If you have snapshots that are breaking for irrelevant changes, then by definition those changes don't need to be snapshotted, do they? Cut down the snapshot to only the relevant part of the rendered HTML so that when it fails, you know something broke.

Eg in htmx we can add a snapshot test for the pagination component I mentioned in this comment: https://news.ycombinator.com/item?id=42619553

This snapshot will break if I have a bug in my pagination logic implementation, and it's highly unlikely to fail for random irrelevant changes.

It would still break if you need to modify that output in any way. Need to add a class for styling? The snapshot breaks. Need to add a new hx-attribute? The snapshot breaks. It's not tied to the logic, it's tied to whatever markup you output. You've reduced the surface area of the problem, but not eliminated it.

> If you have snapshots that are breaking for irrelevant changes, then by definition those changes don't need to be snapshotted, do they?

You're so close to getting it.

> Need to add a class for styling?

How often? All the time? Or relatively rarely? For most projects, it's the latter. We are not constantly churning the styling.

> Need to add a new hx-attribute? The snapshot breaks. It's not tied to the logic

An `hx-` attribute is logic. That's the point of htmx.

> You've reduced the surface area of the problem, but not eliminated it.

That's a risk of any kind of unit test. You can always have false positives.

> You're so close to getting it.

That tests should be fixed until they're robust? I'm not a fan of the learned helplessness of the 'We couldn't figure out how to do XYZ, therefore XYZ is a bad idea' approach.

Do you have experience with snapshot tests? If not, you should try it out for a bit and see what we mean, you'll quickly run into the situation we described.

If you introduce a new feature and have a new button on the page, for example, the snapshot test will fail (by necessity, you're changing what's on the page) because the snapshot doesn't match the current version with the new button, for example. So, what you have to do is regenerate the snapshot (regenerating it will always make it pass).

The problem is in my experience, that these kind of tests are massively unreliable. So you either fiddle with tolerances (most testing libraries let you set a threshold for what constitutes a failure in a snapshot) a lot, or you manually have to hunt down and pixel peek at what might've happened.

As an example of what usually happens is that, at some middle step of the test an assert fails because some new code causes things to render slightly out-of-order or delayed in some way. Ultimately the final product is good and if it was an intelligent system it would give it a pass. The unit tests pass. Even the integration and E2E tests pass, but the snapshot tests fail because something changed. The chance that this test failure is a false positive is much, much higher than the chance of it being a legitimate failure, but let's assume it's legitimate like the good citizens we are and try to hunt it down.

So, you go through the snapshots, 1-by-1, setting breakpoints where you think things might break - note that this process by itself is painful, slow and manual, and often running snapshot tests on your local machine can break things because things get rendered differently than how they would in CI, which leads to an extra set of headaches - What happens here is that you're testing an imperfect reflection of what the actual underlying app is, though, because a lot or most of it will be mocked/hoisted/whatever. So sifting through what is a potential breakage, and what is just the quirk of the snapshot test is basically a gamble at best. You spin up the app locally and see that nothing looks out of the ordinary. No errors to be seen. Things look and behave as they should. You have your other tests, and they all pass. So, you chalk it up to a false positive, regen the snapshots, and go on with your day.

The next day you add some other thing to the page. Uh oh, snapshots fail again!

Rinse and repeat like this, and after the 50th time sitting there waiting for the snapshot to be captured, you decide there are better ways to spend your limited time on this mortal plain and just say "Fuck it, this one's probably a false positive as well" after taking a 2 minute look at the page locally before hitting the repacture command again.

I legitimately don't think I've ever actually seen a non-false positive snapshot test failure, to be honest.

Snapshot tests are even more sensitive to flakiness than E2E tests but flakiness is still a bug that can (and probably should) be fixed like any other.

As an example - the different browser you have running locally and in CI? That's a bug. The fix is to run the browser in a container - the same container in both environments. You can probably get away without this with an E2E test. Snapshot test? No way.

Ive seen people decry and abandon E2E tests for the same reason - simply because they couldnt get flakiness under control and thought that it was impossible to do so.

I dont think it's intrinsically impossible though. I think it's just a hard engineering problem. There are lots of nonobvious points of flakiness - e.g. unpinned versions, selects without order bys, nondeterministic JavaScript code, etc. but few that are simply IMpossible to fix.

Theres a big payoff if you get it right, too.

I’m not sure I’d agree. The HX attributes encode a lot of functionality and you want to check that they do the right thing together. You can test you get the right attributes in a response, but that’s only a proxy for the application doing the right thing, so you most likely still need the end to end tests.

The problem is that end to end tests are the hardest kind to write. At least if you have a frontend code base you can have some tests there and get some confidence about things working at a lower level.

> You just need to test that your endpoints return the right HTML piece. You don't need unit testing the frontend since you don't have that much logic there.

Only using the standard Django test client? I don't find this myself when I've had to work with HTMX code e.g. if you're using HTMX for your sign up form, it can be completely broken on the happy path and on form errors if the HTMX attributes are wrong, and the standard Django test client won't let you know, so you lose a lot of confidence when making refactors/changes.

You don't have to write your own using beautifulsoup. There are test frameworks like https://www.cypress.io/ and https://playwright.dev/ that work great there.
With the BeautifulSoup tests I can run 1000s of tests in seconds. Cypress/Playwright are wonderful for e2e tests, but not comparable to simple unit tests you'd have in React/Vue. I find that the BeautifulSoup tests are a decent middle ground.
I've successfully used (for 3+ years in multiple projects) an approach similar to BeautifulSoup's get_text() function to assert the whole visible text of a component. You can implement it in other languages with a few regexes.

One addition makes it an order of magnitude more versatile: a way to visualize non-textual information as text in the tests. For example add a data-test-icon attribute which contains the replacement text that should be shown in tests. Another method is to parse the HTML and write custom visualization for some elements, so that you get useful default visualization for at least form elements and such, without having to repeat the data-test-icon attribute every time.

See https://martinfowler.com/articles/tdd-html-templates.html#Bo...

I’ve done something similar, but using pandoc to convert the html to text, so tables and bullet points are rendered appropriately.
Why is that a good thing when testing a web app? You want to see if the browser is executing your code with the correct intent.

Seems very brittle and may not catch actual regressions browsers introduce.

But with beautifulsoup you don't test the interactions at all. You only test the rendered template which is nice, but doesn't tell you if any button actually works the way you expect.
I'm all in on Hotwire, which is pretty similar.

They're both fantastic expansions of what server-side rendering can do. They can't really do work as nice as what React can, but you can get perhaps 85% of React for 5-10% of the development time. And a big increase in usability of your app.

> 1. If you consider yourself a "backend developer" only and want to write the minimum amount of JS/TS.

This is a great point and should be underscored more. I think generally the HTMX vs React/Vue/Svelte argument gets undercut when people don't express their innate bias on which part of the stack they want to give more control to. HTMX is great if you're pro-expanding the server; JS Frameworks if you're trying to expand it from the application layer.

This was my exact experience - loved it as a backend developer wanting to build simple frontends with minimal JavaScript (and I still recommend it for many use cases) but when I then tried HTMX to build a more complex application I found that the complexity that would normally be handled by a JavaScript framework ultimately grew and shifted to the HTML and, surprisingly, the backend as well.

For example, error handling in complex forms. When you have React handling errors you simply return a 400 JSON response with fields and reasons, or some other error message, and React decides what to do depending on the context, which it knows. When this responsibility is moved to the backend you now need to track the request location, state etc. and find the right fragment, which very quickly turned the code into a mess.

I think the choice of backend is also important. I suspect that Java (Spring Boot) made using HTMX much less pleasant than it would have been with something else, especially when it comes to templates and routing. Using Java for HTML templates (Thymeleaf or any of the other popular libraries) is something I will never do again.

Edit:

The analogy with jQuery is interesting. I feel the same way about HTMX now as I did about jQuery ten years ago. I used to plug jQuery into every project even if it was just to select elements or whatever, but whenever I used jQuery entirely over the frameworks that were popular at the time (Ember, Angular) I ended up with way messier code.

> When this responsibility is moved to the backend you now need to track the request location, state etc. and find the right fragment,

Maybe not? I'm just returning a 422 JSON response with fields and reasons and I have a tiny bit of JavaScript in the frontend that just plugs them in to the form with the built-in Constraint Validation API.

https://dev.to/yawaramin/handling-form-errors-in-htmx-3ncg

> I suspect that Java (Spring Boot) made using HTMX much less pleasant than it would have been with something else, especially when it comes to templates and routing.

I strongly agree with that and created a library to help with those aspects: https://github.com/yawaramin/dream-html?tab=readme-ov-file#f...

> For my next projects, I will still use Django but with React/Vue for pieces that need interactivity

What's your plan for "plugging" these into your HTML? Web components?

Does Django have some kind of integration with Vite for hot reload during dev?

As I dont do frontend work, how do you "test" anything without an insane amount of browsers/hardware realistically ?

If I was to write tests, it'd be basically http get/post/put/delete requests and measuring the responses are what I expect.. how can HTMX be any different here ?

How do you "test" a button works without a browser engine ? Every browser engine ?

You throw headless browsers into your CI/CD pipeline and try not to think about how many resources you're burning.
Might work for a small project, but a nightmare for medium to large projects. Imagine Microsoft tests their Outlook (web app) like that.
Microsoft tests Outlook?
We do have pseudo-browsers written in pure js that you can theoretically use:

https://github.com/jsdom/jsdom

https://github.com/capricorn86/happy-dom

but they're about as reliable as you can expect: it's difficult to keep up the pace with the big three (or two) on standards compliance, and they usually don't even try.

So the only reliable solution is a headless Chromium, Firefox, and/or WebKit-based noname browser like the sibling says.

https://pptr.dev/guides/what-is-puppeteer

https://playwright.dev/

https://www.selenium.dev/documentation/

Love this.

The attitude of the htmx developers is highly commendable.

"Today many web developers consider jQuery to be “legacy software.” With all due respect to this perspective, jQuery is currently used on 75% of all public websites, a number that dwarfs all other JavaScript tools."

This argument is that jQuery is still very popular compared to JS frameworks like React, etc.

What about vanilla JS?

As someone who isn't that experienced with JS, my understanding is that modern vanilla JS is "about as good as" jQuery. i.e. if you don't need much JS these days, just choose vanilla JS.

That may or may not be the case (see https://youmightnotneedjquery.com/) but the fact remains that jQuery is used on 75% of all public websites.
Notice how the “modern” is almost always more verbose than JQuery.

JQuery might as well be a shorthand JS library.

I view JQuery as similar to C in some ways: It's been around forever, it's mature, and it works. It gives a good experience to get something up and running quickly: it's lightweight and simple.

But if you're working on bigger projects: It is possible, but have have to be very principled in how you use it, otherwise you're going to end up with either a massive spaghetti codebase and lots of edge cases in your app that breaks.

Alternatives like React and Rust may add more complexity upfront, but the improved structure and safety it gives has big benefits in all but the smallest projects.

Not so sure about that. You can easily write horrible code in React: Too complex, inefficient, and/or resource-intensive. If you don’t know the tools and have good theoretical programming knowledge, all code will be spaghetti code in the long run.
I'm no fan of React, but these aren’t equivalent. If you follow the rules, react (or any of its alternatives) will manage stateful changes like adding and removing components and event listeners. JQuery is more similar to doing manual memory management in C. It’s extremely easy to get it wrong and introduce leaks and other non-local errors.
React is also extremely easy to get it wrong.
Can you give an example? I mean I know you can shoot yourself in the foot with any UI framework, but jQuery has no way of managing state, everything just leaks by default. Unless they’ve added something.
I don't disagree, but this is not relevant for the vanilla JS vs. jQuery discussion, since vanilla JS has exactly the same problems you mention as jQuery.
That might be related to Wordpress including jQuery.
That website is (inadverently) one of the most effective marketing campaigns for jQuery. Some of the vanilla JS examples are atrocious.

What it doesn't show is that vanilla JS is not chainable (jQuery is).

What do you mean ?

  let result = "   hello jQuery   "
  .trim()
  .replace("jQuery", "javascript")
  .toUpperCase();
  console.log(result);
map, filter, ...

  let numbers = [1, 2, 3, 4, 5];
  let result = numbers
  .filter(num => num % 2 === 0)
  .map(num => num * 2)
  .reduce((sum, num) => sum + num, 0);
  console.log(result); // 12
Simple string

  let myStr = "This is a wonderful day.";
  let reversed = myStr
  .split("")
  .reverse()
  .join("");
  console.log(reversed); // ".yad lufrednow a si sihT"
  
DOM elements

  document.querySelector('#element')
  .classList.add('active')
  .classList.remove('hidden');
Using a class

  class Chainable {
    constructor(value) {
      this.value = value;
    }

    add(num) {
      this.value += num;
      return this; // make it chainable
    }

    multiply(num) {
      this.value *= num;
      return this;
    }

    getValue() {
      return this.value;
    }
  }
  let result = new Chainable(5)
  .add(3)
  .multiply(2)
  .getValue();
  console.log(result); // 16
Oops. You are right, I beg your pardon. Here's a working example.

HTML

  <span class="a b c"></span>
JS

  function getClassList(el) {
    let ele = document.querySelector(el);
    let list = ele.classList;

    return {
      add: function (c) {
        list.add(c);
        return this;
      },
      toggle: function (c) {
        list.toggle(c);
        return this;
      },
      remove: function (c) {
        list.remove(c);
        return this;
      },
    }
  }
  getClassList('span').remove('b').add('e').toggle('a');
  console.log(document.querySelector('span').classList);
Congrats you're reinventing jQuery. With a worse and more limited API.

Plus jQuery is one of the most battle tested libraries in the world.

That "ops" you made with classlist, you're bound to repeat these mistakes ad infinitum. And they can bite in subtle ways only your users might experience.

People rarely report broken websites unless they really need to.

I am truly interested in your arguments on why using chainable DOM Elements leads to less buggy websites.
You're the only one making that claim.

Plus using a homemade alpha version of jQuery written by one dev leads to more bugs, not less.

> That "ops" you made with classlist, you're bound to repeat these mistakes ad infinitum. And they can bite in subtle ways only your users might experience. People rarely report broken websites unless they really need to.

I think those two sentences are out of bounds, but I somehow get you. Yet I don't get the 'broken website' remark (took it condescending, or is it from experience?).

Mainly, I was replying to the affirmation that javascript is not chainable which is (imho) an indication of how one could get disconnected to the underlying lang by simply relying on libs such as jQuery (and I am thinking the same about htmx). Thanks for your reply!

Thanks again for a nice demonstration of having to reinvent the wheel to produce a poor-man's buggy reimplementation of jQuery.
Those stats are pretty meaningless. How many of those websites haven't been updated in the last 7 years? Not that there's anything wrong with that, but the decisions they made a decade ago aren't necessarily still the best ones today.
How is that meaningless? It seems that web users of the site at least find it acceptable and aren't complaining enough to the site builders that they feel the need to change the website. AKA the website is standing the test of time. That's kind of a huge bonus when it comes to saving money and time to the website maintainers.
The point is that if you were to start building a new website from scratch today, the best tools for you aren't necessarily the most widely used ones. You have the option to start with a clean slate without any baggage. There are no upgrade costs. There are no customers who will get inconvenienced. There is no inertia. You are in a very different position than someone who has a website with millions of lines of jQuery already in use.
Even with a clean slate, there's immense value in choosing something that you already know to be a tried-and-true approach - i.e. in choosing "boring" technology¹ instead of trying to be at the cutting edge.

Now if exploring the cutting edge is a goal of yours in and of itself, then by all means blow some of those innovation tokens on the new Reactangular.ts hotness. For a lot of projects, though, the goal is to get something out the door as painlessly as possible; jQuery and plain JS have (for better or worse) been the tried-and-true "boring" approaches, and HTMX (from what I can tell) seeks to be the similarly "boring" choice.

Obviously right now HTMX ain't the boring choice (because it's still pretty new), but a decade from now it could be. Having used it in a couple pet projects recently, it already does feel pretty boring (especially since it goes hand-in-hand with other boring strategies like "just use SQL" and "just use CGI scripts" / "just use classic MVC frameworks").

----

¹ https://mcfunley.com/choose-boring-technology

It’s functionally as good as jQuery.

However to this day I still find jQuery to be one of the nicest APIs to ever be used on the frontend stack. It is legitimately just more pleasant to write.

(Yes yes I am more than aware of how to shim a lot of it for vanilla JS)

"What about vanilla JS?"

Vanilla JS, as an experienced dev, is the best thing for now. You can write your proxy functions, and globally you get the control over every little thing.

I'd love to use HTMX at work. Sadly the security folks would probably balk at checking in JS code that uses eval(), even though you can disable eval at runtime in the HTMX config.

I thought about writing a script to remove all references to eval (and all tests relying on eval), but at that point it would probably be easier to just rewrite the library.

eval can be disabled at the CSP level, which is much better than at the source level (which can always be obfuscated, missed in a version update, etc)
It can be, but then you discover how marketing added lots of gtag and other content which is already full of eval ;)
> ...you can use as much or as little of it as you like... Stability as a Feature... No New Features as a Feature...

This is the way.

Having lived the alternative, I won't consider building anything significant on top of an abstraction that doesn't credibly promise these.

When the abstraction you've built on changes or fails, the thing you built breaks. When you choose an unstable abstraction, you're creating future bugs you'll have to spend future time on to resolve (and if it wraps the lower layer rather than sitting beside it, you have fewer options to fix them).

These aren't concerns for things that will be short-lived, or are small enough to replace if needed. But I've seen plenty of small and temporary things turn into large and permanent things when they end up being useful.

> ...you can use as much or as little of it as you like... Stability as a Feature... No New Features as a Feature...

Given my experience with node ecosystem, react, and nextjs, I am inclined to agree.

I agree about react and nextjs.

But the node ecosystem includes essentially everything that touches on javascript, both the bad and the good.

I don't think there are very many ecosystems that are guaranteed to have only good stuff. Regardless of ecosystem, the developer has to examine what is available and make wise choices.

I think the culture is so prevalent that I have to defend parent’s statement. Node itself, and npm which is a node project, are some of the worst offenders. It’s had abysmal stewardship imo, and one could argue this sets the tone for the ecosystem at large. Hack upon hack, config files of doom.

There are exceptions, but at this point the verdict is clear. It’s like the meme about Java being enterprisey and over-abstracted with factories. As far as stereotypes go, it’s true. (Or was, haven’t used it in forever)

I’m not even against JS, and much less the web. I think it’s the 7th wonder of the world. But the developer practices makes me want to tear my hair off.

There is a great way to combat this, use libraries you've reviewed to have proper design and implementation, then ignore the rest. People rely on libraries for the stupidiest shit, and also are really afraid to go against the current flow. If you're not doing TypeScript/VueJS/$POPULAR_THING you don't know anything about JS and you're a dumb developers, which of course is very wrong. And stop listening to recommendations from lifestyle developer streamers who most likely got paid to recommend whatever they're babbling about.
Till they change, see Svelte 3,4,5
Major versions that change basically everything should be considered different projects and require a re-review. I remember I did this early with react-router, and I think when they changed the public API for the second time, we forked it and left it as-is, because they made their goals apparent.

If Svelte version 4 and 5 are very different, then they're "SvelteV4" and "SvelteV5", both on version 1.0.0, in my mind :)

I quite liked svelte 4. Svelte 5 might be even better, but I'll probably never find out.

I won't touch it if I can help it. No matter how good it is, I'm fairly certain there will be a svelte 6, 5 will be abandoned, and whatever issues crop up in it will not be addressed unless I move to 6... probably just in time for 7 to come out. I know this because that's what happened before, repeatedly.

I don't know if htmx is actually any good, but they are saying all the right things.

> the verdict is clear

Not to me.

I know there's plenty of junk, but if you opt out of the node ecosystem in its entirety, you're essentially opting out of most of javascript development as well, which is a substantial part of web development.

That's your choice, but you're missing out on a lot of good and useful things... just in terms of software development but also in terms of meeting whatever your business needs are (if you're trying to make money).

Javascript static analysis tools can be very useful (like TS and eslint). app frameworks can provide routing, UI frameworks, UI controls, validation libraries, etc. that you would otherwise have to implement on your own.

These are all part of the node ecosystem. htmx is part of the node ecosystem. IDK, lumping it all together doesn't make sense to me because there's a lot lost and little gained.

Nextjs is a nightmare. React is pretty good nowadays imo.
"Pretty good" is good enough for most developers, but React has some issues that reduce developer experience (having to do your own memoization and a lot of hidden complexity that can impact performance) that require a huge engineering effort to solve (React Compiler has been in the works for years).

I'm also not sure whether the move from class- based components to functional components with hooks should've been part of the "regular" React or if it would've been better to do a hard break (e.g. a version 2.0), but I think the collective front-end developer world is still traumatized from the AngularJS -> Angular transition.

Coming from AngularJS then Angular then Vue, a bit of Svelte, which I didn't like, to React. I tried React before and hated it.

Yes, it's not perfect but right now it's pretty good. I like composables, there are a few gotchas to get used to, but that's everywhere, when in Rome.

Vue is better IMHO, but doesn't have the graphql client I require and there is more momentum in the React ecosystem right now. More innovation is happening in the React ecosystem than elsewhere.

Angular is still stuck in the past. Ngrx as the only state management library, full of boilerplate and the annoying rxjs. One doesn't simply with Angular.

Svelte is too barebones for my taste. Manually doing form validation and rendering for instance. If it had a larger ecosystem it would be great, but it doesn't. It for the purists who like reinventing the wheel. Of course it has other good uses as well, it's fast, much faster than React.

When I used React, I use high level libs where I don't have to manually do stuff. But when I do it comes naturally, it's a simple learning process.

I prefer logic in templates from Vue over the brackets and conditions of React. I like Angular's templating and 2way binding. I don't like Reacts aliases, like having to write className instead of class.

But in the end productivity is what matters for me, and React is pretty productive and has a large ecosystem. But finding the right packages is a journey.

React SSR is a horror story. Vue's especially with Quasar is a love story with butterflies and perfume. Great tooling.

It's good enough and I'm actually enjoying to work with it, maybe because it's so new to me and learning new things makes me happy (like when you're young you're happy because there is so much new stuff constantly, which studies found that it makes people happy).

That they removed the ability to embed it without compilation from v19 on is a very bad move though.

>But I've seen plenty of small and temporary things turn into large and permanent things when they end up being useful.

My experience is that probably more than 9/10 temp projects end up forever projects. My goal is never to work anywhere again that insists on just get it done quick and dirty "its temporary" ever again.

I don't remember where I stole it from but at work any time we're discussing something temporary I like to drop in a "remember there's nothing more permanent than a temporary fix" and it usually gives us at least a few more minutes of considering things carefully before pulling the trigger. Makes me feel better anyway.
I have a wood block wedged between my car's battery and battery mount because the new battery was smaller and I couldn't get the mount to adjust down. I cringe whenever I get the oil done but I don't fix it because it is good enough. I do feel dirty about it and every other weekend I think, "I should install a proper sized mount." But the battery doesn't wiggle. It works. It is a temp fix that has been there half a year. Code is even less visible to most, so even more out of sight and out of mind.
In modern development best practice, you'd refactor that bug fix, by moving the block of wood to underneath the battery where you can't see it any more. (And writing "node_modules/" on it with crayon...)
This perfectly captures the node_modules / JavaScript experience, because being underneath the battery would also stop it from working as intended and the battery would be loose again.
Good. For a couple of seconds, I feared something like "The next step of our wonderful journey...".
> No New Features as a Feature

No new features is such an underrated feature. It's funny sometimes when people see some Common Lisp or Clojure library with no commits in the last X period of time, and people immediately come to the conclusion that something must be wrong.

In the world of AI tooling, "completed" should have a huge advantage over libraries with lots of churn. Maybe a positive side-effect of new AI tooling is that there will be competitive pressure for libraries to reach a completed, no-new-features state.

This is just people's subconsciousness fighting against the rolling progress. It's trying to avoid learning new things and trying to preserve the status quo where you can keep rolling using the already acquired knowledge. It's anti-thetical to being a hacker.

The modern way is to use LLMs to auto generate all this code and do some small corrections in the process. So you wouldn't have to worry about the underlying tech and would only be concerned about the core functionality and actual mechanics of the product rather than being interested and spending efforts on memorization of the specific instructions for the machine. The whole evolution of the programming languages is a process in that direction and new technologies that were embraced by the newer generation like React and Vue.js is the way to go. You can't run geosites forever.

The philosophy of a tool like htmx encourages the opposite of "avoiding learning new things". The reality is that there is not often anything that is truly novel. We waste time by failing to recognize patterns and abstractions that persist over long periods of time and in many cases that are even foundational knowledge.

A foundational fact by definition does not need to be constantly scrutinized as if it were not. Rather it is something that can be relied upon stably until such a time that a change in a core assumption forces us to reevaluate the foundation if and when that scenario occurs.

It’s about using the right tools for the job. FAANG and developer advocates made the web needlessly complex for most people. The over-engineered tools and frameworks became the “default” way of programming for the web, loosing some strong key features that were good about it: simplicity, transparency, and speed.
> It's trying to avoid learning new things and trying to preserve the status quo

Well, yeah. Sometimes the status quo is good. Sometimes you don't want to learn how to do simple async page updates for the thousandth time.

Because many of us here have been there, done that. Over dozens of years. With dozens of libraries.

It's a hamster wheel. It's boring. It's pointless.

In the end, if your website/app does what HTMX is good at, just use it.

I learn dozens of new things every day as a solopreneur SaaS guy. I don't want to relearn how to make async page updates ever again, unless there is a very, very compelling reason to do so.

> The modern way is to use LLMs to auto generate all this code and do some small corrections in the process.

it sounds a lot like correcting the work of a junior developer and it's definitely not what I want to do for a living.

> new technologies that were embraced by the newer generation like React and Vue.js is the way to go.

IMO, anything that requires a build step to the browser runtime is at best a temporary solution waiting for a web standard and at worst a regression.

I am a fan of this approach. About to launch a SaaS now and htmx powers much of the interaction so far.

Tools like htmx make it easier for solo founders and small teams who don't have the bandwidth or the desire to manage all the churn. Keep the dependencies tight and ship!

>In particular, we are trying to push the ideas of htmx into the HTML standard itself, via the Triptych project. In an ideal world, htmx functionality disappears into the web platform itself.

I have been calling for this for a very long time even during pjax era. I hope that is not only an ideal but a realistic pathway forward. Chrome / Blink or Safari / Webkit. If we could just get one of them to implement it as experimental feature. How could we push this forward?

JPEG XL and HTMX in HTML, along with some sort of basic rich text editor for everyday writing is what I want browser to be included by default.

People are commenting about "no new features as a feature", and I agree, but even better is this:

> People shouldn’t feel pressure to upgrade htmx over time unless there are specific bugs that they want fixed

Frickin A! Nice to see somebody pushing back against the trend of "if you haven't updated your software in the last five minutes you're on an unsupported configuration".

So if you have a project that uses a (even small) number of libraries, how to you keep track of being affected of some specific bug of some library?
You submit a bug report and (assumedly) get a fast response because they explicitly prioritize fixing bugs over adding new features.
I guess in most cases you will be affected by bugs that you did not notice let alone report.
More reason to prefer a more deliberate release cycle! Focusing on security and stability restricts the area available to bugs significantly more than chasing hot new features all the time.
And also helps make for minimal changes when you ultimately find you need to move on from your current version. Probably why a lot of people stick with emacs/vim/whatever over every new fangled editor that comes out
A) New library versions are roughly as likely to introduce new bugs, as they are likely to fix old bugs. (If not, why are there still so many updates, you should be running out of bugs ...)

B) If you run into a bug, update that library, then look into fixing it and offering a PR with the fix. Easy-peasy.

Compared to: oh this is a bug in a library that's fixed in an update ... but then we need to update another library it depends on, but that requires an update to nodejs, but that requires us to update some other libraries, which introduce a new more serious regression, so we can't unless we re-write to remove that dependency ...

The classical joke:

Why programmers like cooking: You peel the carrot, you chop the carrot, you put the carrot in the stew. You don't suddenly find out that your peeler is several versions behind and they dropped support for carrots in 4.3

Anyone got a good feel for the htmx accessibility story at the moment?

I'm interested in using it more, but I want to be 100% confident that I understand how to get htmx sites to work well with screen readers. I worry about things like fetching new data into a page not altering the screen reader user in the same way as refreshing a page completely would.

I'm not interested in whether or not htmx uses the correct ARIA attributes - I want to be confident that those ARIA attributes (or similar) do the right thing.

My ideal is still to use JavaScript libraries where the documentation not only describes how they work with screen readers, but is accompanied by video evidence showing the experience a screen reader user gets for different problems solved by that library.

Handling ARIA attributes is out of scope for HTMX. It is your responsibility to include ARIA attributes on the HTML you return and swap/transclude.

As for handling dynamic content for screen readers, focus management is already a thing, and is in the scope of browser standards and the HTML your backend returns. As before, it's your responsibility to manage this. HTMX will neither help you nor get in your way.

HTMX merely extends hypertext functionality to its (mostly) natural conclusion. It is not a component library, or a framework for building components, or a site building framework, or...

You can use other tools to enhance and audit accessibility, but their use is orthogonal to HTMX. I think web developers in general are very used to frameworks abstracting a ton of complexity, but HTMX is not a framework so much as a standardized set of tools for specific low level problems, it is not a one stop shop.

In that case it would be great if the HTMX documentation included worked examples and guidance for how to do this.

Leaving accessibility up to the end developer feels like a genuine missed opportunity for me here. One of the great things about NOT using a JavaScript library is that you can rely on the browser's default accessibility features for forms and links. Those benefits are the thing I care most about when considering HTMX or jQuery or React or Vue or similar.

> In that case it would be great if the HTMX documentation included worked examples and guidance for how to do this.

You can refer to the WAI-ARIA standards.

> Leaving accessibility up the end developer feels like a genuine missed opportunity.

This doesn't compute for me. What would HTMX even provide? It's a set of attributes that extend the behavior of form submission to other elements and all request methods.

> HTMX or jQuery or React/Vue

These aren't the same kinds of tools. They address fundamentally different things. Handling ARIA automatically for you isn't in scope for any of them.

Referring to the ARIA standards doesn't help me answer the more important question: will what I'm doing work in screen readers or not?

I feel completely starved of information here. I care about accessibility. I want to build a web page where clicking on a tab refreshes a subset of that page... and I still can't find a really good guide on how to do that in a way that works in screen readers, that's accompanied by a video (ideally multiple videos, one for each common screen reader) showing the experience I can expect my users to have from that pattern.

HTMX actively encourages that pattern, so I'd love to see the project also embrace helping developers do The Right Thing with regards to the accessibility of that pattern.

> will what I'm doing work in screen readers or not?

Why not try it? But also, why wouldn't it?

Pointing at the ARIA spec as a way of writing code that’ll work with all assistive tech is like pointing at the HTML and CSS specs circa 2005 and saying that following them will make your site work in all browsers.
Try in which screen reader?
iOS has a good one.
The ones you want to support. htmx unfortunately can't tell you what that is.
> I feel completely starved of information here. I care about accessibility. I want to build a web page where clicking on a tab refreshes a subset of that page... and I still can't find a really good guide on how to do that in a way that works in screen readers, that's accompanied by a video (ideally multiple videos, one for each common screen reader) showing the experience I can expect my users to have from that pattern.

I completely agree that this is a pain point. In general, high quality documentation is lacking. I am not however convinced that this is a problem that can be automated and abstracted away. Neither am I convinced that it's one we should necessarily try to hide. It won't win me any favors but I think the issue here is simply an endemic skill and knowledge gap. Shifts in culture via higher educational curricula and stated quality attribute priorities within companies will do more good here than anything else.

Accessibility is a quality that needs to be built in from the start. The good news is that provided your HTML is sane and not a mess of class tagged DIVs, or you're building a pretty straightforward document-like navigation/content/etc site, you really only need to declare attributes to handle the places you do something unusual. The defaults are generally correct.

Much of this "unusual" behavior that needs special treatment is within custom components (e.g. a custom date selector widget with plenty of invisible divs used for layout of the calendar days can be inscrutable to a screen reader without hinting) and is the responsibility of component library or framework producers. Some issues here run deeper, like properly correlating ARIA attributes in shadow and light DOM. But that being the case, such component libraries aren't even necessarily suitable for many sites (either too complex, or make too many mismatching assumptions).

The bulk of the remaining accessibility attribute slinging that needs to happen has to do with the overall site layout (especially reactive layouts). I don't know of any framework that will handle this for you in a satisfying way for anything sufficiently sui generis. I think the tough but true answer here is "the people building the site should have at least skimmed the WAI-ARIA standard, and be using an auditing tool, and know what to be thinking about as they design the site from the start".

Everyone needs to read this spec and then live and breathe its tenets … sure. This reminds me of the time when we fixed the footguns with C by making everyone into better developers.

That guy is asking you if replacing a part of the html with some other html alerts screen readers to the change.

It’s a reasonable question and you could share what you know about how screen readers react when this replacement happens. You could write some documentation on how to alert them, some best practices to follow.

Instead you say read the fucking manual, as if that helps. You put on a veneer of caring for accessibility but it seems you care about the “purity” of htmx more.

Agreed.

Frontend frameworks often do spend a lot of time thinking about the accessibility concerns associated with client side routing, so it's not absurd to consider this question in scope for a frontend library that handles DOM updates.

See for instance this 2019 study by Gatsby: https://www.gatsbyjs.com/blog/2019-07-11-user-testing-access...

Or even the modern Next docs on route announcements: https://nextjs.org/docs/architecture/accessibility#route-ann...

Some of this will have to be bespoke work done on a per-site basis, but I'm not sure I'm comfortable with the idea of completely punting this responsibility to developers using htmx, even if it does make philosophical sense to say "this is scope creep", because ultimately users with disabilities will end up being the ones whose experience on the web is sacrificed on this altar of ideological purity.

> That guy is asking you if replacing a part of the html with some other html alerts screen readers to the change....It’s a reasonable question

Of course it is, but it's like asking if using React.js will prevent SQL injection attacks. They are orthogonal things. Making screen readers announce things is controlled by the HTML you write, not by htmx.

You're wrong, and in a pretty obvious way.

It's actually like asking what a database library will do to prevent SQL injection attacks. And the answer is simple - "don't do string interpolation yourself, instead use the `(?, ?)` syntax". If you use that the SQL escaping will be taken care of automatically by the library. If the database library said something idiotic like "read the spec and implement your own SQL escaping logic" it would be a dereliction of duty.

Make no mistake, a frontend library like htmx has a responsibility to not break the front end from an accessibility perspective. If existing screenreaders break when you replace HTML then the htmx approach is broken and htmx needs to address that.

Conceptually htmx is closer to Fetch API + set innerHTML than it is to a 'frontend library' like React.js. Do people complain that setting innerHTML from JavaScript breaks screen readers? Of course not, they set up aria-live regions correctly as shown in plenty of accessibility documentation. htmx can't make the decision for you what your aria-live regions are and what text should be read out when the content changes, you need to decide that yourself.

EDIT: here's the one mention of `aria-live` in the React.js codebase defining it as a valid ARIA attribute for ReactDOM: https://github.com/search?q=repo%3Afacebook%2Freact%20%22ari...

The one mention in Vuejs core to define its accepted values: https://github.com/search?q=repo%3Avuejs%2Fcore%20%22aria-li...

The one mention in the Svelte runtime defining its accepted values: https://github.com/search?q=repo%3Asveltejs%2Fsvelte%20%22ar...

Do people go after these frameworks saying they need to handle breaking screenreaders by dynamically updating content? Of course not. Setting live regions is the responsibility of the web page creator, not the framework.

Yes, I do go after those frameworks saying they need to at the very least help their users understand what they should do. I'm disappointed by any JavaScript library or framework that doesn't provide good documented examples for this, which is almost all of them.
Simon don’t waste your time with this guy. I thought he was affiliated with htmx but he’s just some jerk off trying to prove he’s “right”.
I encourage you to read the guidelines and familiarize yourself with what is acceptable in HN comments: https://news.ycombinator.com/newsguidelines.html
You're right, thanks for the reminder.

Simon don’t waste your time with this guy. I thought he was affiliated with htmx but he’s just some dude trying to prove he’s “right”.

Being affiliated with htmx or not doesn't change basic facts about web accessibility :-D Go look at the links I posted, look for the issues people filed against the repos claiming that their dynamic content updates break screen readers. There are zero. People understand how web accessibility works and what responsibilities lie at which parts of their stack.

Now if you say that component frameworks like shadcn/ui or whatnot should implement accessible behaviours and patterns, I am 100% with you on that. But React/Vue/htmx are at a lower level, they can't decide those things for you.

EDIT: sure enough, someone filed an issue with shadcn/ui that it does not announce something properly in screenreaders: https://github.com/shadcn-ui/ui/issues/4209

"It won't win me any favors but I think the issue here is simply an endemic skill and knowledge gap."

My problem with that is that, as you can hopefully see, I am very motivated to learn how to do this... and yet I have not managed to learn it.

"Learn how to do it" only works if there are clear and obvious resources we can point people to that will help them learn what the need to learn. The ARIA spec is not that.

This also feels like an inherently solvable problem, which is why I always take any opportunity to put it in front of people that might feel incentivized to help solve it.

Oh yes, I can see :)

And yes, I agree it is not the clear and obvious resource we can point people.

We DO need better "guide" format documentation, rather than dry technical reference. Nearly everything I've seen online is in very poor shape or outright wrong.

I share your feeling that it is solvable, and I also hope that people will help solve it.

But I'm sure of one thing: the people who write that documentation will be familiar with the specifications and refer to them (among other sources) while writing.

An "Accessibility Book" (like sections of the Python and Django docs, or the Rustonomicon for unsafe Rust) would be a fantastic resource and I hope someone writes it.

> "Learn how to do it" only works if there are clear and obvious resources we can point people to that will help them learn what the need to learn.

There are. Start with MDN. There is no more clear and obvious resource than this: https://developer.mozilla.org/en-US/docs/Web/Accessibility

There was a time when I didn't know anything about web accessibility. But I learned by reading, trying out small experiments, and using a screen reader to check my work. If I can do it, you can certainly do it.

After a while you face issues like 'Why isn't the screen reader announcing the dynamic content update', you search for solutions, and you come across incredibly helpful content like this: https://tetralogical.com/blog/2024/05/01/why-are-my-live-reg...

> This also feels like an inherently solvable problem

It shouldn't, especially if you don't know anything about web accessibility. It's hubris to think that something we know nothing about should already have been solved, why hasn't it? Is everyone else just an idiot? No, of course not. It's a complex and nuanced problem. Not the basics like always put an `alt` attribute in your `img` tag, those things are easy. But when you insert dynamic updates with JavaScript into the mix, it gets more complex.

The thing I was describing as a solvable problem was the lack of easily discoverable, clear tutorials - especially for the various libraries and frameworks that encourage patterns like updating small areas of a page that can cause problems.
(comment deleted)
I think what they are trying to say is that it has very little to do with htmx or react of whatever framework. None of it can handle accessibility automagically. Its like asking if it can write html for you - its different problem and a skill. But skills in accessibility apply to all frameworks.
> I feel completely starved of information here. I care about accessibility. I want to build a web page where clicking on a tab refreshes a subset of that page... and I still can't find a really good guide on how to do that in a way that works in screen readers

More generally, I often see people calling others "lazy" for not making websites accessible, but I personally found it hard to get my head around the WCAG recommendations, and I work with designers/developers all the time that don't know how to follow the WCAG recommendations even when you point them to documents and tutorials.

It's like nobody wants to admit it's difficult, and that's not even getting into screen readers still having many inconsistencies for basic UI patterns.

There are some sites that try to document what works and doesn't in different screen readers (e.g. https://a11ysupport.io/tests/), but even then it's still not easy knowing what to do and I don't know of an authoritative up-to-date site.

> I work with designers/developers all the time that don't know how to follow the WCAG recommendations even when you point them to documents and tutorials.

> It's like nobody wants to admit it's difficult, and that's not even getting into screen readers still having many inconsistencies for basic UI patterns.

Accessibility IS hard.

It feels sometimes like nearly everyone involved thinks they'll just read a few good blog posts and know how to make sites accessible. Then the struggle is due to not having read good enough blog posts.

Everyone wants a quick "fix" to a lack of education. Nothing replaces familiarizing one's self with primary source specifications, and most crucially, spending significant time trying out real screen readers.

(comment deleted)
> > In that case it would be great if the HTMX documentation included worked examples and guidance for how to do this.

> You can refer to the WAI-ARIA standards.

Every time someone asks for concrete a11y advice for concrete situations, some joker refers them to WAI-ARIA. This is ridiculous! That document is extremely hard to parse, and it offers absolutely no guidance wrt which parts matter the most, or, say, how the various real screen readers used in the wild behave. Please stop doing this. Accessibility is hard to get right! Making people feel like they're idiots for trying is very unhelpful.

This makes me think that we all need this tutorial to get rapidly on par and ready to read the whole spec
I’m not in a good place to check but what the various AI tools recommend?
> That document is extremely hard to parse, and it offers absolutely no guidance wrt which parts matter the most, or, say, how the various real screen readers used in the wild behave.

No, but it does enumerate what is available which is the starting point for figuring out what is relevant to your use case.

If you want tutorials or guides relevant to your particular use case you can seek those out, but to understand them you will need familiarity with the set of available attributes and where they are or are not permitted.

Many (most?) tutorials online have flagrant violations of the specification. We need better ones that actually emphasize understanding WAI-ARIA and not cowboy markup recipe books.

> Please, stop doing this.

No, I will not stop telling people to familiarize themselves with the primary reference material. Reading technical documentation and specifications relevant to a project is not an optional step.

It is not complete in the ways you describe (actually testing real screen readers is crucial), but it is absolutely essential reading to begin with.

> Reading technical documentation and specifications relevant to a project is not an optional step.

Well, I'm competent at HTML and CSS yet I never properly read the HTML or CSS specs either. Specs are generally a terrible place to learn a technology.

I simply don't understand how it's possible that the people who seem to care most about accessibility also seem to deeply, strongly believe that doing good accessibility ought to be very hard and time-consuming, and you don't deserve to call yourself a proper web dev without going through the rites. It's... not very accessible!

> Well, I'm competent at HTML and CSS yet I never properly read the HTML or CSS specs either.

I would strongly recommend you do! Most web developers are unaware of a good deal of just what all is available to them in those specs (especially HTML).

Are you talking about the specs? The stuff on https://www.w3.org/WAI/ARIA/apg/ seems pretty scrutable to me.

As for "real screen readers", yeah. There needs to be a caniuse.com for assistive technology.

> it would be great if the HTMX documentation included worked examples and guidance for how to do this.

The htmx documentation does include examples with accessibility guidance. Eg https://htmx.org/examples/bulk-update/

> The server will bulk-update the statuses based on the values of the checkboxes. We respond with a small toast message about the update to inform the user, and use ARIA to politely announce the update for accessibility.

If you check the Server Requests panel it also shows the responses and the ARIA attribute they include.

EDIT: I've submitted a PR to fix the notification toast announcement, with this the screen reader announces the notification correctly: https://github.com/bigskysoftware/htmx/pull/3112

The key is to mark all live regions statically before doing any htmx requests, then injecting the response HTML inside those regions. Then they are announced by the screen reader. This is nothing special to htmx of course; every app needs to work the same way.

> I worry about things like fetching new data into a page not altering the screen reader user in the same way as refreshing a page completely would.

Isn't this more of a general browser question that would apply to any website that uses Javascript to load page elements?

How would using HTMX (as opposed to any other library, or plain old Javascript) affect the answer to the question?

Yeah, any website that uses JavaScript to load page elements needs to solve this. My hope is that a library like HTMX can help reduce the friction in implementing the best possible patterns for doing so.
See the proposed moveBefore API [1] which is meant to solve those issues at the platform level. In the meantime, htmx has their morphdom extension, which I’d say is a must when replacing any page content with interactive elements within. Aside from that one major gotcha, the main issues with htmx are the poor accessibility of the examples in the docs [2]. In particular seeing so much ARIA without the corresponding keyboard support.

[1] https://htmx.org/examples/move-before/ [2] https://github.com/bigskysoftware/htmx/issues/1431

Hey Simon, maintainer + article co-author here.

tl;dr htmx is better than a lot of alternatives, but Simon is right, it can improve this story and it has a responsibility to do so.

As a framing device: any interactivity that is not described with HTML is interactivity that someone is responsible for making accessible (which you correctly pointed out). Unlike JS frameworks, htmx encourages the developer to solve problems with HTML first, so the inaccessible surface area that the developer has to worry about is going to be much smaller on htmx-based applications than it is with JS-based applications. That's a pretty strict win from where a lot of the industry is right now.

That having been said, I agree with you (and disagree with a lot of our defenders in the comments) that thinking about this is in-scope for htmx. In fact, I'm a firm believer that libraries are exactly where responsibility for implementing ARIA attributes live. The average web developer should not have to think about this at all—they should be able to use declarative abstractions and trust that they are annotated correctly for screen readers. This is the only system that scales, and htmx should adhere to it as much as possible.

Ideally, htmx would just add the polite notification attribute to the elements it processes, and give an easy way to customize that. I think it's basically possible to do this in a backwards-compatible way (first as an extension) that aligns with the maintenance strategy outlined in this essay. And I do think we can improve the documentation as well.

I'm thrilled to hear you're thinking about this. I really like the philosophy of the project, very happy to hear that reducing accessibility friction is a value you care about too.
I would argue that frontend libraries like htmx and React are not the place to build in ARIA attributes patterns/behaviours. In fact, none of the Big Ones do anything specifically w.r.t. announcing changes. See https://news.ycombinator.com/item?id=42625070

What would be the appropriate place, imho, would be component frameworks that are built on top of htmx. FastHTML is an example; they already have htmx integration and they talk about server-side components. If we look at a popular one in React, this is what they do: https://blog.logrocket.com/aria-live-regions-for-javascript-...

Thinking about it in terms of dream-html[1], it might look like:

    let announce msg =
      p [
        class_ "announcement";
        Hx.swap_oob "innerHTML:.announcement";
        Aria.live `polite;
      ] [txt "%s" msg]

    (* POST /purchase *)
    let purchase request =
      let thank_you_fragment = ... in
      Dream_html.respond (
        (* Join fragments together *)
        null [
          thank_you_fragment;
          announce "Your purchase has been successful!";
        ]
      )

[1] https://github.com/yawaramin/dream-html
This is one reason I created https://alpine-ajax.js.org. A few years ago there were a lot of examples in the HTMX documentation that discouraged accessibility and progressive enhancement. Stuff like like clickable <div>s, ignored keyboard focus, lack of screen reader announcements. There’s been some improvement latel, but I still think the library has a lot of foot guns for new web developers.
Thank you for alpine-ajax! It's amazing as an HTMX-lite or HTMX-just-right in many many use cases.
I understand screenreaders have a set of standards, aria tags etc - but are the next generation of AI screenreaders (I’m sure some already use AI?) going to replace the need for these tags, and just read a page as a human would?
I'm huge a supporter of the HTMX philosophy. I highly recommend reading Hypermedia Systems especially for people that are just beginning doing web development. I've purchased the book and it was a wonderful read especially for its explanations and pragmatism.
(comment deleted)