HackerTrans
TopNewTrendsCommentsPastAskShowJobs

Htmx 2.0.4 Released(github.com)

196 points·by ms7892·2 anni fa·129 comments
github.com
Htmx 2.0.4 Released

https://github.com/bigskysoftware/htmx/blob/v2.0.4/CHANGELOG.md

135 comments

ianpurton·2 anni fa
Do some people have examples of interactivity they were able to replace with Htmx?

For me, I've been able to get turbo style links with the boost to get nice page transitions. I can also see how I could use the class-tools extension to enable buttons to open dialogs etc.

I'm curious to see when people say they needed an SPA for interactivity, what interactive features Htmx can already do and when do we need to break out some JS.

An example that I think needs JS is a copy paste button.
fhd2·2 anni fa
One thing I use HTMX for is to quickly hack interactivity into a more traditional site.

One example is incremental filtering: I added an input field, and made it (a few ms after the last value change) load the same page the user is already on with a query parameter that filters the items in the response. Then I just replace the list of items with the contents from the response, ignoring the rest of the page.

It's a bit wasteful perhaps, but all this took just a few lines of HTML.
kisamoto·2 anni fa
I tried HTMX but found it too restricting. It's great if you just want to load a portion of the page. Maybe if you have an up-vote, just send the request and replace the icon with a gold icon.

But I want things like an on-site calculator. I load in products and prices, users can adjust sliders to change the quantity and relevant number is calculated. I don't want to use HTMX for this to call the server each time, I want instant reactivity and state in the frontend maintained so when the user has tweaked as necessary they can just check out.

HTMX does not fit this use case so I use React to build widgets (or if even more complex SPA then Angular). If I'm using a JS framework anyway, then I don't need HTMX. It's just something else to clutter the project and remember to use.

HTMX has its place but with the user expectation for reactivity in the browser I personally find it too limiting.
BiteCode_dev·2 anni fa
Because HTMX is declarative and the declaration is in HTML, people have weirdly extended the "no need for js+json+rendering for ajax" to "don't use js".

This is making your life needlessly difficult.

HTMX is just a fancy ajax layer with a little event handling sprinkled on top. You can and should script to your heart content even if you use it, when you need so.

I use js in all most of my HTMX powered pages. Sometimes just a few lines. Sometimes a whole lot. Sometimes vanilla, sometimes alpine. I even have one where I load react for one single page because I want a community widget while the rest of the site is pure HTMX.

You can do whatever you want.
kisamoto·2 anni fa
Of course you can combine the two but why use three tools (SSR + HTMX + JS) when I can just use two (SSR + JS)?

My point is that if you are going to use a JS framework then it will do the same as HTMX and I don't have to remember where to draw boundaries of responsibility.
recursivedoubts·2 anni fa
htmx generalized hypermedia controls, so it makes HTML more powerful as a hypermedia:

https://dl.acm.org/doi/pdf/10.1145/3648188.3675127

that means you may be able to express more of your UI needs in HTML, using the traditional REST-ful architecture of the web (HATEOAS, in particular) and reserving JavaScript for the areas where that additional complexity adds the most value.

Depending on your application, this may lead to significant reduction in application complexity:

https://htmx.org/essays/a-real-world-react-to-htmx-port/
halfcat·2 anni fa
This kind of use case is where you’d use Alpine instead of HTMX (if you’re going for the no-build approach). It has everything you’d need for this, client-side store, etc. Alpine is basically light weight, no-build Vue.

HTMX is really only about swapping out the elements on the page and pushing updates to the server, which in this case might just be lazy loading the calculator component that contains Alpine attributes and Tailwind elements, and HTMX only if there are elements to swap or you need to save state to the server.
kisamoto·2 anni fa
I haven't tried Alpine but I will investigate, thank you for the recommendation.
yawaramin·2 anni fa
> when the user has tweaked as necessary they can just check out.

And what happens after the user spent all that time adjusting their order, submits it, and then is told at the very end that some items are out of stock? Do you think they're going to be happy about that?

What if their browser crashes and the order they had built up carefully is lost? Will they bother to try again?

Will you do price calculations properly with a proper decimal library or allow the user to see what IEEE754 floats think '0.1 + 0.2' should be?

