I'd say it's not about what can be done, it's about how it's defined. HTMX is a abstraction layer on top of an existing abstractions that you still have to know, because it's defined in terms of those abstractions.
So when you write something like `hx-trigger="click" hx-put="/api/my"` you're actually actively thinking of an `addEventListener("click", ...)`, `this.innerHTML` assignment and `fetch("/api/my", { method: "PUT" }))`. Can't use HTMX without knowing the underlying principles and primitives.
And then you still have to do JS because how else you're supposed to handle `htmx:responseError` and stuff. And maybe I'm wrong but it feels risky because the logic could end up all around the place and not in a single nice function/code block.
So, basically, it's a nice DSL providing a bunch of shortcuts, but it doesn't magically alleviate knowing any underlying principles and nuances of JS and DOM. Again, it's even defined in terms of those systems (`hx-swap="outerHTML"` being a very clear indicator example).
So when you write something like `hx-trigger="click" hx-put="/api/my"` you're actually actively thinking of an `addEventListener("click", ...)`, `this.innerHTML` assignment and `fetch("/api/my", { method: "PUT" }))`. Can't use HTMX without knowing the underlying principles and primitives.
And then you still have to do JS because how else you're supposed to handle `htmx:responseError` and stuff. And maybe I'm wrong but it feels risky because the logic could end up all around the place and not in a single nice function/code block.
So, basically, it's a nice DSL providing a bunch of shortcuts, but it doesn't magically alleviate knowing any underlying principles and nuances of JS and DOM. Again, it's even defined in terms of those systems (`hx-swap="outerHTML"` being a very clear indicator example).