htmx 2.0.0-beta1
v2-0v2-0.htmx.org
v2-0v2-0.htmx.org
I think adopting HTMX as a framework would be difficult to switch from a React, Vue, etc. environment. I think using it inside internal tooling or a hobby project will not be able to justify its merit.
I understand that it is just a simple framework and it addresses an industry-related issue, but migration is a lot of effort. Does HTMX really provide enough value to justify the engineering investment required?
I totally get your sentiment.
There are a lot of server side templated web facing applications out there, and htmx provides a simple and gradual UX improvement with very litte investment.
It depends on what you deem "internal tooling" but a lot of b2b software isn't built to be flashy.
I know Rust is gaining traction, and I have always found languages like assembly, C/C++ to be more enjoyable than the higher level languages. So, I might try and take a stab at Rust and see where it can take me. I'm just so fatigued from all the web dev stuff. The whole field feels too scatter-brained to me.
Instead of trying to solve useful problems, I feel like much of web dev's frameworks are just focused solving an already solved problem with slightly differing and dogmatic opinions.
After being reminded of the importance of supporting low-spec clients[1] I’ve been testing without the HTMX library loading as well, and mostly that works like it should. I say mostly because I didn’t get the markup right everywhere yet.
I can see why some wouldn’t like it. But, it’s not a good/bad or works/doesn’t thing - it’s just different.
[1] https://danluu.com/slow-device/
Edit: typo, HTML -> HTMX
See also https://hotwired.dev/
htmx encourages you to put most of the logic on the server and to keep the client lean and clean.
When you do an htmx navigation to a new page, a discarded tab will "restore" only the last htmx fragment loaded, not the entire html page with style tags. Fix is to use unique url on push that isn't in local cache which forces a server reload on tab wake from discard.
Vary: HX-RequestI'd say the main thing I like is testing. With a JS framework I have to have tests spread over both JS and Python, with HTMX I can mostly just focus on Python tests and assume the HTMX is going to work correctly. There's a good, stable testing story for Django, so I know the tests I write won't have to be rewritten all the time when dependencies change. I just don't write many JS tests because stuff changes so fast.
The main downside I have with it though, is I just can't seem to remember how to use it. Every time I need HTMX I have to look at code I've written or go to the docs. There's just too many options with names that are confusing (hx-select, hx-swap, hx-swap-oob, hx-target?).
Aside from that, it's also a pretty large dependency. I'm also using Solidjs to mount web components (which is a pattern I love) and HTMX is a majority of the JS bundle. That was surprising to me. Maybe version 2 will be smaller?
Perhaps this could be smoothed over with snippets or an autocomplete extension for whichever text editor is being used?
I could see a better tutorial experience with live examples for common patterns. Something like SolidJS does (https://www.solidjs.com/tutorial/introduction_basics). That would be a good reference. Alternatively, a copy/paste pattern library, like what a lot of people are doing with Tailwind (https://daisyui.com/components/).
I've noticed the more I use HTMX, the more I tend to end up needing to use the JS API too.
For example, if I have an HTML table with inline editing, and I need there to be validation on what people are entering. So, I have HTMX firing when people save their changes via a button, then I need to use the JS API for conditional logic e.g., if valid, then update table. If invalid, then display some kind of message or whatever.
HTMX has been working great for my needs, but the more I tend to get into the weeds of the JS API, I cannot help but sometimes question whether I am truly gaining that much more over using plain AJAX requests. However, HTMX is definitely more concise, so that's a nice benefit I suppose over a unmaintainable slew of AJAX requests.
Couldn't that be handled server-side as well? I have my validation logic server-side, and it either returns the updated table row (or other element), or it returns the form again with validation/error messages, fields highlighted where the error occurred, etc.
The general philosophy is that "React etc are great for some things, but they are being used way outside of their sweet spots". There will always be a gray area - and your existing habits and skills are also a factor but for some of us - the "SPA framework" approach always smelt fishy for typical web builds.
This means, that almost all uses of react and friends are wrong, a waste, or an unnecessary complication.
So, if you are serving HTML, then htmx.
When you reach for react? If you are making an app of the kind that you should have use a non-web thing (because is now necessary to bend with major complicated hacks HTML to make a clone of Photoshop).
(and in short amounts like creating complex widgets like maps, selects, etc).
---
I work for eCommerce, and there is terrible to use React: It is too easy to make "hacker-friendly" websites when using it: INSTEAD, you MUST validate, format, process, render, and display all on the server side.
For me, I retain all the logic on Rust, display HTML, and just put some extra interactivity with htmx, that because at the server-side is the same as without, means I CAN'T INTRODUCE A SECUIRITY BUG.
Seems that HTMX requires unsafe-eval?
For such things, if you're not doing everything Server Side to Render fully validated and sanitized data safely, you should be.
If it’s is purely a SPA, then all business logic would be behind secure APIs, so I don’t really understand your point.
Nodejs is quite popular. One language works on front-end and back-end. Like any language, security is up to the developers.
>Many junior devs believe the client code is trustworthy and put important validation only in the client.
Who is letting "junior devs" make these decisions? It sounds like they deserve to be hacked.
This isn't exclusive to SPAs. For example, I am a .Net dev, and I have both front-end and back-end validation in most of my applications without ever using any SPA frameworks.
If I am in a pinch for time, I sometimes just drop front-end validation completely, and let the server handle the validation and then have the front-end handle the server validation responses accordingly.
In contrast, server-side validation only means any validation deficiencies are more likely to be discovered during legitimate usage since the client-side validation is no longer covering up for it.
Fun thing, customers find the new version (htmx/django-livecomponents) to be more responsive than the old version (react+REST). New version is less lines of code and easier to hack on die to fewer context switching.
Give htmx a try, it's worth a shot!
Sounds cool. This one?
Anywhere I could conceivably get away with HTMX over React I would (and tbh I’d launch with no JavaScript at all before that). But if you’ve got a massive React codebase then you’re already in quite deep, both codebase and team structure.
All that said, some really high level apps are moving to WASM anyway, so I don’t know that an investment in React is safe for the long term.
I also work on a React site and I wouldn't want to move away from it unless someone dared to utter the word rewrite.
One benefit I found to it is that it allows developers to keep the business logic entirely on the backed side, without having to duplicate any effort on the frontend side.
Disclosure: I built it (without HTMX).
Unlike all-or-nothing approaches like React, htmx allows you to add just the right amount of partial updates to your web app, using just the technologies that were already there to begin with. I realize that this approach doesn't appeal to everyone, but being able to map simple requests to simple responses was an absolute life-saver for my projects many times over.
Migrating to a truly-truly minimalist approach (see: https://www.stefanjudis.com/notes/htmz-a-176-bytes-htmx-alte...) is still on my to-do list, but for now, I'm quite happy with the htmx status quo.
Setting this config makes it easier to use 'template fragments' with oob-swaps, since you can set the hx-swap-oob=true attribute on the element and reuse it to render a whole page or just a fragment of the template. Very nice to use with Go template blocks for example.
Most sane services will only return a 200 OK if, well, things went OK. Most sensibly designed services will return 400 range if an error has occurred that has been handled gracefully.
I am aware that you can kludge a hack in the form of a JS snippet to force htmx to render content on !=200, but it shouldn't be that way IMHO.
Yeah, it caught me by surprise first time I used htmx. I spent forever trying to troubleshoot why it wouldn't render the error message, then I discovered it was the old "feature not a bug".
https://htmx.org/extensions/response-targets
I don’t know what kludge you’re referring to, it requires you to add basically two attributes to your HTML, it’s really no hardship at all.
And why should I need to load an extension to handle a 400-series ? That's just nuts.
The kludge is loading the following JS snippet on your page:
if(evt.detail.xhr.status >= 400 && evt.detail.xhr.status <= 499 ) {
evt.detail.shouldSwap = true;
}Yes, but you are not designing your MVC controller as a REST service, and are not trying HTMX to your REST API directly. This makes sense if you think of it from this perspective, like the classic MVC view-rendering controller behind your HTMX page.
https://v2-0v2-0.htmx.org/docs/#configuring-response-handlin...
A few people on the core team agree that htmx should always swap. It was perhaps a bad decision on my part, but it is fixable w/ a bit of config.
https://htmx.org/essays/web-security-basics-with-htmx/#bonus...
> Some htmx applications make use of inline scripting—the hx-on attribute is a generalized attribute listener that can evaluate arbitrary scripts (although it can be disabled if you don’t need it). Sometimes inline scripts are appropriate to preserve locality of behavior on a application that is sufficiently secured against XSS, sometimes inline scripts aren’t necessary and you can adopt a stricter CSP. It all depends on your application’s security profile—it’s on to you to be aware of the options available to you and able to perform that analysis.
Is hx-on required often? How clunky does it get to avoid hx-on everywhere?
As someone who rarely use DELETE requests, what's the best practice for passing parameters and why?
DELETE cannot have request body, just like GET cannot have a request body.
(Well, it's a syntactically valid HTTP message, but there's no semantic meaning to the body.)
For that matter I've never quite figured out when to use POST vs PUT. POST doesn't feel right for a query.
> (Well, it's a syntactically valid HTTP message, but there's no semantic meaning to the body.)
To quote RFC 9110:
> Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]). A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.
For this reason, Elasticsearch also accepts queries as POST.
> A client SHOULD NOT generate content in a DELETE request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported.
By way of analogy with POSIX, `cat` (GET) and `rm` (DELETE) both just take a file path, whereas writing or overwriting a file (POST/PUT) also require something (a request body) to write.
light, well documented, snappy, easy to work with - i love the idea of endpoints returning pure html instead of json - it feels obvious.