Lot of questions come up with the client-only approach.
kisamoto·2 anni fa
Appreciate the concerns but they're non issues.

Stock doesn't matter for my case.

The browser has storage options to handle close and reopens.

Prices in each currency are all in ints (i.e. cents) to avoid float issues.

There are problems to address on either end that you have to be aware of.
yawaramin·2 anni fa
Good to know that it's not an issue in your case but just a reminder that your specific case is, by definition, not generalizable. These are problems that exist in general and have to be solved or prevented in some way. For example, you found some solutions that work for you but they won't for everyone.
bjackman·2 anni fa
I recently tried out htmx for rendering a web clone of the terminal UI for https://github.com/bjackman/limmat

It's a simple usecase but nonetheless I was blown away by how trivial HTMX made it! Very cool.
srid·2 anni fa
Interesting, I'm working on a similar project myself. Is your web clone open source?
bjackman·2 anni fa
The whole web part is in here: https://github.com/bjackman/limmat/blob/master/src/http.rs

Like 100 lines of code total to get it rendering in a browser with live updates over a web socket.
serial_dev·2 anni fa
> An example that I think needs JS is a copy paste button.

And it’s fine? htmx allows you to write JavaScript. It’s probably one line, I don’t think everything you can come up with needs to be part of htmx.

It’s not all or nothing.
srid·2 anni fa
> An example that I think needs JS is a copy paste button.

Evidently you can use Hyperscript for this. Its website <https://hyperscript.org/> demonstrates it with a similar "copy" button.
sublinear·2 anni fa
I wrote plain HTML, JS, and CSS and it worked great in all browsers and all devices and passed all kinds of audits necessary in the real world.

Don't bother with libraries like this.
spirodonfl·2 anni fa
Go off King!
_heimdall·2 anni fa
> Calling htmx.ajax with no target or source now defaults to body (previously did nothing)

This one jumped out to me as an interesting one for a patch release. Changing the default behavior feels like a breaking change, though hopefully there weren't sites expecting an ajax call to not do anything.
latent22·2 anni fa
Actually this was just a stupid bug I introduced in 2.0.3 which was found soon after 2.0.3 shipped. I fixed a bug that allowed ajax api to target body and blow away your whole page in error if one of the selectors you pass in was not found. But It broke the default no source and target behavior but this is now fixed that 2.0.4 is shipped
ahoka·2 anni fa
This is why I think semver is impossible to do in practice.
teruakohatu·2 anni fa
> This is why I think semver is impossible to do in practice.

The semver docs explicitly address this scenario. If a change in minor update breaks compatibility release a new minor update to revert the change.
foldr·2 anni fa
It’s correct practice, but bad luck for anyone who ends up depending on the buggy behavior in 2.0.3. Their code will break when they upgrade to (say) 2.0.7.
joshmanders·2 anni fa
This would make sense if 2.0.3 was released long enough ago for people to start using and relying on a bug, but it was released less than 2 months ago...
latent22·2 anni fa
The bug in 2.0.3 just breaks one default use case and where you pass in no source or target to the api so anyone using this feature their app broke on upgrade to 2.0.3 and they had to set a source explicitly or revert the version. 2.0.4 just fixes this with no downside unless you like seeing console errors
mirekrusin·2 anni fa
Agree, behavior vs misbehavior (aka feature vs bug) is user's decision (at call site), not author's decision (at implementation side).

Semver is just _indicative_ attempt at describing changes.

If this wasn't true, we wouldn't have lockfiles.

Ie. semver is just approximate attempt at change description that aids/helps development/maintenance but should never be fully trusted.

The only way it could fully work in automated fashion is if the whole program would be written in some formal proof language – then dependency upgrades could be considered as breaking or non breaking. But again, easier and more precise from end user position, not author's position because breaking change in one project can always be non breaking in other if that part is not used/used in more relaxed manner.
[deleted]·2 anni fa
_heimdall·2 anni fa
Ah okay, that makes total sense. I should have checked the PR first!
chrismorgan·2 anni fa
> though hopefully there weren't sites expecting an ajax call to not do anything

It didn’t need to do nothing, it just needed to have no visible effect.

I would be absolutely astonished if this affected no one. It’s very easy to imagine someone having written

  htmx.ajax("GET", "/some-tracker-that-returns-nothing-or-json-or-something")
