I have a question towards HTMX users about something I never quite understood as an outsider: How do you ensure IDs don't "drift" over long periods of development? Is it possible to check for this at compile time or is it a "just be disciplined / write a lot of tests" sort of thing?
Example, so that you get what I mean: Let's say I have a button that swaps an element with a particular ID defined in my templates. Some other colleague comes around (or me if I'm being scatterbrained) and edits the target of this swap. Is there any mechanism that will warn me that #particular-id is now #some-other-id or am I borked unless I have made tests particularly for this element?
I am regrettably very React-brained, where I rarely ever have to mess with IDs and TypeScript catches most of the obvious mistakes, so I lack the immediate intuition to figure out how one would go about mitigating this.
I can provide a comment from my own experience, having used HTMX for some years while also having spent many years using React.
Target drift is indeed a problem that can occur. HTMX is not compiled so there are no automated checks. Tests can go a long way to cover this issue but you're still at the mercy of discipline and exhaustiveness.
However, there are aspects of how HTMX is meant to be used that should further clarify your question.
Targeting by id is not the only way to target elements. In the context of swapping DOM elements that are close to the trigger, I'd reach for other selectors like find, closest, this, etc than an id. Nonetheless, the elements behind these selectors can also change so you still have target drift.
HTMX argues for an implementation designed around locality of behaviour, meaning you'd implement an interaction such that you can see right away how things work out. Yet, this is somewhat contingent on the affordances that your server has for generating and returning markup.
For things that need updating beyond that locality, and disregarding out-of-band-swaps (which are bound to target drift too), I've turned to using custom events or response headers to handle cascading effects.
Obviously, this is way different to the reactivity model that React and others use. HTMX is not that and you'll be disappointed if that's your expectation. I like HTMX for certain projects and use reactive libraries instead where it makes sense. These are not mutually exclusive either; you can delegate interactions/elements that require more reactivity to a reactive library and communicate over events.
That being said, my experience working with developers who only know React or the reactive model is that they'll find it difficult and counter intuitive to use HTMX, and even more so to combine it surgically with a reactive library / plain Javascript where necessary. In a project in which I participated Vue was added progressively until we ended up moving everything over to it when requirements for reactivity where such that it made sense to do so. The rest of the team was overjoyed when HTMX was removed, though HTMX did a great job to carry the project up for over a year while the product found product/market fit and now had enough traction to justify growing the team.
I mean, as someone who uses htmx, three parts to that answer:
I don't use htmx for massive sprawling interactive apps. It's not a good fit for that. So I don't know this has ever actually come up.
But I also don't really use IDs unless I'm replacing several thing at once. You can always just target this or things like closest .classNameHere and equivalents, in which case this doesn't apply.
And to the extent that it would apply, in any large-enough code base, I almost always have linters to prevent this kind of thing for CSS reasons (at least if I'm not using something like BEM or SMACCS or whatever the hotness is right now).
tl;dr: if you're doing something big enough where this would actually suddenly be A Thing, I personally would really say it's time to look at Svelte or React (or maybe Unpoly if you're really set on a mostly-static approach). I think htmx is great at its niche, which is basically web sites with interactive bits. I don't think htmx is great for complex interactive apps, and IMVHO you're gonna have a bad time trying to shoehorn it into that world.
I agree with most of this but I would challenge your last statement. HTMX can be great for complex interactive apps too if most of the interactions involve server round-trips and client-side state is not, as you state, sprawling.
For an application that does most of its work on the client-side then yes, HTMX is not as appropriate.
Also, funny that you mention BEM or SMACCS being the current hotness. They were hotness when I started doing web development back in 2013 :)
I think that's fair. I've just never (personally!) been in a situation where I had a complex interactive app and the state would be pleasant to handle server-side, but I know they exist. (E.g., there was actually a great post on here a couple of months ago where someone redid a sign-up wizard as server-side logic, and talked about how that even enabled things like people finishing signup months after they started. I don't recall them saying they used htmx in there, but it'd have been a good fit.)
Not defending that a whit, but at my day job, where I'm...uh...super strongly encouraged?...to use LLMs, I've had this pop up when the prompt is something like
Do the prep for the new release. The docs are <wherever the docs are>. Make sure to cut tags, run the release job, and update the release notes.
and have it show up that way. That said, I literally never let Claude commit for the same reason I don't just YOLO patches that hit my inbox onto main, so it wouldn't be obvious I'd done that.
Note that we are not marking 4.0 as latest in NPM because we do not want to force-upgrade users who are relying on non-versioned CDN URLs for htmx. Instead, 2.x will remain latest and the 4.0 line will remain next until some point in early 2027. The website, however, will reference 4.0.
Two things here:
I don’t think this makes any sense. If they suggested unversioned URLs in the past… well, that was a mistake. But even apart from that, I just don’t believe that waiting six months before changing it is going to change much. People that are using public CDN URLs are unlikely to update their version numbers, because they will have no automated channel for noticing it. Ultimately when they switch it over, it will be just as much a breaking change and I strongly suspect will affect approximately the same number of people. Really, it’d be better if you could opt out of allowing versionless/latest URLs on the CDN. As it is, in the mean time they make it so that npm install htmx.org gets you the wrong version!
You should never deploy things like this to production using public CDNs. Copy the file(s) and host them first-party: especially where it is just a single file, the difference in effort is negligible, and you get a more reliable, trustworthy, and faster result. There are no valid reasons to use a public CDN for anything beyond quick experimentation, since five or six years ago when Chromium and Firefox adopted cache partitioning (Safari did it in 2013). Honestly, the fact that htmx installation instructions start with public CDNs with no mention of why deploying in that shape is a bad idea has always turned me off it.
jamesgecko | 9 hours ago
I was confused about the jump from 2.0 to 4.0. Apparently this is to fulfill a promise that there would never be an htmx 3.0.
https://htmx.org/essays/the-fetchening/
nemin | 12 hours ago
I have a question towards HTMX users about something I never quite understood as an outsider: How do you ensure IDs don't "drift" over long periods of development? Is it possible to check for this at compile time or is it a "just be disciplined / write a lot of tests" sort of thing?
Example, so that you get what I mean: Let's say I have a button that swaps an element with a particular ID defined in my templates. Some other colleague comes around (or me if I'm being scatterbrained) and edits the target of this swap. Is there any mechanism that will warn me that
#particular-idis now#some-other-idor am I borked unless I have made tests particularly for this element?I am regrettably very React-brained, where I rarely ever have to mess with IDs and TypeScript catches most of the obvious mistakes, so I lack the immediate intuition to figure out how one would go about mitigating this.
ggpsv | 11 hours ago
I can provide a comment from my own experience, having used HTMX for some years while also having spent many years using React.
Target drift is indeed a problem that can occur. HTMX is not compiled so there are no automated checks. Tests can go a long way to cover this issue but you're still at the mercy of discipline and exhaustiveness.
However, there are aspects of how HTMX is meant to be used that should further clarify your question.
Targeting by id is not the only way to target elements. In the context of swapping DOM elements that are close to the trigger, I'd reach for other selectors like
find,closest,this, etc than an id. Nonetheless, the elements behind these selectors can also change so you still have target drift.HTMX argues for an implementation designed around locality of behaviour, meaning you'd implement an interaction such that you can see right away how things work out. Yet, this is somewhat contingent on the affordances that your server has for generating and returning markup.
For things that need updating beyond that locality, and disregarding out-of-band-swaps (which are bound to target drift too), I've turned to using custom events or response headers to handle cascading effects.
Obviously, this is way different to the reactivity model that React and others use. HTMX is not that and you'll be disappointed if that's your expectation. I like HTMX for certain projects and use reactive libraries instead where it makes sense. These are not mutually exclusive either; you can delegate interactions/elements that require more reactivity to a reactive library and communicate over events.
That being said, my experience working with developers who only know React or the reactive model is that they'll find it difficult and counter intuitive to use HTMX, and even more so to combine it surgically with a reactive library / plain Javascript where necessary. In a project in which I participated Vue was added progressively until we ended up moving everything over to it when requirements for reactivity where such that it made sense to do so. The rest of the team was overjoyed when HTMX was removed, though HTMX did a great job to carry the project up for over a year while the product found product/market fit and now had enough traction to justify growing the team.
gecko | 12 hours ago
I mean, as someone who uses htmx, three parts to that answer:
thisor things likeclosest .classNameHereand equivalents, in which case this doesn't apply.tl;dr: if you're doing something big enough where this would actually suddenly be A Thing, I personally would really say it's time to look at Svelte or React (or maybe Unpoly if you're really set on a mostly-static approach). I think htmx is great at its niche, which is basically web sites with interactive bits. I don't think htmx is great for complex interactive apps, and IMVHO you're gonna have a bad time trying to shoehorn it into that world.
ggpsv | 11 hours ago
I agree with most of this but I would challenge your last statement. HTMX can be great for complex interactive apps too if most of the interactions involve server round-trips and client-side state is not, as you state, sprawling.
For an application that does most of its work on the client-side then yes, HTMX is not as appropriate.
Also, funny that you mention BEM or SMACCS being the current hotness. They were hotness when I started doing web development back in 2013 :)
gecko | 11 hours ago
I think that's fair. I've just never (personally!) been in a situation where I had a complex interactive app and the state would be pleasant to handle server-side, but I know they exist. (E.g., there was actually a great post on here a couple of months ago where someone redid a sign-up wizard as server-side logic, and talked about how that even enabled things like people finishing signup months after they started. I don't recall them saying they used htmx in there, but it'd have been a good fit.)
FedericoSchonborn | 12 hours ago
To do difficult things like (checks repo) add a link to a HTML file?
https://github.com/bigskysoftware/htmx/commit/ea594096c862878bf00578e1d37236cc8c3609f4
I'm sure all that power was necessary for the task.
gecko | 12 hours ago
Not defending that a whit, but at my day job, where I'm...uh...super strongly encouraged?...to use LLMs, I've had this pop up when the prompt is something like
and have it show up that way. That said, I literally never let Claude commit for the same reason I don't just YOLO patches that hit my inbox onto
main, so it wouldn't be obvious I'd done that.Halkcyon | 9 hours ago
Is that not already in your CI job? Are you replacing purpose-built tools with LLM slop?
gecko | 9 hours ago
I, personally, am undoing this at the moment, but my predecessor: yeah. And I can only write actual code so fast.
Halkcyon | 9 hours ago
lonjil | 8 hours ago
Every time I try to scroll down on this page, I get sent back to the top within a second or two.
chrismorgan | an hour ago
Two things here:
I don’t think this makes any sense. If they suggested unversioned URLs in the past… well, that was a mistake. But even apart from that, I just don’t believe that waiting six months before changing it is going to change much. People that are using public CDN URLs are unlikely to update their version numbers, because they will have no automated channel for noticing it. Ultimately when they switch it over, it will be just as much a breaking change and I strongly suspect will affect approximately the same number of people. Really, it’d be better if you could opt out of allowing versionless/
latestURLs on the CDN. As it is, in the mean time they make it so thatnpm install htmx.orggets you the wrong version!You should never deploy things like this to production using public CDNs. Copy the file(s) and host them first-party: especially where it is just a single file, the difference in effort is negligible, and you get a more reliable, trustworthy, and faster result. There are no valid reasons to use a public CDN for anything beyond quick experimentation, since five or six years ago when Chromium and Firefox adopted cache partitioning (Safari did it in 2013). Honestly, the fact that htmx installation instructions start with public CDNs with no mention of why deploying in that shape is a bad idea has always turned me off it.