htmx
htmx.org
htmx.org
htmx has been a revelation and has really opened my eyes to the nuances of hypermedia development modalities that I was ignorant of. For me, it has become very clear that htmx and hypermedia development is far more simple, productive, beneficial, and FUN for 90% of web dev use cases. I feel huge disappointment how unnecessarily web development evolved into bad client server rpc json protocol for basically everything web.
Kudos to the htxm creator and his vision of what should have been. My experience absolutely corroborates his thinking on these things.
javascript fatigue:
longing for a hypertext
already in handWhat's the logo of the cornucopia looking thing next to the django and rails logos?
While I love making projects with htmx, doing the equivalent for the complicated frontends we've got at my dayjob would not be enjoyable to maintain either. You'd end up with with fragment routes all over the place and will have serious issues finding where which is used, as the routes are all just strings with variable substitutions. Its also annoying to write non-e2e tests for the resulting backend IME, which is totally fine for a lot of applications, but forces you to restructure your code awkwardly to be able to write unit-tests in the backend
The catch is that very few JS SPAs actually deliver that functionality either - the functionality I'm talking about is desktop-app-grade functionality (think a trading terminal for example) that very few JS SPAs actually deliver. Most JS SPAs are just shitty reimplementations of basic browser functionality, and that is reasonably trivial to convert to server-side rendered HTML with HTML or ad-hoc (inline?) JS sprinkled in where necessary.
Keep in mind that server-side-routing doesn't prevent the use of React or similar frameworks either. If you have an application where 90% of the pages would be fine as server-side-rendered HTML but 10% require heavy interactivity, you can have your server return a page that embeds React or your JS framework of choice. (the reverse is also possible - if you have a JS-heavy website but have a few "boring" pages like for example an account details form, you can have your backend serve that as an HTML form and just have your JS iframe it)
Or, you could define every route to render a full page by default and render a fragment only if you detect an htmx request. So you end up with the same number of routes as for a normal MPA.
This:
<button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>
Should be just this: <button onclick="htmx.post('/clicked', 'outerHTML')">
Click Me
</button>
This way, no magic would be needed, a lot of indirection and complexity would be avoided and everybody who knows HTML and JS could immediately read and understand it: - When does something happen here?
When the button is clicked.
- What does happen?
htmx.post() is called.In this case, I would say the 'outerHTML' parameter is enough to define what will be done with the post result.
Makes me more interested than the current syntax.
Is this an informed criticism based on your experience having worked with htmx, or is it just an off the cuff opinion?
Personally, I don't think the goal should be "no magic", or "no indirection", or "no salt", or no "sugar". I feel that aiming for just the right amount of those things, to have the goody without crossing over to disgust, is a sound goal.
https://htmx.org/attributes/hx-trigger/ https://htmx.org/attributes/hx-sync/
Can you give minimal example on jsfiddle so we can compare different approaches?
Another big aspect of allowing to handle any event is integration with other JS libraries. See this basic example of interacting with Sortable JS [1]
Also, htmx has a response header called `HX-Trigger`[2] which lets server trigger custom events on the client and you can handle those events as well[3]. This is quite useful if you have interdependent data and you want to refresh regions on the page in response to user actions somewhere else (for which htmx allows multiple different patterns for different scenarios)[4]
[1]: https://htmx.org/examples/sortable/
[2]: https://htmx.org/headers/hx-trigger/
[3]: https://htmx.org/attributes/hx-trigger/#triggering-via-the-h...
Is this the relevant line?
<div hx-get="/random" hx-trigger="every 2s"></div>
If so, can you make an example with just that?I separated those examples to different files: https://plnkr.co/edit/0TWYrtbMGP9UAzE4
Also, you may notice there is <template/> tag. It's just for the demo [1], it serves as a mock endpoint
https://jsfiddle.net/w6nrek81/
No need to bring up multiple examples. We just need one to show that htmx makes something simpler. This isn't one though.
Your solution, for example, will break if the target div already has content in it. It also won't work if we want to insert the content after or before the element, you need to somehow keep track of the element being triggered, so it will grow more complex.
And still, it won't work with custom events
> No need to bring up multiple examples. We just need one to show that htmx makes something simpler.
This approach is not productive. A single example could be easily dismissed on the ground that it's not enough to justify design decisions that htmx has. I wrote multiple examples and provided additional links specifically to show various use cases that htmx covers and to avoid playing ping-pong of tiny examples.
> This isn't one though.
You just picked one example, which also happened to be the simplest, and seemingly ignored everything else. I apologize, I don't know how to continue from here.
If you want a parameter "not if already loading", make it part of the post() function. No reason to make it an attribute on the html element.
It’s nice and easy to work with, and lets me keep almost everything in python (flask).
It’s a bit more bandwidth, but it’s a hobby/bootstrapped project right now, and since it’s an api, if I ever make any money, it’ll be easy to rewrite and heavy lifting.
I like it because I’ll write 3x the code in the same amount of time if it’s python. I just don’t like js much even though I know it’s fine.
HTMX substitutes a DOM element with the HTML response you get from an on-click HTTP request instead of redirecting to a new page.
Claims of HTMX being yet another complexity or yet another JavaScript framework fail to acknowledge this.
Just look how VueJS got started, it began with sprinkled in html and was marketed as the framework for backend devs, as you were just writing html to render lists/objects etc.
And htmx does more then what you're alluding to here, as should be obvious from reading their docs about server-side events, notifications, lazy loading, JS extension api etc
<button hx-post="/upvote"
hx-trigger="click"
hx-target="#notification-bar"
hx-swap="outerHTML"
>
Upvote
</button>
Well where is this notification-bar? It could be anywhere on the page. Maybe it was introduced by another htmx action from another endpoint. Answering this simple question could take a lot of work. There is no way to work it out systematically short of auditing every interaction on the page. $('.foo').on('click', () => $.ajax(... $('.bar').html(result) ))
become unmanageable just as quickly.For example the upvote could be implemented like this:
function renderUpvote(container, showNotification) {
$("<button>").appendTo(container).on("click", () => $.ajax( ...
result => showNotification( result ))
}
Now the notification action is passed in from a parent component. It's easy to trace where it comes from. You can also declare local variables in this function and have confidence that they will only be manipulated by callbacks within the module. This is how I wrote frontend code before React came out.An idea could be that the notification bar is polling a notification endpoint every Xsec or on a specific event [2], or if you want to be fancy with WebSockets [3]
[1] They actually talk about this: https://htmx.org/essays/locality-of-behaviour/
[2] for example afterRequest or afterSwap : https://htmx.org/events/#htmx:afterRequest
(I've never used HTMX or even looked beyond this page for it, so maybe what I'm about to say is logically wrong.)
If I said that for an HTMX project you must define all components you use within the project, wouldn't this hx-target example be very easy to identify quickly in the project? You simply grep '#notification-bar' and see where it lives in the project...
I think the goto comparison is somewhat related, because it's about reasoning about control flow (or rather, how it makes it unreasonable) - but isn't this example pretty easy to reason about when you consider you're one search away from finding the notification-bar in the project? You're still creating a tree of components and interactions, and in order for that to happen, you must be able to reference them with confidence in some way.
I still prefer the React way (tree structured components) regardless, but HTMX does seem interesting from a DevX point of view. I think it'll be forgotten about in about 5 years.
Isn't that Haskell?
On our most recent project we do the same with Django and HTMX. Organized endpoints by component. Composable, reusable server-side components with django-components [1]. And we’ve been orders of magnitude more productive, shipping more in 1-2 months than we did the previous 12-18 months working with React.
I believe there might be a sweet spot for small projects unlikely to grow in complexity, maintained by a Python dev who is allergic to JS. But I don't see why you would want to invite yet another abstraction into the web stack, when it's built on top of the very language you're trying to avoid, and which you'll inevitably encounter in all its automagically obfuscated glory as soon as you run into a moderately complex problem.
They have a tiny bit of a point, in that the forms are able to work without client-side JavaScript* thanks to progressive enhancement, and only Svelte and maybe Remix and a handful of others do that. Svelte does a better job of explaining it and making it customizable IMHO though. https://learn.svelte.dev/tutorial/progressive-enhancement
Though Svelte has this, I think perhaps most Svelte devs prefer JSON to form data, because it's directly nestable. That in general is good for full-stack development. You don't see very much TOML in the framework written by the author of TOML, but you do see a little. :) https://redwoodjs.com/ form-data is very TOML like in its data model.
* Except nowadays most of them depend on it to be usable.
Notably, since a few weeks ago, Next.js (by far the biggest of the pack) has support for progressive enhancement with Form Actions.
https://nextjs.org/docs/app/building-your-application/data-f...
As an aside, htmx uses JS under the covers to make HTML dynamic.
You are putting far too much faith in the design of web standards.
Anyways, here's a counterexample to your claim:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...
And of course <button type="submit">, <button type="reset">, annnnnd cough <a>.
There was <blink> and for some reason still <marquee> if you wanna consider animations dynamic.
HTML is interactive and dynamic.
EDIT: Oh wait, maybe they did now that I re-read it... maybe? I think it's time for bed.
htmx simply generalizes this concept, allowing any element to be a hypermedia control, issuing any sort of HTTP request, in response to any sort of event and replacing any element in the DOM.
I have written an essay on an alternative software design principle to the traditional separation of concerns that we see in web development here:
HTMX effectively used js for a polyfill of potential html standards, very similar to using babel or postcss to prototype a proposed spec.
I seriously doubt many people decide they prefer coding up logic in attributes. It's just what HTML gives you as an extension point.
The project I’m currently building is an enterprise b2b SaaS and I’ve gotten it fully functional without writing a single line of JavaScript. By functional I mean it looks and behaves like there is JavaScript, because there is with HTMX, but it’s abstracted away to the point of taking none of my time, which is what matters.
There’s no way I could learn the JavaScript ecosystem in a day. Maybe I could get something functional in a day but the technical debt would be too costly. I’m not sure any human could learn it in a day with acceptable technical debt trade offs.
For my situation of an enterprise app that’s mostly declaring resources in the backend via API, it’s been much faster to write in my preferred backend language only. I build the API, make a command line tool in the same language that calls the API, then add a basic HTML form for the demo and it’s great.
However you would just be able to do what you can do with SvelteKit (Parts 3 and 4). Not too different from what you can do with HTMX.
You would need to deploy SvelteKit but could have SvelteKit call your backend API for all of the heavy lifting and its deployment requirements would be minimal.
Yes, a bigger chunk of the JavaScript ecosystem takes longer to learn, but you can also do more with it. If you make an apples to apples comparison I think they're effectively in the same ballpark, and JavaScript is better just by having more resources.
I think if you are, like me, someone who for various reasons never followed the JavaScript ecosystem for various reasons over the last few years (in my case because I was working on exclusively backend APIs in C#), coming back into trying to do any frontend website is just ten thousand people saying "it's not that hard, just follow something like this: x", where 'x' is any one of forfty hundred humungous different frameworks.
If you don't want to have to learn a whole new ecosystem but just want to bang out something that can take advantage of a bunch of modern-ish nice front end paradigms like being able to selectively update individual components without having to do a full page reload then htmx feels like it would hit the spot for a lot of different use cases.
(I say this having only read the site several times, usually when it pops up here in some context, and I always think "oh damn yeh that thing exists, I have to give it a go at some point!" but never actually have yet)
Here's your list of examples: https://htmx.org/examples/
Here's validation: https://htmx.org/docs/#validation-example
It looks kinda like ruby.
https://htmx.org/essays/when-to-use-hypermedia/#hypermedia-n...
You said it yourself:
> We all have finite time and it's great to learn something once and be able to use it multiple times.
We all have finite time and it's great to use tools that help us work efficiently, following the strengths of those tools, instead of having to maintain unnecessarily complex solutions
It also uses a DSL that has no application outside of its specific corner.
It also forces you to return HTML fragments via AJAX.
By the way I did use intercooler.js (prev. iteration of htmx) intensively and while I liked it at first, it really added up to being an HTML/JS soup when other developers started extending.
14kb
> It also forces you to return HTML fragments via AJAX.
not true, you can return anything. support client-side templating for JSON etc
So, I did the world a favor and wrote just such a definition: https://github.com/prettydiff/wisdom/blob/master/Easiness.md...
https://mastodon.social/@UP8/110432673973724419
This is a research project, but it's a research project by an applications programmer so it has to be solid. Yet I have to be able to change anything when I want to do it and if I used the "standard model" I'd have to change both the back end and the front end when adding a new task but this way I can add a new form once and add it to the rotation, pop it up in a modal, split it out on another page, etc. If this was a big production system with lots of people tagging things I could roll out new tasks by rolling out new forms and not force reloading of a front end.
I use it together with other client-side Javascript, for instance with D3.js for highly customized charts and visualizations.
A major time saver is that it skips the Javascript build. When I make I change I reboot a Python server and it comes up in 1.6s.
I've also found the productivity of a "strong" decoupling from frontend and backend to be super satisfying.
Suppose you want to add a ‘plug-in’ such as a new social media share button: often this is going to involve front and back end changes. In my RSS reader this could be a python package with declared entry points so the application could read it, enabling a few more http endpoints and also adding templates to extension points.
In a ‘standard model’ application you need to have an npm package and a Python package and corresponding extension mechanisms on both sides. You can probably make a system that wraps an npm package inside a Python package or maybe the other way around but it will be a struggle.
(The architecture of my current system was inspired by a system I worked in that not only used Scala, Typescript and Python but also Docker such that builds took 20 minutes! They could afford to do that on a venture capitalist’s dime but I can’t.)
I used to work at a marketing agency many years ago, there's a huge number of professional, revenue generating websites out there that just host a form. And that form probably just needs to send an email.
Using a form, then a network request to some service, then showing some HTML will solve 100% of the problem for the local hair salon taking reservations, some mom and pop store's contact form, or a local newspaper's letter to the editor form.
HTMX supports that flow with a couple of HTML attributes. Barely anymore "code" than authoring and styling the actual form.
To be fair, a callback and fetch() call aren't much harder but provides just enough complexity to make shooting yourself in the foot easy when you bill hourly on a $200 budget.
You don’t need JavaScript or htmx for this. It’s been in the html standard since 1.0. Forms work from plain vanilla html.
> Using a form, then a network request to some service, then showing some HTML will solve 100% of the problem for the local hair salon taking reservations, some mom and pop store's contact form, or a local newspaper's letter to the editor form.
All of these things can be done without htmx or JavaScript. It’s just forms.
(You “need” htmx or JavaScript if you need to dispatch a request without actually submitting the form and triggering a new page load, for example to autocomplete an email or get search suggestions. None of your examples need that.)
The point they were making was that for many small single-purpose sites the interactivity needs are low but for various technical or social reasons may be higher than exposed with pure html/css, and htmx meets those needs adequately without adding much additional complexity.
But they used forms as an example, and now you're deep in the nitpicky weeds about the semantics and capabilities of html forms, having missed the point and left it in a ditch miles ago.
If you're going to make a point like that via examples, they should be (in aggregate) useful examples that make your point!
Even setting aside that examples made up basically that poster's entire point, the reason people provide examples even for more developed argumernts is because concrete evidence is important to persuasiveness (not because they are being charitable). When someone tries multiple examples and none prove their point, it's perfectly valid to point that out.
However, stating that we're avoiding "idiomatic code" is incorrect. Are you claiming React and JSX and useEffect are idiomatic? Really? Surrounding HTML fragments with return() and attributes with braces is idiomatic? These are literally the antithesis of HTML.
Perhaps the real reason we're happy is that we're experiencing a huge productivity increase, lower cognitive load, fewer difficult bugs, terrific performance, and a great dev experience.
<form hx-post="/test">
<input _="on htmx:validation:validate
if my.value != 'foo'
call me.setCustomValidity('Please enter the value foo')
else
call me.setCustomValidity('')"
name="example"
>
</form>
It has a multiline HTML attribute value and an unfamiliar programming language with the english word me that is sure to be confusing to some who don't speak it as a first language.Me/my is rarer: Reminds me of VB
it's based on HyperTalk, the scripting language of HyperCard:
with some Web-specific syntax thrown in to make things cleaner:
add .visible to <section.fade-in/>Where are the docs that make it easy to avoid hyperscript, if it's usable without hyperscript? This has hyperscript sprinkled in: https://htmx.org/docs/
In the example above, if you need custom validation logic, you could handle the HTMX:validation:validate event with any normal JS event handler.
Of course, it's up to you to decide how much effort to put into client-side validation that can be easily bypassed.
If you really need client-side, yes, of course you have to script it. If hyperscript is not to your taste, you use a bit of js.
Ok, but note that a big part part of the appeal of htmx is that yes, you work mostly server-side. If your use case absolutely needs client side code, htmx might not be the right fit. (But in many cases you don't need as much client-side Code as you might think at first.)
i use hyperscript because I created it and like it, but the example could just as easily use JavaScript, the point is to show that htmx respects custom validations
They do suggest being able to use it without learning a lot of hyperscript, but I see the same with Svelte, where you can get by on copying and pasting a great deal. https://learn.svelte.dev/
htmx generalizes HTML as a hypermedia, making any element a hypermedia control that can issue any type of HTTP request in response to any event and target any element in the DOM for replacement
that's the concept, improve HTML, and it gives you quite a bit more than plain HTML, but it is intentionally constrained to not go beyond that
for things beyond what that gives you, I am not afraid to recommend scripting: Fielding explicitly included scripting as an optional constraint his description of the REST-ful architecture of the web
A good example of how we like to see scripting used w/ a hypermedia system is the Sortable.js demo, which shows htmx integrating w/ Sortable.js via events, the cleanest way to integrate hypermedia controls w/ client side scripting:
https://htmx.org/examples/sortable/
we have a chapter on client-side scripting in hypermedia systems here:
I'm not suggesting that you don't. I'm suggesting that it's quite similar to SvelteKit, Remix, and now Next.js, and other form-friendly frameworks in what you'd need to know in order to do a non-trivial full stack JavaScript project that supports progressive enhancement.
The unfamiliar programming language (which I've never used) seems to be binding some code to some type of validation event. "my" and "me" seem to refer to the input tag. "my.value" probably refers to the value of the input. If it's not foo it calls a setCustomValidity method with the input tag as the caller. Could be some built in method that you can call on any input tag or anything validatable.
Ok I just checked the link and setCustomValidity is part of the HTML5 Validation API (haven't worked on web dev in years).
I can assure you that the first person pronoun is among the first things we learn when studying English and assuming the code snippet does what I assume it does I'd say it's pretty intuitive to learn. Especially if we are comparing it to JS where "this" is not what you'd expect from using it in other languages, but the late-bound called of the function... except in all the cases where it isn't.
In any case, trying to guess how a programming language works is a very bad idea so it doesn't matter how obvious the language manages to be, you still should read the documentation.
Or maybe people are kinda informed, and simply drawn to HTMX because it's easier to learn than Vue, Svelte, Mithril, Cycle, whatever (or they just don't want to try a zillion frameworks) and it works really well and developers seem to love it and recommend it a lot?
But isn't HTMX one of said zillion frameworks? What makes it any different?
Here's polling in Svelte: https://stackoverflow.com/questions/61391174/how-to-do-polli...
and in HTMX:
hx-trigger="every 2s"
https://htmx.org/docs/#pollingMaybe Svelte has an easier way, but Google isn't directing me straight to it, which is all part of the "easy to learn" aspect.
Sure you have: literally any frontend framework post, from React and Vue to roll-up, webpack, and everything in between. Tons of non-FE engineers or engineers that work on small and trivial apps will flood in to say why the lib in question, and usually the entire FE ecosystem, are crazy, rapidly changing, undecipherable, etc.
i have a free book available on the hypermedia approach and how it contrasts with the SPA/thick client approach (both its strengths and weaknesses) here:
I’m fine learning JS, but with the ecosystem it isn’t just learning JS. It’s learning the new hotness for packaging / versioning, it’s the frameworks that are constantly in flux, it’s the inconsistent abstractions that seem to be mercurial and constantly changing.
If we were to sit down and write some frontend code to say, make a simple kanban board every 9 months using “current” JS best practices or popular frameworks over the last 6 years…
How many different tools might you run across?
How easy would it be to take that 6 year old code and bring it up to modern standards?
The reason you see people allergic to the JS ecosystem is because it is incredibly opinionated while simultaneously being a free for all.
And you can always just write the thing in JS without any hotness at all. The JS ecosystem's obsession with frameworks is a diversion. You really only need a framework if your site is super complex. And even then, if you're careful about how you write your JS, you may not need a framework (you'll end up creating your own, probably).
I'm with you that the JS ecosystem is a seething mess, but I don't think that's actually a problem unless you want a job as a FE dev. You can just ignore it ;)
90% of the toolchain is not required at all. Just quality of life improvements.
Good ES6 (and TS) idiomatic code feels actually closer to reading Scala than reading a legacy Jquery app.
And the V8 engine has so much investment in optimizations today that is actually closer to Java and in some cases lighter than Go.
IMHO people don't hate JS in reality. They hate the strawman made of the worst parts of Junior code ever encountered and inconsistencies that really don't happen in practice unless you actively look for them.
The end user is NOT writing Javascript.
You write fantasy future JavaScript. Sure, it will be available in ECMAScript 23, scheduled to drop in real browsers in 2092. But for now, here's a convoluted mess of polyfills, Babel, and WebPack, that we HOPE papers over the real behaviour of browsers, and suddenly your test-and-debug cycle has introduced a flow-shattering 15-second build cycle each time you change a file.
The only thing which I believe is still needed is a bundler when your project grows to a certain size. Fetching a complex graph of thousands of files will likely never be fast.
Using webpack resulted in some of the most painful experiences of supporting serious production software in my career.
The progress and maturity of JS tooling/DX as a result of stuff like esbuild and Vite, or Typescript more generally, can not he understated.
For people not doing frontend it can seem like a neverending series of new stuff but there is a very rational and tangible level of progress being made. Especially for serious JS devs not jumping on hype trains.
I don't miss the days of gulp and webpack at all and I don't blame anyone for hating on JS if they experienced using them professionally.
Now Vite seems to be all the rage? But is it a bundler?
Wepack seems to be very hard to configure. Looks like nginx config vs caddy config.
Rather, one would opt for something like vite, the spiritual successor to react-scripts, that bundles all of these tools together with some good defaults/plugins, a means to configure them, and usually also some kind of dev server with hot module reloading, for a complete developer experience using your preferred toolchain.
Check out 'parcel' for something pretty modern, universal, and low effort, IMHO.
I never invested too much time in understanding webpack but it does feel like fighting it a lot of the time when I want to change something in my personal projects.
Care to share some anecdotes of those painful experiences?
And a type system... And maybe a styling system... Oh and let's have some nice Rx data flows!
But, jokes aside, even if you go that Route you still end up with a complex npm project that involves dozens of libraries.
I've been at that point every year since starting doing npm spas in 2014ish (mostly as side projects, my work is typically more serverside). At some point I just decided that the upkeep wasn't worth it any more as you create the same stack every year but with wildly different libs. For me the solution was to switch to an elm+sass+webpack boilerplate that hasn't changed since 2018 or there abouts.
A lot of this JavaScript criticism was appropriate circa 2017, but these days JavaScript's gotten a lot more stable.
ES2015 was the one big language update, and although it took a while to all roll out and for older browsers to die off, at this point we’re now living in “the future” and almost all language changes are incremental.
Like, you can write ES modules with async/await and run it in all modern browsers without any compilation. If you add an HTML import-map element you can even import node_modules by name.
Now, most people still prefer to use a bundler so that their users can load a single script instead of dozens of tiny ones, but that’s optional, and the gap between “the code you write” and “code that runs in the browser” hasn’t been this small in years.
Not everyone is on a greenfield project with full authority to grab the freshest and latest. Some of us are effectively living in 2014-- they can't say "no, you can't use IE11" to paying customers, or committed to a platform at the wrong phase of maturity, and remain stuck around a state-of-the-art-in-2014 build process.
There’s one framework that won, that’s all you have to learn, as far as the industry goes (as opposed to hobbyists) it’s been decided. React won. React is the framework you learn.
“Popular frameworks for the past 6 years” - React has been dominant over that entire time period, from beginning to end. React is what you would’ve reached for 6 years ago (it was already mature then, in 2017) and it’s what you’d turn to now. This is what I mean. You could update your React code to use hooks instead of classes - or you could not, it will continue to work if you don’t.
The “JS changes all the time” take is frankly out of date in 2023. “Which framework do I learn…” you learn React, the framework that won. It’s pretty much that simple.
You generally can’t go from company A to company B who both use react and have the same calling convention, code structure or tool chains even though they are both using react.
Retention shows a clear trend for all frameworks and even in general conversation Solid.js has been taking up more and more of peoples' attention with signals.
The compound advertisement of hearing about Svelte and why it's always going to be faster than React because of not having a VDOM along with Solid.js will make a dent in React and it will become the next Angular. 20 years is not going to happen.
So nobody should learn AngularJS any more?
Only VanillaJS.
And my clients are happy it seems.
So React clearly isn't the only choice, unless you're a new graduate with no clue about anything, then sure start with React.
If you built an app in react 16 and wanted to upgrade to 18, using the documentation it almost resembles 2 different frameworks. Sure, maybe the code executes, but all the js devs would be like “why did you write it like that”?
Real Question: Why does this ecosystem have this issue, but others have it less? For example: Why doesn't Python or Java have the same madness?
Please don't read the question as criticizing web dev / JavaScript / etc. My curiosity is genuine.
To be fair, it does feel like C++ is more maddening than Python or Java, but part of can be explained by (1) native code generation (build is way harder than languages that run in a VM) and (2) the insane complexity of the language which _traditionally_ made IDEs much weaker than other languages. MSFT Visual Studio and JetBrains CLion have come a long way. (I can already feel the HN pitchforks poking at me for these C++ comments!)
So we started to compensate: end state: Typescript to fix JS, React/Angular/Svelte to fix DOM API and a npm package hell to have batteries included. And all of that bundles, compressed, etc to have a good download time.
"XML is like violence: if it doesn't solve your problem, you're not using enough of it."
Welcome to real life.
Beware the ecosystem that does not change (COBOL).
There will always be demand. It's likely very practical for certain usecases but that won't stop people from abusing it in full SaaS web apps before some CTO joins and has to abandon it all when requirements evolve. Although I've seen some highly capable apps built on top of jquery plugins like Select2, which were extended well beyond their initial intent. Things that work is all that matters at the end of the day when it comes to making $$$.
It's the exact sort of technology option that is simple and accessible on the surface which is why someone inexperienced would adopt it in the early days. Then requirements naturally evolve and it gets shoehorned into ever more complex situations it was never intended for.
I'm speaking from experience and anyone who has worked in web app dev / JS for any length of time can see this coming from a mile away. The mountain of jQuery libraries alone should be enough but in the history of the internet WordPress is the classic cliché example of a simple technology that frequently gets abused beyond its original design. If your project is small and niche then obviously this critique isn't relevant. Nor is it dismissing the utility of htmx.
There is nothing wrong with offering simple solutions.
The problem with WordPress is that you can't just stop using it and painlessly swap to a more powerful framework/platform. You can really dig yourself into a hole.
This doesn't apply to HTMX.
Being the guy who has to decipher it is not a fun job and gives you perspective on early technology choices.
I've read enough discourse on HN re htmx to recognize people seeing it as an adequate solution for serious business usecases because they don't grasp the natural evolution in demands for complexity and interactivity in browser UIs.
People love downplaying why more serious JS frameworks are adopted in the first place then find themselves in situations that need it but try to pretend they can just force it on primitive "simple" libraries, as we saw with jquery ad nauseam. Or more likely they leave their mess for the next developer to do the job properly from scratch.
One of the benefits of HTMX is that it doesn't add many abstractions, it primarily builds off existing ones. A HTMX dev must understand the basics of HTTP and the DOM, and not much else, to be functional.
I mean, you technically can, but for that amount of work and/or friction you can pretty much go between any 2 frameworks.
If you are refactoring everything because a small subset of features didn't fit the HTMX glove, that's an engineering management failure.
I write plenty of JS (12% of my biggest project, according to GitHub), but it's added onto HTML in such a way that the HTML still works for:
* a security-minded person who has it turned off in their browser,
* a user of a browser without JS support, such as Links, Lynx, w3m, Dillo,
* someone with an older device using NoScript for performance reasons,
* someone with a slow network connection who can't load the included library,
* a server operator who chooses to disable JS rendering/injection and serve plan HTML, such as the website for a Bitcoin conference,
* another scenario I haven't even thought of or imagined yet.
My conscience as a developer and enabler of information access just does not allow me to write off all these people as undeserving of accessing my websites. You may feel differently, and I think that is OK, too...
None of this is possible with HTMX if the user has JavaScript disabled. The first step to using HTMX is to import a JavaScript file from a CDN, and none of the features for partial page replacement will work without it. Whereas with Next.js, with JavaScript disabled, a Link will revert to a full page load where the next page is rendered on the server. It will be progressively enhanced to what appears to be a partial page load by using the same JavaScript that would render the full page on the server to instead render it on the client starting from the current state of the DOM.
Umm, progressive enhancement is a general concept that can be applied to any stack, not just Next.js. With htmx we can just use good old anchor and form tags to fall back to full-page loads if JavaScript is disabled. In fact it makes it more obvious because usually those are the tags we're using even with htmx and JavaScript enabled.
I know that from a webdev bubble it seems the world is made of JS - I should rather say “and its various frameworks” - but that is not the case. There are lots of places where keeping the surface area small is very much appreciated and the concept of using “bundlers” for your moderately complex crud interface will get you laughed out the room. I guess that is where htmx can shine, not in webdev consultancies.
I continue to be impressed with the amount of handwaving the already-initiated do to downplay the horrors that are starting JS development in 2023.
I think you can achieve the same thing with both, but Unpoly is higher level, that means I have to write less attributes/code to achieve the same stuff I guess.
"Compilers" are also a nice way to attach custom code. All the helpers for form validations, the extremely easy way it provides to do modals, and layers in general. The navigation feedback (a'la turbolinks) when navigating across pages, the caching, the error handling. The up-keep for keeping a video player or anything else across pages transitions, and absolutely everything of this can be accessed from a JavaScript API in case you need to perform any of this from your own code and most of these APIs also trigger events.
Probably you can do all of this with HTMX too, but it is more work.
"You can update multiple fragments from a single request by separating selectors with a comma."
"The server still renders full HTML pages, but we only use the targeted fragments and discard the rest"
Wow... Of course full pages should have a lean markup, otherwise a lot of data transfered could be useless, but that's a pretty neat feature
Or point the request to another view that just returns those fragments.
But I don’t think many apps need this level of optimizations.
Not that I'm a fan of doing marketing of tech, but... that's the explanation I find for it.
Can trivially do it in vanillajs so I'm sure it's possible?
It's meant to run on a laptop. In an existing site that people will already be using. It's free software. If you wanna build a native client, too, be my guest. I might at some point.
Having said that, for a time-tracking application, personally I wouldn't be OK with the risk of a browser screw-up (e.g. site data deleted, malware hoses the browser) losing tracking data. But you do you.
You and I don't have the same constraints and resources as Google.
I guess you could block htmx.js in robots.txt to force them to the non-JS experience?
I think people mistake what htmx is - they think it is a way to not write react/js in a node environment.
Where HTMX really shines is being able to bring the experience of writing React-like code without a nodejs environment in Java for e.g. (or Golang, Rust, etc)
FWIW, if that's all you're after, and you've mastered the Rust borrow checker, Yew (a React-like experience), or Leptos (a SolidJS-like experience) might be interesting to look at.
Yew is writing Rust to create html. Same as Java Thymeleaf. Here's the problem - Java developers are bad at UI. And good UI designers/developers think in HTML. I am not pro or anti this situation...im just talking about the reality.
The tooling is also around html. Figma-to-HTML is the most effective way to have your design cycle work.
This is where HTMX shines. HTMX is just HTML++. It is is not Rust or Java. Which means your design cycles will continue to work.
I was just suggesting, if, by "react-like" code, you meant "a UI library that uses a vDOM to transform functionally written code into DOM nodes", Yew fits the bill.
Also, typically, one writes JSX when writing react, not HTML. It's similar with Yew[0].
If you're already aware of Yew, I'm not trying to change your mind. I was just trying to make you aware if you weren't already.
[0] It says so right on the homepage: https://yew.rs/
Generally, Alpine would handle pure client-side functionality, like toggling classes, expanding a drop-down multi-select, etc.
HTMX for server interactions, fetching, posting updates, etc.
One can accomplish a lot with little to no JS, with the app primarily driven by the backend. Which is quite a benefit if you know and like PHP/Python/Go/Elixir/C++ better than JS. Or just don’t like working in JS.
On the other hand I am so pampered by front end component based templating especially with Tailwind.
It would be cool if I could just import my Svelte components from Django.
react.dev and reactjs.org has had 2 root url submissions: (728 upvotes) https://news.ycombinator.com/item?id=35186812 and older https://news.ycombinator.com/item?id=15366446
vuejs.org only had about ~1 meaningful root domain submission: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
I suspect HTMX is more of an idea that people like to talk about on HN more generally, like Clojure and Erlang. Being the underdog matters on social media. Maybe it feels more authentic or relevant to discourse because it's still niche.
Pretty glib take.
The more exposure this stuff gets the better. I'd really like to have more job options out there that don't involve maintaining an internal web API so that two applications you own can talk to each other.
Unpoly has similar goals to htmx, but by default works with full page responses, swapping only the identified content in the page.
Or another example, the teddit reddit-frontend has collapseable threads with the summary/details tags, also works without javascript.
And imagine if htmx became absorbed into the real html standard. It would take much longer for the standards body (and then browser makers) to respond and implement.
So the crucial flaw is that it will always be reacting instead of innovating. And more generally, this is likely why the “thick client” approach is more popular on the web these days. Nobody wanted to wait around for standards bodies and browser makers.
But the truth is, HTML itself does so very little that it’s barely useful as a starting point for building applications.
Arguing about idiomatic HTML in this context is like arguing about how to write a scientific paper in idiomatic toddler language. One faction thinks you should stick to monosyllabic words. Another believes drawings of colorful balloons are key. Both are held back by the fundamental assumption.
I kinda like the aesthetic. It feels a bit like what HTML might have looked like if XHR had been baked in.
Even though JS is ubiquitous and small, well written JS is harmless, I still try to avoid it like the plague. Maybe just to somewhat fight back against all the excessive JS that plagues every site.
The point of HTMX is to avoid writing custom JavaScript.
Are people driving the tools?
Or are the tools binding people?
Some discussion 5 months ago:
Pick your poison because in any case there will be crossing of those concerns.
Personally I've never seen react code that doesn't go sour beyond a toy demo.