And now your body is clobbered, leaving either nothing behind or a raw JSON response or some such thing. Seriously.

Should such a person have used fetch() instead? I dunno, probably; I don’t use htmx.

This is an extremely breaking change.
_heimdall·2 anni fa
That's fair, I guess someone could be doing that. Not quite sure why you would though, if you're already in JS and aren't updating the DOM, fetch() would make more sense.

Either way it sounds like this was a fix to a bug introduced in the last patch so the semver makes more sense here.
recursivedoubts·2 anni fa
Yeah I tend to agree this should have been in a minor rather than a patch release. The reality is that I tend to regard the JavaScript api as an afterthought (the html attributes are the main api) and the existing behavior seemed like a nonsensical bug, but on reflection I wouldn’t have changed the html api like that and should treat the JavaScript api the same way.
tomjakubowski·2 anni fa
> though hopefully there weren't sites expecting an ajax call to not do anything.

thatsthebeautyofit.com in shambles
cschep·2 anni fa
why would you call it expecting it to do nothing?
beanjuiceII·2 anni fa
why is the wrong question, because it doesn't matter
cschep·2 anni fa
of course it matters. not all workflows are worth preserving at all costs. there could be a really important trade off lurking, I'm not familiar, which is why I asked!

https://xkcd.com/1172/
recursivedoubts·2 anni fa
yeah, the htmx JavaScript API is not widely used, but I agree it's right on the edge of what's acceptable in a patch release
hipadev23·2 anni fa
> Changing the default behavior feels like a breaking change

I'm fine with breaking changes personally. An adherence to maintaining backward compatibility always is what leads to bloat and criticisms of "poor design" from HNers in the future.

Keep it slim, have one way to do things, and avoid the disaster that is js and python today.
Spivak·2 anni fa
It's not that there are breaking changes, but that breaking changes were introduced in a patch release.
sethammons·2 anni fa
Backwards compatibility is a mainstay in Go and I don't experience bloat, and, I believe, such goals are a hallmark of good api design. Source: over the last 20 years, built several and used many large code bases that have used for years and years that had different teams and individuals regularly committing into them.
izietto·2 anni fa
I'm not fine with breaking changes in a patch bump, otherwise it means versioning is useless
PhilippGille·2 anni fa
In addition to what the siblings say, in case parent isn't aware of semantic versioning: https://semver.org/
intalentive·2 anni fa
How is Python a disaster?
[deleted]·2 anni fa
benatkin·2 anni fa
There's a question I've had about htmx for some time, might as well ask it here. Why does it keep the history cache in localStorage and not sessionStorage or memory? Some kind of a microoptimization? sessionStorage seems like it would be better to me if it's really a good default. I also think it should be publicized more, because it unexpectedly keeps stuff in a location that can be accessed more easily and beyond where the browser's back button cache can.
recursivedoubts·2 anni fa
memory wouldn't survive a page refresh

sessionStorage wouldn't survive a tab close

i'm not opposed to making the latter an option though
benatkin·2 anni fa
> memory wouldn't survive a page refresh

That isn't very common.

> sessionStorage wouldn't survive a tab close

When a tab is restored, the browser typically restores sessionStorage.

> i'm not opposed to making the latter an option though

That isn't what I was getting at. If I'm going to buy into htmx, I want to understand the design. I wondered why this was the default, and why I hadn't seen it mentioned as a security concern.
recursivedoubts·2 anni fa
i don't know how common it is or isn't, but it's reasonably common for htmx to be sprinkled into a regular MPA with full page navs, etc. and memory wouldn't survive that

no strong opinions on session vs local storage, i was trying to make htmx act as much like the browser as possible and the browser caches across tabs

you can disable history on any page by using the hx-history attribute and you can force a server request on every history navigation by setting the htmx.config.historyCacheSize config option to 0:

https://htmx.org/docs/#disabling-history-snapshots

https://htmx.org/docs/#htmx-security-tools
benatkin·2 anni fa
Memory would indeed be an issue for mixing MPA and SPA, but besides not being an issue for a full SPA it also wouldn't be an issue for sites that are all MPA except AJAX submissions that don't cause a SPA page change. Currently I think an all MPA would waste the localStorage space.

