Skip to content(if available)orjump to list(if available)

Htmx 2.0.4 Released

Htmx 2.0.4 Released

135 comments

·December 14, 2024

ianpurton

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

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

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

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

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.

halfcat

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

I haven't tried Alpine but I will investigate, thank you for the recommendation.

yawaramin

> 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

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.

bjackman

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

Interesting, I'm working on a similar project myself. Is your web clone open source?

bjackman

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

> 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

> 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

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

Go off King!

_heimdall

> 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

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

This is why I think semver is impossible to do in practice.

teruakohatu

> 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.

mirekrusin

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.

null

[deleted]

_heimdall

Ah okay, that makes total sense. I should have checked the PR first!

chrismorgan

> 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

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

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

> though hopefully there weren't sites expecting an ajax call to not do anything.

thatsthebeautyofit.com in shambles

cschep

why would you call it expecting it to do nothing?

beanjuiceII

why is the wrong question, because it doesn't matter

cschep

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

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

> 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

It's not that there are breaking changes, but that breaking changes were introduced in a patch release.

sethammons

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

I'm not fine with breaking changes in a patch bump, otherwise it means versioning is useless

PhilippGille

In addition to what the siblings say, in case parent isn't aware of semantic versioning: https://semver.org/

intalentive

How is Python a disaster?

null

[deleted]

benatkin

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

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

> 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

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

bdcravens

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.

johnfn

A page refresh isn't common?

esperent

> 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.

deedubaya

As ceo of htmx I’ll field any questions now

mongol

What are the credentials you need to become CEO of HTMX?

devjab

Well, you need an X account, so too high?

recursive

I doubt that.

recursivedoubts

no, they are a CEO of htmx

so are you:

https://htmx.ceo

ossobuco

/u/recursivedoubts correcting /u/recursive has to be some of kind of joke you guys prepared in advance, right?

adzm

I'm sorry, can someone please explain

xupybd

As another CEO of HTMX, how do you feel about this release?

WD-42

Nice boring release, just the way I like it. Thank you!

thekashifmalik

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

> 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

I'd like to see a demo of htmx talking to the WebAssembly HTTP capability component.

ianpurton

What is that?

euroderf

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

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

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

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

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

Same. Tried to write a boot loader in HTMX. Wish I’d used React instead.

joshmanders

Same. Used htmx to write a pacemaker. Wish I'd used React instead. RIP dad, I miss you.

Babawomba

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

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

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

Htmx belongs on a pedestal

peterpost2

Agreed, web development without all the time consuming nonsense.

2-3-7-43-1807

what is the selling point of htmx? why use it versus ...?

halfcat

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

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/