SessionStorage by default with prominent placement in the docs would be better I think. It would automatically clean up the data from visitors' disk space at appropriate times, whereas the localStorage setting puts it in a place that gets persisted for quite some time.

Thanks for those links, I've read them but it's good for others here to see them.
bdcravens·2 anni fa
Maybe because I'm "old" and use browsers the way they were used when I first started using the Internet, but I refresh often enough that I'd quickly lose patience with an "app" that broke because I used a very basic feature of the web.
benatkin·2 anni fa
If the site wasn't working it wouldn't break, it would download each page when you hit the back button. That would actually be a welcome result if I hit the refresh button wanting to make sure I was only looking at fresh data.
bdcravens·2 anni fa
Any resource (ie page/URL) should function correctly with no regard to how that resource was loaded. That's the contract any server has with the client (browser), with no regard to what technology is being used to deliver the resource.

If a website or application basically has to do the 2024 equivalent of "don't hold it that way", it's the result of a broken development model.
benatkin·2 anni fa
The correct function comes down to what the browser APIs say is valid in navigation. Both loading cached data and making the request again are valid. In the case of soft page navigation (onpushstate/onreplacestate) it's very clear that both are valid, as SPAs aren't expected to cache nothing, nor are they expected to cache everything.
withinboredom·2 anni fa
If I’m currently filtering some search data and hit refresh (or the browser tab went to sleep and wakes up, or restored after a reboot) I expect it to be in the same place without having to search and filter again.
benatkin·2 anni fa
https://en.m.wikipedia.org/wiki/Query_string
withinboredom·2 anni fa
You would(n't) be surprised how many applications don't use this great feature.
johnfn·2 anni fa
A page refresh isn't common?
mrits·2 anni fa
I'm wondering how they use this site
benatkin·2 anni fa
I wasn't talking about Hacker News or lobste.rs :)
gklitz·2 anni fa
So you were only trying to say that page refreshed aren’t common on some subset of pages where it isn’t common? What’s the point of that argument.

Also curious, why are you arguing so intensely for a “solution” that seems to only be worse and introduces issues as explained, without ever having stated any problem you are trying to solve with the change?
esperent·2 anni fa
> When a tab is restored, the browser typically restores sessionStorage

Is it guaranteed to do this? Otherwise, if it just sometimes does it, or different browsers handle it differently/may change in the future, it seems like a recipe for problems.
hotpocket777·2 anni fa
Not guaranteed, no. Thankfully.

Chrome does, however, if the “resume where i left off” setting is enabled.
deedubaya·2 anni fa
As ceo of htmx I’ll field any questions now
mongol·2 anni fa
What are the credentials you need to become CEO of HTMX?
devjab·2 anni fa
Well, you need an X account, so too high?
recursive·2 anni fa
I doubt that.
recursivedoubts·2 anni fa
no, they are a CEO of htmx

so are you:

https://htmx.ceo
ossobuco·2 anni fa
/u/recursivedoubts correcting /u/recursive has to be some of kind of joke you guys prepared in advance, right?
recursive·2 anni fa
Not prepared in advance, but I knew the user name on the htmx guy, so I just decided to use the word "doubt".
adzm·2 anni fa
I'm sorry, can someone please explain
joshmanders·2 anni fa
Anyone can be htmx CEO, even you could be without knowing it.

I'm an htmx CEO, btw.
xupybd·2 anni fa
As another CEO of HTMX, how do you feel about this release?
WD-42·2 anni fa
Nice boring release, just the way I like it. Thank you!
thekashifmalik·2 anni fa
So happy every time I see HTMX.

I'm hoping there is more innovation in this space with React engineers rediscovering the benefits of server-side rendering and Backend-For-Frontend efforts.

I think the perfect stack involves all 3 paradigms (initial loads, hypermedia loads and data/AJAX loads) used in parts of the application as makes sense.
bogdan·2 anni fa
> React engineers rediscovering the benefits of server-side rendering and Backend-For-Frontend efforts

React 19 has just been released recently with server components and server actions. Worth having a look. It's a very powerful model.
euroderf·2 anni fa
I'd like to see a demo of htmx talking to the WebAssembly HTTP capability component.
ianpurton·2 anni fa
What is that?
euroderf·2 anni fa
https://github.com/WebAssembly/wasi-http

WebAssembly (wasm) already runs in the browser, but now also it is being used to create cross-architecture executables and modules that might (so they say) replace k8s.
euroderf·2 anni fa
To expand, as I understand it, the component model is meant to enable large scale deployment, and runtime module composition using well-defined interfaces in an IDL called WIT.
qwm·2 anni fa
I have several problems with htmx, and none of them are love of React or the thousands of NPM modules that make up most modern frontends today. I'm also not a fan of JavaScript itself, and I don't write Node backends unless I can't avoid it.

The main problem I have with htmx is it requires my backend and frontend to be uncomfortably coupled. I write most of my backends in Go these days, but I've written a lot of Java and PHP in the past. I particularly hate PHP and the model of mixing backend logic and presentation markup. I'm not a fiend when it comes to separation of concerns; I try to keep relevant things together. With that said, constantly bundling markup with actions is annoying. For example, POSTing a comment would require the backend to send back the new comment's HTML, then possibly perform some action like bumping off comments that are too far down.

The other big problem I have with htmx is that it has no good solution for managing state and staying consistent with the backend. I used to work on a site written in PHP that, while not using htmx, used generally the same system of returning HTML from ajax calls. I was working on implementing comment replies, which required not only appending a new comment, but changing some of the markup on the original comment to indicate that it had replies and a button to collapse those replies. The solution I chose for this was to make those changes to the original comment dynamically with raw JS, then append the HTML for the new comment returned by the server. This worked fine, but it was annoying because I had to replicate rendering logic in both JS and PHP. This kind of thing can easily become death by a thousand papercuts as your site grows and you have more and more duplicated rendering code. This problem does not exist in the Vue/React/etc. world.

There is value in keeping all your rendering in one place, even if that place is the server and access to it requires enduring network latency. I understand why someone who uses a language other than JS for backend would enjoy htmx, but I think it's going to bite its users in the ass one day or another when their application becomes too big and rendering logic becomes hard to maintain.

I would say my favorite alternative to htmx for people who want statically rendered pages but don't want to go without niceties like components, JS type checking, reactivity and other things that speed up frontend development and make it more scalable is Inertia.js. It allows you to use a JS frontend framework like Vue or Svelte and the backend of your choice without having to write an API or (god forbid) GraphQL. https://inertiajs.com/

I've also found that petite-vue is great for adding progressive enhancement to otherwise static sites without using a bloated framework. I've used it in several contract projects and it works like a charm. https://github.com/vuejs/petite-vue
recursivedoubts·2 anni fa
yes, hypermedia couples things at the application layer, but decouples at the network architecture level:

https://htmx.org/essays/two-approaches-to-decoupling/

htmx uses Hypermedia As The Engine of Application State:

https://htmx.org/essays/hateoas/

The problems you have had appear to be addressable using techniques outlined here (from least to most complicated):

https://htmx.org/examples/update-other-content/

Of course, there are going to be applications and features that the hypermedia approach are good or not appropriate for, I try to outline those situations here:

https://htmx.org/essays/when-to-use-hypermedia/

I think you could build an excellent comments system using htmx if you wished to.
htmxceo·2 anni fa
I tried to use HTMX to fix some of the plumbing in our bathroom and I’m very disappointed … it just isn’t fit for purpose. I’m sticking with React
halfcat·2 anni fa
Same. Tried to write a boot loader in HTMX. Wish I’d used React instead.
joshmanders·2 anni fa
Same. Used htmx to write a pacemaker. Wish I'd used React instead. RIP dad, I miss you.
Babawomba·2 anni fa
Tried Htmx a while back... mixed feelings. Love how easy it is to get basic interactivity—honestly, adding a filter or an upvote button in a couple of lines of HTML feels like magic. No messing with a frontend framework, no bundlers - just works.

But I hit walls when I needed more complex stuff. Like, if I want to keep state on the client (e.g., a live calculator or sliders updating a table), Htmx feels clunky. Sending a request to the server every time a user adjusts a slider—yeah, no. React or Svelte is a better fit there. And if you're already using those tools. Htmx starts to feel redundant. Why add more when you've got everything in one place?

Also, not sure about the recent patch release - Changing default behavior in a minor update? Feels risky, even if it's "fixing a bug." Imagine waking up to find your body tag wiped because you updated without reading the changelog, yikes. Makes me think twice about trusting it in production.

Butfor MPAs or projects that lean heavily on server-side rendering, it’s a game-changer. You’re not rebuilding the wheel, just enhancing it. Htmx has a sweet spot—it’s just not always the right tool for every job. Depends what you're building, I guess...
yawaramin·2 anni fa
Wait, why do I need React for a live calculator or sliders updating a table? Does plain JavaScript and the Web APIs no longer exist? Don't Web Components/custom elements exist? I need to immediately jump to React/Vue/etc. at the slightest bit of client-side interactivity?

Also, do people just update and yeet their apps into prod without testing it? What happened to test environments? Test suites? Manual QA? Letting it soak? Where did quality control go?
adzm·2 anni fa
Same here. I honestly love react, it just seems to make sense, integrates well with legacy stuff, great tooling, really nothing else comes close
RamboRogers·2 anni fa
Htmx belongs on a pedestal
peterpost2·2 anni fa
Agreed, web development without all the time consuming nonsense.
2-3-7-43-1807·2 anni fa
what is the selling point of htmx? why use it versus ...?
halfcat·2 anni fa
You team knows Python/Ruby/PHP/Elixir/C# and uses Django/Rails/Laravel/Phoenix/ASP and doesn’t have a need to hire dedicated frontend people. You can leverage your existing talent to drive the frontend from the backend.

It has limitations (not going to use HTMX to build Google Maps) but handles the 80% of use cases well for little added skillset required.
recursivedoubts·2 anni fa
depending on your application type it might simplify your application:

https://htmx.org/essays/a-real-world-react-to-htmx-port/

how to determine if it is appropriate:

https://htmx.org/essays/when-to-use-hypermedia/
[deleted]·2 anni fa
sublinear·2 anni fa
(1)
gloosx·2 anni fa
>htmx.ajax, htmx:trigger, synthetic load event

>Nested shadow root

>element is reinitialized via htmx.process()

>Boosted <form> tags

>htmx-powered elements located outside a form, but that refer to a form via the form attribute

>preload, hx-boost, response-targets, ws, head-support, sse

I see... Folks at HTMX are always thriving for a little bit more power of hypertext.

Remember guys this is how S.I.M.P.L.I.C.I.T.Y. looks like.

Fnatics, unleash your downvotes!
xupybd·2 anni fa
Nothing new under the sun. This is just a rip off of intercooler js. Only without jQuery. Times moved on and someone copied the idea (exactly) but with the aid of modern JavaScript didn't need jQuery.

I mean it's nice that it's a bit more modern but still.
antonyt·2 anni fa
Just in case this isn’t sarcasm, you may be interested to know they’re made by the same person.

https://news.ycombinator.com/item?id=23330881
[deleted]·2 anni fa
genocidicbunny·2 anni fa
You do realize that htmx is intecooler.js 2.0? Made by the same people, for the same purpose. And if you don't believe me, the intercooler.js homepage says pretty much the same exact thing.
xupybd·2 anni fa
I think you'll find there is some animosity

https://x.com/intercoolerjs/status/1845878585078567084?t=p41...
recursive·2 anni fa
It's a joke.
benatkin·2 anni fa
It's a dank meme.
choilive·2 anni fa
... you realize this is a joke right?
xupybd·2 anni fa
Tell that to Carson Gross!
choilive·2 anni fa
The creator of HTMX and Intercooler.js? I think they already know.
xupybd·2 anni fa
Both of them take this feud very seriously from what I've seen
xupybd·2 anni fa
https://x.com/intercoolerjs/status/1859652045399355559?t=-za...
choilive·2 anni fa
you realize theyre the same person... right? right?
xupybd·2 anni fa
But clearly not the same personality
nakeru·2 anni fa
Is this supposed to be a joke? If it is... it isn't funny. If it isn't... Maybe it's time to face the fact that you're very wrong about this...
icemelt8·2 anni fa
Tell me I have autism without....
nakeru·2 anni fa
Tell me I'm rude and that I don't understand what autism is without...