I am burnt out (but recovering!) with web dev and htmx is what I am using for my project.
Django, DRF, Postgres, tailwind and HTMX.
I am so tired of all the front end frameworks and all the complexity that gets added. At some point I think you need it and you get returns from it but hearing more people in the industry recognize and talk about how JS everything isn't always the answer gives me hope.
I like what HTMX has to offer and I am excited to see it continue to get air time.
If you are burned out because of tooling, but trying to recover, I do recommend throwing out tailwind and just use pure CSS for your styling. Modern CSS is plenty fun, there is no need for an external framework to do a complex layout. CSS grid is the simplest way to do layout even if you include CSS frameworks. Custom properties (CSS variables) are more powerful then reusable styles from frameworks.
The final peace of the puzzle is getting component scoped styles, which you can do by packaging your components into a web component and using the shadow DOM. CSS custom properties actually penetrate the shadow boundaries so it is a nice catch-all. If web components scare you (which is reasonable, they are scary) then there are other systems (as simple as class naming conventions) which you can use to reach component scoped styles without tailwind.
Do you have any specific suggestions for resources for exercising grid & shadow dom knowledge/chops?
I'm updating my CSS understanding after having left the front end for ~6 years (but having done a lot of front-end work for the previous 10), loving custom properties and am intrigued with some of the systems built around them (e.g. Pollen), trying to figure out where else I should be directing attention.
As for the shadow DOM, it is pretty advanced, I don’t recommend going there unless you really want to learn it. Using web components without understanding can cause way more problems then it solves. And at the end of the journey you get a very verbose system with a lot of boilerplate just to get component scoped styles, which is not worth it. But if you still want to learn it, this is a good place to start: https://developer.mozilla.org/en-US/docs/Web/Web_Components
I've just done a small project using web components. I didn't use the shadow dom at all (please note I have no idea what I'm doing).
This was after reading a single hacker news comment saying not to bother with it, after days of research where everything I read spoke about web components and the shadow dom as if they were inextricably linked.
I didn't want the styles to be encapsulated. I wanted the css to cascade in like it does everywhere else. I don't really see many use cases where you would actually want to style a component from the inside and not have the user of the component be able to style it themselves.
All the blogs I read spoke about exposing a styling api using css variables. But by doing that, are you not going to great lengths to recreate what already exists in the normal dom?
Not really, the shadow DOM is an opt in choice for that reason. Only a subset of cases do you actually want the styles to be encapsulated. The shadow DOM is actually harmful for form components as interactive relations are voided if there is a shadow barrier between them (which has implications on both UX and accessibility; I think there is an effort in WHATWG to fix this). But when there is a usecase, the shadow DOM can be really nice. As you get nice things like component scoped styles and unique idref, among others.
> All the blogs I read spoke about exposing a styling api using css variables.
This might be an outdated advice. You are supposed to use a mix of CSS variables and ::part()[1]. CSS variables should cover the most basic styling while you are supposed to expose style-able elements of your components with the part attribute.
I bought Tailwind UI and am using all their components (or as much as I can). I don't disagree with anything you said but I do like the tailwind features and design philosophy.
I have completely ignored web components and need to learn all about them.
Can I ask you how long you have been using this stack for and what are your findings ? Do you have a complex UI heavy application and can you deterministically say that this stack can replace frameworks like React/Vue for JS heavy frontend ?
Is HTMX really mature and stable for production and massive UI heavy apps ?
I am asking because we are starting a big project in Django, Postgres, Tailwind and for frontend, still trying to use VueJS and we hate SPAs so curious what our options are.
Not sure what you mean by "heavy" frontend, but you might want to look into LiveViewJS (and/or similar) if there's a lot of frontend iteractivity, but you still want to do most of the logic/interaction on the backend.
I don't have much experience with HTMX, but it seems to be aimed at sites with a little bit of interactivity, especially if you want to be "forced" to maintain compatibility with no-js. (I mean "forced" in the positive sense. It keeps you honest.)
Can you speak of your experience with liveviewjs? I've been looking at it, and htmx, and everything else, over the past few months for a heavily-interactive frontend project I need to start.
I'm an experienced ios dev, but in at the deepens with all this js frontend stuff. There are so many options! The one thing I'm sure of is I don't want to use react.
For extra credit look for places in your UI where you need to work with as much data as possible from as many different places as possible. One of places that justifies heavier front end frameworks and SPAs is when you can precompute things on the client side that make it more performant.
Things like efficient updates of large tables of data in the browser that was constructed out of multiple database tables… things like order + shipping status + customer shipping address… lots of day to day business stuff is like this and while you can manage to do it with just HTML and forms with or without JavaScript … it’s very easy to fall into performance traps between big form data submissions, potentially tricky JavaScript loops to shrink the data submission and backend N+1 query updates… it gets pretty tricky sometimes.
The point is the most complicated part of your UI may not be the most visually complex part. It can be just a simple data grid or html table… it can be the intersex of your requirements around the data being handled, the workflow/interactions on the data, and the performance/usability requirements of the users (offline editing + sync on reconnect basically requires a SPA)
This is such sage advice! Pick the hard UI/UX bits and prototype to de-risk and see how it feels once it’s working. Bravo Quekid5!
As for htmx, my team and I have been very happy with a Go + Fiber backend with Go templates and some htmx and Alpinejs for the more heavily interactive parts of a moderately complex application. Not having to deal with NodeJS, React, thousands of JS packages and overly complex configurations has been a blessing. Our system is insanely fast, plays nice with browser history, and is super cache friendly.
We make “component”-like parts such as toolbars, footers, menus, data tables, etc. with Go templates (partials called by a main template) with appropriate htmx. (Edit: we use/love Bulma for CSS.) High degree of reuse, great performance, and low complexity.
Everyone's definition of 'complicated UI' is different, as is the amount of reactivity you have in your app (e.g. when this data changes, what else in the UI needs to change?).
There is one caution I will give: try and predict where you will be in 2-5 years. 5 years ago I built an app with complicated screens server-rendered with a smattering of Vue to enhance them. We are now moving more and more of the screen into Vue because the reactivity has increased. It would've been better to decide to build _this section of the app_ in Vue from the start, though situational constraints (aka the budget) would have prevented us from doing so anyhow.
That is sound advice and I take it to heart. I was mainly wondering if you'd hit any roadblocks whose existence might not have been obvious from the outset?
Nothing in particular that I wouldn't have predicted (from a detailed reading of the tech). I guess one thing to always keep in mind that these are frameworks that are limited by the client<->server interaction as a critical path. If you're doing a full SPA-type-thing you have to option to do optimistic updates and that sort of thing, but IME that's advanced stuff that only major orgs should even attempt to do.
Positive experience with Phoenix LiveView here. I don't know what you mean when you say heavily interactive but I've got: via JS hooks: drag and drop and charts; and hand built with live view: data tables with filter+sort, query builder and a simple report builder. It's pretty easy to hand off to JS when the need arises.
Have you considered https://inertiajs.com? It's still SPA-ish, but keeps server-side routing and controllers. To me it sort of looks like templates rendered in the browser with almost no need to keep state and juggle xhr calls, the app component just re-renders with new props whenever something is submitted to the server.
"I'm burnt out on frontend frameworks. HTMX has been a good change to JS heavy alternatives."
"Can you give more thoughts on it for heavy interactions?"
"You might try LiveViewJS."
"Can you tell me about your experience with LiveViewJS?"
"Have you considered InertiaJS?"
I have no intent here other than I found this circular chain amusing. Let it go on long enough and someone will without a doubt recommend HTMX as if it's something they don't expect the parent has heard of.
https://htmx.org/essays/when-to-use-hypermedia/ addresses your first question. The tl;dr is "probably not" as htmx is not really designed to handle complex browser-based UIs, but I have seen people in this thread and elsewhere discuss more complex use cases, so YMMV.
If you hate SPAs and are chafing against Vue for building your app, it's probably worth considering if your app absolutely needs to be a JS/frontend-heavy product, or if it would be viable using a more traditional HTML+AJAX design.
Highly recommend the post and video mentioned above! The SaaS application shown in the video is non-trivial and appears to be very well done using htmx. Worth a close study https://htmx.org/essays/a-real-world-react-to-htmx-port/
I default to using Vue.js imported via a script tag inside static html pages styled on bootstrap. It’s perfect for basic apps and you don’t really lose a lot on interactivity. Backend, current fav is FastAPI.
Curious at why are you using DRF with HTMX; isn't DRF more common when you need to return JSON for example and render in the frontend? Wouldn't returning Django templates to use with HTMX be the best option? Or is it for POST requests?
Does the server renderer call the API routes via HTTP, or does it have a more direct path to fetching the same data? If HTTP, what interface does it use - loopback or the public address of the server?
In my experience this distinction has been a source of complexity in server-rendered apps that consume the same API as the client but at a different address, leading to problems like untrusted self-signed certificates, mismatching hostnames, and leaky proxy routes.
Or perhaps none of your server rendered pages even call the API directly, and you just expose it for other clients?
As long-time (and happy) DRF user of more than 7 years I've recently switched to django-ninja [1]. It's like FastAPI, but for django. Granted, I've only used it for a couple of months now, and also not in production yet. But I think it's pretty nice and a breath of fresh air for django. The thing you get from using it is full typing and IDE support (autocomplete!). It's using pydantic instead of DRF's serializers. Can definitely recommend so far.
I played with HTMX and I think it just pushes complexity into the back end that now needs to render full and partial pages. Granted on the back end you get to do traditional programming and pick your language
Not sure I agree. Yes, it requires more work on the back end: rendering templates for whole pages and parts of pages, then integrating them. I've done it with Python (FastAPI/Jinja2 & htmx). My only SPA experience is with dotnet on the back end and Angular on the front. Based on that experience:
1. Python with htmx has less accidental complexity. It doesn't get rid of intrinsic complexity of the domain, but it does reduce technology-induced overhead.
2. Dotnet/Angular tech split has organisational implications, tending to encourage a division between front end and back end developers. Communication and coordination overhad goes up correspondingly (Conway's law).
3. htmx is stable. There's a lot less churn than with Angular. I haven't measured this, but subjectively, there's less time spent updating packages and re-testing. Keeping FastAPI/Django/Python update is approximately equivalent keeping the dotnet back end up to date.
4. State management is simpler. There's no front end caching to deal with, and so no corresponding cache invalidation questions.
I'm not building tech unicorn sites, so can't comment on whether the technical overhead is justified at that scale. I _have_ been pleasantly surprised at the level of UI sophistication that can be achieved with server side rendering and htmx.
I'm not a big javascript fan generally, so definitely have bias. I also have an increasingly allergic reaction to accidental complexity, so am constantly looking for ways to minimise it.
Based on those biases and experiences, my default starting point is SSR+htmx. In my experience the accidental complexity is lower, productivity higher, and intra-team communication better. YMMV obviously.
I imagine that by moving this to the backend you could guarantee (at compile time) that all Ajax calls on the client have an associated backend endpoint. This eliminates dead urls, and gives you more opportunities for code generation or IDE-style autocomplete when creating Htmx views.
Do this in a static functional language and your whole app will more “deterministically pure”.
So yes, it causes more work on backend but, given more tooling, it can provide more opportunities for less code written overall via code-generation (like how creating a model in Rails generates lots of helpers).
In a lot of cases you can go a long way without having to adapt the backend at all - just request the full page at the existing url and pick which part you want to replace. Works well enough with a page that presents paginated items for example.
I'm a huge proponent of Tailwind. What I tell people is to ignore their gut impression and just try it out.
Equivalently, my first impression of HTMX is that I kind of hate it. But I could see it being similar to Tailwind, where you just need to try it out and then it'll click. Is that fair to say?
I second Tailwind as I can't stand complexity, so I'm trying to simplify the entire stack down for _just_ my needs. Tailwind is a big part of simplifying my life.
The other part is that I'm trying to simply "fix HTML", and I believe HTMX is pretty great. I'm taking a different approach as I have a reactive backend, and I can make the HTML simply be a template of a streaming JSON object. It's like mustache with reactive data binding.
I'm enjoying, but I'm not a consultancy so I don't need to push the framework for every usecase.
I've tried Tailwind, and as a back end dev who only really understands the basics of CSS I find it a bit overwhelming and open ended. Seems it's designed for people with already a really deep knowledge of CSS who can could create beautiful components with it if they wanted but for whom hooking up the CSS to the components is painful. If you aren't good enough to create components with CSS in the first place, seems better to stick with things like bootstrap/bulma no?
Or you can use tailwind-ui components that look way more polished.
Another big advantage of the Tailwind approach is that you can copy any component you see on the web, paste it in your project, and it will look the same (unless custom classes are used). No need to hunt down and adapt the whole cascade of styles for each tag.
In that sense, Tailwind has some of the earlier-Internet charm where you learned by seeing what others were doing.
100%, absolutely. It’s not an abstraction of CSS; if you don’t know the language already then it won’t help. But if you do, then it improves your productivity dramatically.
If you’re in a scenario where you’re tasked with building out UI, but don’t have design or FE skills, my recommendation would be something like bootstrap or MUI.
Agree. The idea of Tailwind just feels wrong because it goes at the opposite of everything we can believe regarding content/style separation. But the fact is, it's amazing to use.
Maybe it's not for everyone, but it really is worth a try, with an open mind.
It’s such a cool experience - actively disregarding well-established principles that have been in place for 20 years…only to have it fix nearly everything that I hate about CSS.
For me, it clicked immediately. It is a simple way to partial updates of the UI, without having to worry about a ton of tooling. It also pushes most of the logic to the backend, which is nice. It also constrains some of the UX decisions, leaving less room for useless craziness.
It's tiring, but for those of us that have the humility to know, for example, that we aren't experts in implementing every last detail of WCAG-spec compliant accessibility --and the application I'm building requires it-- it's better to build on top of someone else's solution. There's so many pitfalls to quite easily writing un-semantic, incorrect HTML. Browsers are forgiving, but a screen reader won't be.
IME, HTML-driven web applications (to say nothing of simple pages) in the field are generally more screen reader friendly than SPAs, though you can certainly achieve good accessibility with the right team and resources.
I’m pretty burned out by devops and backend solutions. I think the number of cloud native services and tools is similar if not more exhausting than FE in terms of depth and complexity.
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).
The point you're missing here is that if you use HTMX, you often don't need to write any JS. You just write HTML with some special tags, and the library handles everything for you.
Unless you only consider the happiest path, as in "I develop on localhost with zero latency, 100% uptime, and my backend validation logic perfectly matches my frontend policies" (and probably a lot more other "if"s and "only"s).
If the HTTP request that htmx has made returns a status code >= 400 or times out then the response will not be swapped into the body.
There are several events that htmx fires, once of which can catch `responseError` [1] and you can write some Javascript to handle it according to your requirements (throw a toast, swap anyway by setting `evt.detail.shouldSwap = true`.
In a project I'm working on we use htmx to load the content for modals, so we have small handlers on htmx events to display the modal whilst the request is being made, put a spinner indicator in the modal body to show the user something is happening and then swap the body in once the request has completed.
We've also used `HX-Trigger` response header [2] which htmx helpfully catches and allows us to easily hook onto, we've got ones to display a toast notification, hide open modals, refresh content divs, untick bulk action checkboxes, etc.
All in, our project probably has around 200 lines of Javascript for the different event handlers we do, so it doesn't eliminate the need to write any JS, but it's significantly reduced and is pretty much all event handlers.
so would you say that one of the first things a htmx based project should do is handle all the error conditions ? like all the 40x and 50x ? and stuff like your modal thinggy ?
how do you develop the js here ? do you setup a different nodejs/npmjs toolchain. or do the jqueryish development of edit->browser reload ?
> so would you say that one of the first things a htmx based project should do is handle all the error conditions ? like all the 40x and 50x ? and stuff like your modal thinggy ?
IMO yeah, but different pages and actions will (probably) want different things. For example clicking a button that makes a POST request may make more sense to have a red toast notification if it fails, however a tab that dynamically loads its content in using htmx might want a dummy placeholder saying "Sorry, try again later" or something like that. Functionality around the modals were done as and when we needed them and then expanded on over time so I don't think you need to write/know everything up front. It's honestly been a joy to use based on how simple it is once embrace server side rendering.
> how do you develop the js here ? do you setup a different nodejs/npmjs toolchain. or do the jqueryish development of edit->browser reload ?
For my projects it's just 1 or 2 JS files that are included in my base template that contain the event handlers, so it's quite old school of edit and refresh. I use Django mostly now so I can use that to collect and minify static files so it's low effort/complexity.
The only down side is for the few JS packages I do need (e.g. Select2 for nice dropdowns) I either vendor the package in (no automatic updates) or use NPM (but it's a pain). Again, depends on what you want because htmx doesn't care either way.
React forces you to think like how its designers view the world.
While alpinejs does not really interfere with your workflow. That's a huge sell for team like mine where we are working with legacy projects and devs of various levels of XP. We can get a jnr dev up and running in a week flat.
hey thanks for that. any particular opinions on hyperscript vs alpinejs ?
hyperscript is said to be "made for htmx". But alpinejs is generally more popular standalone. so im wondering about the choices here if we're starting a htmx project.
The most popular JavaScript engine (V8) is written mostly in C++. Same with WebKit. Other JS engines are written in Rust, like Deno or Servo (used in parts of Firefox).
I'm not aware of a major Javascript engine which is written in C, except for QuickJS, which is not "major" in any sense of popularity but is an efficient engine for embedded use cases (and anything from Fabrice Bellard is always work a look).
How do you integrate tailwind and django? As far as I know (which isn't very much), tailwind encourages the use of "components" which comes very naturally with other frontend frameworks. But with django, do you put each component into a template, like `<button class="rounded xxx"></button>` and `{% include "button.html" %}` when you use a button?
About 2 decades of software development and today I would choose the same stack. I've coded in PHP, C#, Java, Scala (Play framework), Rails, NodeJS, a bit Go. Django, DRF, and something like HTMX will be my default choice today, unless there's a specific requirement or the project is something unusual.
I am so tired of everyone complaining about complexity in front end frameworks, as if this sort of thing doesn't exist in other languages and stacks, and as if frontend dev isn't as complex as other domains. Just ignore them or do something else.
There is a reason we complain about front end frameworks. The fatigue is real. The npm and node_modules hell is real. The constant quirks with JS to make it work with our backend is real. I have been programming professionally for 18+ years and even though I can do anything, JS frameworks give me the most anxiety. Just this other day, something broke with an npm package and the error messages require me to hire a cryptography expert. I am half joking.
I am all in for something that keeps us on server side templates/HTML with dynamic capabilities.
I’m tired of everyone talking about the frontend as if it’s a monolith. In a world where web uses span all the way from a blog with a contact form to an entire app like Gmail it’s silly to pretend there’s only one answer.
I think we’re still suffering from “everything with React” syndrome, I’ve never used htmx but if it can help as an antidote I’m all in.
This is so true. I have two real hobbies - web dev and wood working. One thing that makes me chuckle is the different takes the communities have on tools. In the web dev people constantly argue about how there is one best tool!!! The wood workers make an art form out of collecting the most tools possible, because each tool has a job and the person who dies with the most tools wins.
Is the argument here that there are too many JS frameworks, or that the complexity of the frameworks themselves tends to grow over time?
If the former, totally agree. If the latter, Java frameworks are plenty complicated.
Also not sure how you've missed a lot of other frameworks; Spring and J2EE are certainly not the only ones that have been around for 10+ years. Dropwizard, Vert.x, akka-http, GWT, Play... just to name a few.
The argument is that I could learn Spring in 2002, find a Job
then I could learn Spring in 2008 and find a job
and then I could learn Spring in 2013 and find a job and
then learn Spring in 2018 and find a job
and then learn Spring in 2023 and find a job.
Spring IS complex, but you learn it once and you are done with it.
I'm not a java man but a quick google leads to a lot of "10 java frameworks you should know", "17 popular java frameworks", and a "list of java frameworks" on Wikipedia that's dozens long.
Frontend wise it seems similar at a glance, in that you could use react for the last 10 years and be fine. Or you could jump from react to vue to svelte and make life hard for yourself.
Makes sense, probably just ad click driving spam page, appreciate the info :)
I wonder how much of people being burnout on "front end frameworks" is because of "17 must know javascript frameworks" articles akin to the JAVA stuff at the top of google.
Vaadin? GWT? Not a java guy, may miss some distinctions.
As someone who came into webdev only recently with a long experience in just-development, it feels like there is no problem with frontend at all. The problem is that the frontend industry chose the worst perverted defaults and those defaults pay the most money. That’s the whole drama. It’s just a “five monkeys experiment” sort of situation.
Maybe you are? Yes, it integrates existing frameworks and libraries. In fact, the home page says "Dropwizard is a Java framework for developing ops-friendly, high-performance, RESTful web services."
I mean, if you still believe that Java has as many frameworks as Javascript has (and had in the past) there is nothing I can say that will convince you.
I've been using Java on and off since 1996. It absolutely has had a ton of frameworks over the years. Yes, I realize many of them are niche or no longer in use, but that doesn't mean there isn't a legacy application where you have to maintain 10 or 20 year old garbage.
FYI, I despise both J2EE and Spring. (Maybe Spring Boot is okay.)
Spring Boot is recapitulating the worst parts of old (like, 3.0-era) Spring. It's the biggest step backwards in programming history since... I actually can't think of anything worse.
Have been using htmx for a little over a year now, and I am so thankful for this library. It has simplified our development tremendously from ClojureScript / React to vanilla Clojure on the backend doing SSR of HTML with htmx HTML element attributes. All with 1 script tag that includes this wonderful library. Kudos to the creator of htmx!
This is what hypermedia architecture with true HATEOAS is all about. It feels like we took a wrong turn a decade ago, and we have been trying to reinvent rich clients with JSON RPC designs from the 90s. It has resulted in too much churn and complexity IMO.
Doing something similar with janet. Really does simplify so much, and being able to not have to worry about always translating json -> html via { insert SPA framework here } is a breath of fresh air.
Agreed that it is a breath of fresh air. It totally eliminates heavy complexity in the development environment and networking protocol layers. What makes me happy is that it completely reinvigorates the server side language you prefer to use.
I've done a few years of solid frontend dev in the last decade and became efficient in a few different modern frameworks. For personal projects I just pull in a bootstrap and jquery framework from a CDN. I think htmx is going to replace this practice.
Do you know off hand how much JavaScript your pages are including now versus when you were using ClojureScript/React?
I ask because I know ClojureScript is built on Google Closure which has pretty advanced dead code elimination (and typically for React functionality people use libraries like reagant that take advantage of this - I think?). Presumably with htmx users are having to download the whole htmx lib.
The JavaScript we use is now much, much less. Actually, most times we just sprinkle in a bit of hyperscript for the times we need something a bit more dynamic than plain htmx. _hyperscript is a separate library by the same author that provides an HTML type of scripting in the attribute tags.
Still, in general, because we are generating fragments of hypermedia (HTML) on the server and returning that to target elements in the browser directly, the need for JavaScript directly in our code lessens dramatically. As you mentioned, though, you do need to include the hmtx JavaScript libary with a script tag. That library is very small though when min - something like 12k.
Amazingly, you can build some pretty dynamic web apps using htmx and sprinkling in a little vanilla JavaScript or _hyperscript if you are daring! The main key for us though is thinking from a hypermedia point of view with SSR; that coupled with the elimination of the complicated development configurations, is a huge win in simplicity and productivity. No more versioning our endpoints too!
Hmmm. alpine.js does complement htmx very well and is pretty popular, so it is a great choice. I liked _hyperscript when I saw it when assessing htmx so thought they might play better together since the author is the same for both. But I don't know if that is even really true actually, and alpine.js seems to be just fine. Honestly, it may be because I used AppleScript back in the day and _hyperscript reminded me of it!
I will say, the :advanced flag for the closure compiler has caused us some real headaches in production, enough to where we needed to migrate to only the :simple flag.
The reason being, is we needed to do some code gen of Svg components in React Native, and in the build process (via shadow-cljs), the closure compiler was munging the definitions in the.
Off the top of my head an svgr component which looked like:
// generated component
import React from 'react'
function SomeSvg(props) {
return React.createElement(..., ...merged props..., ...children...)
}
was getting "optimized" to be used as:
function $SomeSvg(props) {
return $R.$c($$..., $$...merged props..., $$...children...)
}
The above is psuedo-ish code, but I think covers the point. There were also some edge cases where not includeing a ^js reader macro before using js values caused crashes, due to the symbol being munged in the background. As a result, whenever we used any sort of js, we needed to mark it w/ a ^js reader macro, which began to get really noisey and error prone if you forgot. :simple has made the code based more stable. Could be user error on our end, but the fact that we ran into so much with :advanced and our application stabilized significantly after that one configuration change, it makes me think using :advanced can be too involved.
In addition (to an already winded comment), cljs needs to include the cljs runtime. I haven't benched the size, but it is no negligible (think in the 100's of KB), on top of what react/reagent/re-frame may bring in, you can easily end up w/ a compiled cljs app of > 1MB.
here's a question to you...since ur like, almost from the Java world!
Why not clj-thymeleaf ? or even clojurescript ? this is very interesting that you find HTMX better than clojurescript - typically clojure devs prefer to stay within the lisp world for any markup.
ive been getting pushback in a java team against htmx. cos the value prop is unclear vs jsp or thymeleaf. Would love to hear ur perspective.
I see bnert gave a very good answer to your question in a reply. So to echo what bnert said, as far as the java template frameworks like jsp and thymeleaf, htmx is complementary to them. Here is a good scenario in this blog post by someone.
https://www.wimdeblauwe.com/blog/2021/10/04/todomvc-with-thy...
Also like bnert, when using Clojure we prefer to use a library on the server-side called hiccup to generate HTML from Clojure data structures instead of a template library. Either way, template engine or hiccup HTML generation, the principle is the same. You are coding everything on the server-side and rendering HTML back to the browser - something it is VERY good at rendering. :) As part of that HTML rendering, you are putting attributes on some HTML elements that htmx understands from the browser side.
ClojureScript is a totally different concept, as it basically allows a Clojure developer to write JavaScript in Clojure - it generates JS. With the server-side rendering model above, we still code 100% in Clojure, but we get to jettison a lot of the complexity of the ClojureScript model (Reagent etc), and development set-up. It is far simpler.
Other benefits of the hypermedia approach provided by htmx:
1. It is obviously true HATEAOS, so we don't worry about end-point versioning issues.
2. The barriers of the UI team and Server team negotiating and re-negotiating end-points is gone. We have all transitioned to "full stack developers" - sanely.
3. As mentioned above, it is language and server-side agnostic, so use what you prefer and have competitive advantage with using.
4. Simpler mental model. The team thinks in hypermedia terms from a server rendering perspective only. That lets you wrap your brain more easily around the business problems.
5. You have the full power and capability of your database at your disposal instead of going through and desigining the correct endpoints to get there first.
hey thanks so much for the explanation. so my question about cljscript and thymeleaf vs htmx was because they all do the same thing.
im totally sold on the server side aspect of the whole thing...and especially the "full stack developers" aspect.
what im not sold on is HTMX specifically. im kind of wondering things like "hey what if we just used alpine.js with JSP or thymeleaf and skip htmx entirely", etc
what im getting incrementally with htmx is a bit unclear...while staying in the server side rendering of things.
After a quick glance, it seems like htmx would complement thymeleaf, if the web page/app you're writing doesn't need any sort of eager client (eager as in, treat and interaction with a remote service as "successful" and resolve the error in the background somehow).
W/ htmx + clojure, you can define your ui like so:
And like that you have a page with a button that tracks a counter and updates the ui (I haven't tested this, YMMV).
Also if it isn't clear, you can also keep all your markup as Clojure data structures, which means you can write an `html` function which has the common styles/scripts/etc.. necessary so you get a ton of re-use with an already similar syntax vs needing to learn a new templating syntax w/ its own conventions.
W/ clojurescript, to get the same behavior you need:
- clojurescript toolchain w/ some configuration of how you'll bundle/package it
- an idea of how you'll distribute your application (serve spa from same API service? S3/Object store? another web service? How to reconcile state?)
- an idea of how you'll reconcile state between local/server, if you want to go that route. If only local, nbd. If server, you add a handler and fetch data once SPA or cljs has loaded.
- and idea of what format you want to consume (JSON, HTML, XML,text) and then write the translation between that format and your markup.
etc...
I hope the above answers your question, or at the very least offers another perspective.
As a quick postscript, I think it is underestimated how convoluted templates/templating engines are, given they have the tendency to implement their own language/semantics outside of the PL you're using. I have much respect for the authors of template engines/spec, the engineering that goes into them is impressive, however, most I have come across tend to be a leaky abstraction. Once I experienced writing markup as Clojure data structures, it ruined me for templates permanently. I don't want to go back to writing templates, and doing an assessment of "what language does this template engine implement, and is it simple/easy to learn?" is an exercise I do not miss.
Note: I've been Clojure/ClojureScript developing professionally for almost two years now and have debated most of the above internally during that time. Done some templating w/ JS, Go.
hey thanks so much! truly appreciate the detailed answer.
I have one doubt and uve probably answered it...but i still cant see it.
im not able to figure out what is it that htmx is saving you in the example above. with clojurescript, wouldnt you have written very similar code ? i mean all you are doing is calling an api.
is it automatically doing conversion of JSON to ur DTO/business object. that cant be right can it ?
my mind is telling me that it is some kind of lifecycle management - like before/after hooks. make sure that the html loads after server is loaded, etc. is that what it is ?
Taking clojure out of the equation and only looking at htmx, I would say it buys you is simplicity, and for most use cases that is the difference between a shipped thing and a dead one (thing in this case is project, product, etc...). Granted, htmx isn't a silver bullet, as you have to learn some of the idioms of the library. But it may be worth it to some (it is to me), to not have to bring in an entire JS toolchain to get a thing bootstrapped.
im not able to figure out what is it that htmx is saving you in the example above. with clojurescript, wouldnt you have written very similar code ? i mean all you are doing is calling an api. is it automatically doing conversion of JSON to ur DTO/business object. that cant be right can it ?
It can kind of be what you need it to be (if I am interpreting the API provided by htmx correctly). The way I have been using it is to partially update my DOM based on some user interaction (either a POST, PUT, DELETE), by returning html. This makes updates html -> html vs json -> frontend framework -> html.
As far as ClojureScript code, the above example would resemble the equivalent ClojureScript code almost 100% (with some slight differences). The example above was a little contrived, in that it is so simple. However, if you think about a larger use case (i.e. 100's of elements need to be rendered from a db), it doesn't become contrived.
With a Clojure backend + htmx, all I do is write my business logic, define my html via hiccup (Clojure vectors w/ a convention similar to html) and return the html to the client, which I can ship without needing to coordinate different pieces. In addition, the hiccup I hopefully defined is broken up into functions that'll allow me to partially update the DOM for different user CRUD operations.
With a Clojure backend + ClojureScript SPA, its the same-ish business logic on the backend to return results from a JSON API, some more logic on the front end to validate said JSON, some additional logic to add said data to a global store, then finally my view can update. Then in order to get you're app out there, you'll need to figure how to get you're application deployed. There has been a lot of work in ClojureScript land as far a build/packaging tools, but they can still be rough around the edges, which results in headaches sometimes between dev/prod. After you've gone through that and put your app in an S3 bucket/object store (for the sake of example), you'll need to get your API deployed (which should be same steps as above backend + htmx).
So while it may seem the same, there is a lot more complexity that comes with ClojureScript SPA.
Also, as a final thought for this section, even if you went with vanilla ClojureScript + html, you won't get much for free. You still need to compile your ClojureScript, which still requires DOM API's, which you'll still need to call from ClojureScript to handle updating the DOM from the ClojureScript which still needs to call AJAX/fetch, which still needs to resolve promises in order to get your JSON data (or html data), which still needs to translate your interchange format (in this instance JSON) to html. At this point, are the layers of abstraction worth it?
my mind is telling me that it is some kind of lifecycle management - like before/after hooks. make sure that the html loads after server is loaded, etc. is that what it is ?
Sort of. I like to think of htmx as filling the role of sync-ing my web view/page/app with backend state without all the ceremony and fuss of a frontend framework. I can handle all the logic and UI definition on the server and defer http requests (GET, POST, PUT, PATCH, DELETE) and DOM patching to htmx. Kind of like how a user of a frontend framework defers that same patching to the underlying virtual dom implementation.
Personally, when I first saw htmx I thought "well... that doesn't seem useful. I can get a React (or Vue, or Solid, or Svelte, or X) spun up w/ a cli command and do all my things there. But then I used it and couldn't have been more wrong on its usefulness. I encourage you to play around with htmx, try implementing the counter example in your preferred language, see if you come to the same conclusion you had previously.
There are cases where a SPA is appropriate and merits the investment, but I think they should be the exception not the rule, due to the complexity brought about by a frontend framework.
In conclusion, I hope I answered your questions. I am happy to continue this discourse if you still want to chat about it. At the end of the day though, all we're trying to do is render web pages, so do whatever makes sense to you to accomplish that.
>The way I have been using it is to partially update my DOM based on some user interaction (either a POST, PUT, DELETE), by returning html. This makes updates html -> html vs json -> frontend framework -> html.
oh this clicked. Now i get what htmx is doing. its basically doing a react-ish way of UI changes without a full page reload (which thymeleaf would have done).
so what happens if i click something that needs to go to another "page"? do you "swap" the html out with the html of the other page ? or do you trigger a full page reload.
For SEO reasons, im kinda putting the requirement that every interaction must have a unique url
its basically doing a react-ish way of UI changes without a full page reload (which thymeleaf would have done).
Interesting, I missed that in my scan of the thymeleaf docs. I haven't used that library at all (and tend to shy away from Java land in general, unless it's Clojure).
And for my purposes, yes. I may be missing the point of the library, but that is how I've tended to use it.
so what happens if i click something that needs to go to another "page"? do you "swap" the html out with the html of the other page ? or do you trigger a full page reload. For SEO reasons, im kinda putting the requirement that every interaction must have a unique url
I'd say pick your poison. You could go either route and it would most likely be roughly the same code.
I don't love the idea of implementing common app state logic via attributes. It probably works a lot better than I'm assuming, but it feels hacky to me. Like it can't solve every problem you'd actually encounter when making a complex app, so eventually you'll need to fall back to using javascript, and possibly a framework or three...on top of htmx.
But it does seem like this would be fun to play around with using PHP as your backend. No more JSON, or GraphQL, or bloated frameworks, just intermixed code and markup in the same PHP file...just like the good ol' days! For the situations where it does work, this could simplify the architecture of an app significantly.
Also, 10/10 meme page.
EDIT: are there any large and complex projects using this that are publicly accessible?
I'm using htmx for my SaaS web app. It has a lot of spreadsheets. User can filter, sort, highlight with color, etc. It's for PPC managers, they work a lot with spreadsheets. So I'm making a specialized version of that.
First two weeks was tough, but after I adapted and found htmx idiomatic recipes to common tasks, it is crazy productive. I can show, if you are curious hit me at twitter @alexblearns.
PS. I just believe people have to try it, because it's so much easier to do web apps this way.
I've used HTMX on several projects (Django) and it's truly a great add in. You can basically build a "React" style app with Django. I can't praise it enough.
HTMX is the perfect example of a project that, like jQuery, exists to be replaced with a W3C standard. And I don't think the people behind it would feel at all bad about that, as it fills a real niche that ought to have been filled a decade ago.
Maybe, but probably not because it wouldn't help with paginated data sets displayed in tables. You don't want to sort only the items you currently see, but across the whole data set most of which is likely not loaded.
HTML imports got deprecated in favor of ES modules, because JS was required anyway to use those imports.
I was disappointed at the time as I wish we could make web components without touching JS directly.
Now with HTMX the future sounds promising.
It runs a small mock server inside the browser which is very Django inspired, so it should be very familiar if you have experience with it.
The mock server runs using PollyJS and Nunjucks as the templating engine. There is sadly no mobile support or the ability to save yet, but it's still a great place to start tinkering without needing a full setup.
This is refreshing, and not unlike what Stimulus is trying to do in the RoR space. This is simpler than Stimulus, IMHO.
So much about modern FE dev requires knowing stuff that was intentionally abstracted to purer forms years if not _decades_ ago and easy to pull off in a browser<>server relationship with a little bit of JS for state management or swapping content. The author even uses the phrase "AJAX," which I feel like I haven't seen used in earnest in years. This library is for the OGs.
Obviously, trade offs etc etc. If you're starting a new web based project, something that's just submitting forms and showing results, why would you really use anything more complicated than this? It's sorta hilarious that JSX took off; it shows that the declarative nature of HTML was right all along.
1. One of the most painful thing with SSR forms is passing the data back-and-forth between the server and client when there are validation errors. Sometimes the data is very sensitive and you have to return the form with some values (like SSN) empty and make the user retype that along with with whatever field(s) were the actual issue. I'm also curious about how file uploads would work.
2. REST/GraphQL/gRPC API. Often, if you want to open up your API to internal or external users it's a lot easier if the frontend was already written to deal with protobuf or JSON endpoints. Seems like it would be painful to add an API to an htmlx backend.
Why can’t you hydrate the form with the SSN? If you’re serving it via TLS, there shouldn’t be any problem. It’s no different sending it up to the client than it is for the client to send it down to you. Unless you’re logging every rendered page for some reason, I guess.
Regarding #1, I've found that Phoenix + LiveView has been helpful for these cases. They have great form validation tools using Changesets and the `phx-change` attribute [1]. You can redact certain fields [2], and even treat certain fields like virtual fields (like password not being stored vs the password hash being stored) [3].
Of course, the (potential) drawback is in using Elixir for both front-end and back-end which may be a tough sell to a client or employer.
With something like Django you can make a quick and dirty json API by just returning the context dictionary that you were passing into the template renderer.
We're migrating our apps from Vue.js to HTMX, and it has been a great experience. The size of our codebase has consistently gone down as we move things to HTMX, and it feels like the level of complexity goes down as well.
If possible: Can you say how much of the code reduction is based on not needing to manually handle bespoke request behavior? (errors, transitions, animations, etc.)
Also: How much has the backend's responsibility in pre-rendering grown in response to the move to HTMX?
What kind of apps? I used Intercooler (sort of a predecessor to HTMX) for a personal project and it worked well but I didn't get a good feel for what it would be like to build more complicated UI.
I don't think UI is part of HTMX's concerns. It is a library for submitting data and loading HTML fragments. For general UI components, I like https://shoelace.style/.
Would you be open to sharing your experience on this a bit more ? We have a JS heavy app with 100s of VueJS components. Could those be transferred to HTMX ?
I'm confused about what value this adds. The introductory example is certainly not helpful, as it takes an `<a href="/blog">Blog</a>` and turns into 7 lines of markup to accomplish the same thing. (And then it says a bunch of things that are arguably not desirable, like "any element can now trigger requests".)
Like: what's the point of using this over HTML5+js? I've spent 15 minutes reading the website and I still don't understand why I should want this, especially if I already know HTML/CSS/JS. All it seems to do is add a SGML DSL into your HTML, so you can be all declarative about `onclick` attributes.
The great thing about HTMX is it fits really nicely with templated server-rendered frameworks like Django.
You can have a page with a list of items. The page is one template, and it includes a sub-template which is just the <li> items. Then you have a separate view for "get list fragment" which just returns the updated/sorted/filtered <li>, rendered with that same sub-template. If you toggle the ordering, or filter the list, HTMX will automatically call the fragment renderer and replace just the <li> items, without reloading the page.
This approach solves the common interactivity use-cases requiring JS in a server-rendered app, without having to write any JS, and without having to build a REST API. Instead you just render HTML, which your framework is excellent at.
But you can already do that. I was doing it in the 90s, Ruby on Rails supports it, etc. Just send the HTML if you want to and call `el.innerHTML = response.body`.
The false dichotomy here is that it's either htmx or React. Why not... neither?
but it does support history, collecting parameters from the DOM, an extensive event model and extension model, targeting other elements, listening for events in sophisticated ways, coordinating multiple elements that are making requests, etc.
so there's some additional stuff in there that makes building a proper hypermedia-driven application easier
I ask similar questions about React ecosystem for years and the most frequent answer is “you’ll know when you need it”. Made few dashboards, smartphone-servers control panel with live streams, svg-heavy fully interactive cashflow graph builder for inhouse accounting, a bunch of typical “react” sites (literally because “frontend dev is slow and we need something right now, they’ll catch up later”, how does that sound) and still waiting for that enlightenment to come.
People throw bs under their feet and then learn how to avoid stepping into it too much. It’s insane. I think that htmx, despite clearly being a breath of fresh air for them, is in the same category: it does all you that could just_do already, but looks nice.
Consider the case of calling your backend with a POST call and then updating your app in response.
Typically, for a SPA: your backend would return some data, and your frontend would then figure out how to update your html in response to it.
For a multi-page-app: your backend will redirect the user to a whole new page with new HTML.
This is somewhere in between: Your backend will send just a little bit of HTML and you can update your existing HTML with it. It should feel like coding an MPA, but get the benefits of an SPA.
Yeah, that I understand. I am not a huge fan of sending JSON that's not backwards compatible. Sending HTML is probably a good choice for some applications, but that was already well supported 20 years ago. Why is htmx better than one line of javascript saying `onload = function() { e.innerHTML = response.body` } ?
Look at each of the distinct things that htmx lets you do, and tell me what would be required to do it in vanilla JavaScript. Notwithstanding that even in your example `onload = function() { e.innerHTML = response.body` } [sic{ doesn’t even tell the whole story, HTMX does more than just this and this is blindingly obvious from its documentation.
If you need those things more than, say, a couple of times in your project, the natural thing to do is to factor them out to what essentially becomes a framework.
This is what that is.
HTML element attributes is used as the interface because there are a whole lot of people that don’t like switching to writing JavaScript. You can argue all you like that you’re not a fan of this, but plenty of people are.
You can also argue all you like that one will eventually need to write some JS which will make the whole thing confusing to follow. The reality is that there are a whole load of projects where this isn’t the case.
If you’ve spent this long going back and forth with people about the merits of this project, and still don’t see it’s value, then it legitimately isn’t addressing a problem you have, or, more likely, it isn’t to your personal style/taste, or for whatever reason you are unable to relate it to any personal circumstances you’ve ever been in.
The documentation gives tonnes of practical examples of how the framework can be useful, and there’s mountains of third party examples. Beyond that, your arguments seem to revolve around a lot of technical, performance, and DX hypotheticals that you could test yourself by experimenting with the project. Part of its selling point after all is the lack of a need for complex build tooling.
If you still legitimately can’t see the value then it doesn’t seem worth the discussion.
The reality is that there are a whole load of projects where this isn’t the case
The reality also is you don’t know that until the project is archived. Their questions and doubts are valid, why not just say “yeah, it’s just a nice looking sugar for that with manageable caveats”.
I can see how reiterating on what can be done with it as if that couldn’t be done with AJAX in the same amount of code could make discussion a little confusing.
In practice you don't want to just swap the content 100% of the time. Appending to the current content is quite common too, as is deleting from it. You sometimes need to touch other elements too, or maybe show a progress spinner.
Or perhaps push a URL to the navigation history.
Htmx provides a batteries-included data-driven experience. It is a means to avoid having to write dozens of slightly different variants of the same 5-10 lines of Javascript.
But all of those things are trivial. Are we going to next get a library that lets you declaratively specify string operations and integer multiplication? Why not write a dozen variants of 5-10 lines of readable Javascript? What's the problem? It's maintainable, fast and every other developer will immediately understand it.
One of the stated goals is to make html a true hypermedia language right? That's really pretty much it.
A lot of these objections sound like "why bring these functions into JavaScript if JQuery already exists? Why do we need CSS Grid if bootstrap already exists?" Because those are arguably add-ons meant to deal with the deficiencies of the original technology. Fixing that technology is a better place to be.
Except that it doesn’t fix the technology, it gives the appearance of augmentation via a bunch of JavaScript. Seems more like the jQuery and Bootstrap of your examples.
Sure, you don’t have to look at it, you just program against the interface. Just like you don’t have to look at the internals of jQuery - you just program against its interface.
Please see my answer above, but htmx has some swap attributes where you can declaratively update as many elements of the page as you want. You can grep this id and find all the updates easily.
Hmm so like how Wicket Ajax works, but as something you can bolt on to any framework? That's cool, although I'm not sure how well it would work if the framework isn't component-oriented in the first place.
It's just a JS library that attaches behavior to HTML elements based on attributes where you'd otherwise have to write a bunch of JS yourself. It's just a framework where all the metadata is just embedded in the HTML.
It's pretty clear that TFA means that this is better because that's how HTML should have been, in their opinion.
Is it better? Well, I think so. Practically speaking, for example, if you use NoScript or something like that, it kind of would be if you could block scripts but not HTMX. Also practically speaking the cognitive load of HTMX should be lower than the cognitive load of JS (especially for beginners). More generally speaking, I think it's quite right to say that HTML should have had a lot more of this early on, but the pressure for HTML to evolve clearly dropped once JS came along since JS provided a way to work around the limitations of HTML.
IMO it is a good idea to standardize a bunch of behaviors as HTML attributes for these reasons.
But if you disable JavaScript, then htmx won't work either, right?
And how is it lower cognitive load? You have to learn JavaScript, but now you also have to learn htmx. I don't call that a win. Code is read by a lot more people than wrote it. It's not great if you constantly have to be learning some flavor-of-the-week framework. (No problem learning new things where it's warranted, but this isn't even interesting, it's just a DSL.)
> But if you disable JavaScript, then htmx won't work either, right?
It would work if either HTMX became standardized and implemented by the browser, or if I could allow HTMX (the JS) and not other scripts [selectively].
It's called baby steps. Implement the HTML extensions you want using JS, then get them standardized. You could do it w/o the PoC first, but then it might be harder to get the mindshare and traction you need to get the W3C to go with it.
Even if the W3C rejects this, it would still be useful for many who want to write declarative scripts rather than actual JS.
Why does CSS exist anyways? Because it's a declarative language, and declarative languages are clearly better for certain tasks. HTML itself is declarative.
While I am just now discovering it so have not used it, I personally love this approach because it keeps the HTML syntax. It is like programming in two different languages when you only need one. Normally, you would add an onclick event handler to the element to call a function. Then, you scroll up to the function and back down to the anchor. Back up to the function. Back down to the anchor. This puts everything in one place with cleaner syntax.
I've looked at a few of those and I still don't understand. Also, hilariously, several of them are already broken. (Like the table one that's not updating.)
EDIT: Sorry, nevermind. The Bulk Edit example does work, I think it either does not like Safari, or something failed to load before, but it works in Chrome.
if you can, try to give the idea some time: it's a bit different than other approaches, but it's at least an interesting alternative to other front end libraries, even if it isn't right for everything
Replying to myself: I guess the main point of this library is to use HTML as the protocol payload between serve and client, instead of JSON. I can see the benefit of doing that, although I have a bone to pick with the condemnation of all data APIs because JSON is awful. Protocol buffers, for example, are trivially forward and backward compatible and mostly self-describing.
Also if you build stuff on top of hypermedia APIs then bye bye performance. It's probably fine for web pages, because you're competing with JS+JSON/REST frameworks that are written by people who have never heard the term "L2 cache", but I strongly suspect the right move is to drop the framework completely, not replace it with a new flavour-of-the-week thing.
Just write HTML5. It's fine. Add javascript for the 2-3 bits of interactivity you actually need. If you hate JSON, use protobufs. Your web page will work forever, because it'll sit on the actual API provided by the browser, and it won't make my laptop overheat when I load your site.
You can use the swap data attribute to update several fragments (imagine a saved icon) in several places declaratively.Then you can get rid of almost all your js code.
The price to pay for this is it does not work offline. For quickly prototyping and app it is very fast.
> You can use the swap data attribute to update several fragments (imagine a saved icon) in several places declaratively.
Yeah, but why? The javascript snippet to accomplish the same is absolutely trivial and avoids a dependency.
> The price to pay for this is it does not work offline. For quickly prototyping and app it is very fast.
The true price is that you've now rewritten your HTML code in a non-standard DSL and are forever dependent on a third party library, and all that to accomplish a goal that seems entirely aesthetic to me.
I disagree with this other than in a simple example. Updating something that depends on sth is far from trivial. It looks trivial.
> The true price is that you've now rewritten your HTML code in a non-standard DSL and are forever dependent on a third party library
So, like React. Prob also a build and scaffolding tool, and a linter were added in that case.
Regarding arsthetic I actually find htmx kind of ugly but it works so well I cannot ignore it. It simplifies everything a lot, but I am just discussing here.
> Just write HTML5. It's fine. Add javascript for the 2-3 bits of interactivity you actually need.
Why write any JS at all if you don't have to? Htmx extends HTML to replace the need for a lot of the JS that's out there. It gives you client/server interaction and dynamic page behaviours without a single line of code.
Sure you can do without it. You could always do it all in vanilla JS or jQuery, at the cost of debugging it yourself.
This idea used to be called microformats. The premise was that you send an HTML snippet, and all the semantic attributes plus a protocol definition will let you parse it as either data or a part of the UX. It's self-documenting in the sense that, if you do it right, the snippet has clear semantic meaning.
However, it's not backward and forward compatible as either UI or data, because that was never an explicit goal of HTML. It's also much slower to process because:
1) Network IO is CPU intensive, so sending more data is worse
2) HTML is not optimized for data interchange. Parsing a protobuf is probably at least 10x faster than parsing the same data out of an HTML microformat.
Um, 'parsing...data out of an HTML microformat' sounds like a fancy way and obscure way of saying 'the browser renders HTML, something it has been optimized to the gills for'.
> Parsing a protobuf is probably at least 10x faster
Faster than a browser rendering HTML? That would be quite a feat.
> I guess the main point of this library is to use HTML as the protocol payload between serve and client, instead of JSON
HTTP is named Hypertext Transfer Protocol after all. Exchanging schema-less JSONs is conceptually pretty lame. It's plain old RPC architecture. That's why we end up needing to write API docs to line up the frontend and backend, or otherwise inspect backend code to figure out what's being handed over.
Browsers are built to understand HTML. Whereas in the modern world we largely ignore that and write double the code we'd have to write otherwise passing arbitrary messages and it introduces a whole new set of problems making sure those codebases line up properly. Whereas HTML produced by the backend (properly) contains all the information someone could need.
This hits the nail on the head so hard that reading it feels like waking up from a bad dream.
> Browsers are built to understand HTML. Whereas in the modern world we largely ignore that and write double the code we'd have to write otherwise passing arbitrary messages and it introduces a whole new set of problems making sure those codebases line up properly.
This belongs in a manifesto. Put it on a shirt and I'll gladly wear it
yep, perfect example is the history API. People created the problem that the history API fixes by doing things they shouldn't have been doing in the first place.
This answer is exactly correct. You must really think about how this dramatically makes developing these types of applications simpler by a magnitude. You are literally killing significant complexity that causes time, effort, and bugs. And, no, this is not merely shifting the problems back to the server-side. This is how HTML should have evolved in the first place.
Things that don't require request to server - managed by alpine, things that do require - by htmx. There are situations where both tools can be used, one has to pick.
I’ve been looking for alpine and forgot what it was called, have come across it some time ago. I knew I would find it in the comments on this post as it’s kind of like htmx. I didn’t even know the same people made both!
First, I'll preface this that what I'm about to write is meant as an endorsement of HTMX.
What HTMX does should've been a W3C standard a decade ago, and I've my fingers crossed that some day I'll be able to do what I've done with jQuery and remove it.
Thank you for pushing the state of the art forward in a meaningful (and RESTful!) way.
I love the model. I've been writing a golang app with the standard library template system and it works really well.
One bit I've found slightly unintuitive is the swap and settled states. Took my a while to animate in a sidebar how I wanted. It was my fault for not groking it faster but perhaps some more examples or guides in that regard could be useful.
Hi, on the subject of hypermedia: I recently saw your talk when you showed hyperview.org as an alternative to HTML for mobile use case.
As someone who is very interested in the space, are there other hypermedia implementation (if is the right word) that you found interesting? Or do you have some pointer for those who want to explore this space?
Personally I really want some kind of hypermedia framework for terminal application, since I often need to work with hardware (or bandwidth) where the only interface is a terminal, and I never feel productive with manually writing the application code, having to reimplement a new client every time.
Also thank you for htmx, I started using for a couple of project, and it really is refreshing. Especially kudos for the various example, that really helped making it "click".
heya, i don't know of any terminal-based hypermedia, but that's an interesting concept
maybe gopher as a prototype example?
adam stepinski (creator of hyperview) is one of the heroes of hypermedia in that he didn't just develop a hypermedia format but also developed a hypermedia client, and you need both for a proper hypermedia system
so, I would say... maybe you are lookin' at the person in the mirror who is going to make that terminal app hypermedia?
How does error handling work? If I try to replace the content of some div with a reply I get using htmx, but the request fails or times out etc., what content is then put into the div? What if the reply is not valid HTML?
I've never used htmx, primarily because I like the concept of "components" so much. (They serve two needs - standardizing larger blocks of UI and encapsulating them with an alternative interface, and providing islands of rich interactivity)
Is there any material on successfully combining htmx with web components? It doesn't look to me like the original design takes this possibility into consideration...
(note: at a surface glance it doesn't look to me like components are in conflict with hypermedia - one could treat them as a side channel that "enhances" the standard set of elements)
I'm not sure if I've entirely grokked the idea of components, but can't you define them server-side? So write them as some template magic that creates the "inner HTML". Then you just need some HTMX to enable using the component in a richer way.
It's not really Web Components as specified, but iirc those are generally pretty much JS-dependent? But hypermedia's reliance on server side rendering means that you can just move this logic to the server.
Why wouldn't htmx work with web components? It just does asynchronous fetches and DOM swaps. Web components are just pieces of DOM. There should be absolutely no issue with them working together?
You have mentioned here and in other places that you use HTMX + HyperScript in production. Curious what that looks like, is it part of consulting, a side business, a day job ?
When I started using them, one of the hardest parts was to actually have it imported and built with webpack, since the site focuses on cdn and webpack example is really brief. Same goes for hyperscript
What’s the story for modals? Or multiple modals, navigating in them etc… Do you plan to take inspiration from Unpoly Layers (https://unpoly.com/up.layer) or is it out of scope for htmx?
Quick question, as it made me curious. Can I send the content that I want to swap to the server itself? Say I want to submit a form to the backend, will it only send form fields or is there a way to send the form html itself?
I'm gonna make a note on that when I have cycles to burn to experiment with htmx. From my understanding of reading that section, parameters being a container of kv pairs, I'd have to hack on the internals of htmx for it to be able to send a pure string (not form/multipart) as the body of a post/put request.
If I get around of experimenting with that, and it fits my flow, would that be something you'd accept back into the project as a contribution to the code?
I have a nifty (or so I'd like to think) slapped together HTML parser, that instead of building a DOM tree, streams the HTML nodes as a list. Which in practice makes it easier to validate a field, and insert the appropriate validation message at the right location, without switching from request -> data representation -> validation failure model -> templating language ifdefs to inline the validation classes and additional helper text.
Might sound not that convenient for basic things like login forms, but I have frontend code that builds dynamic form fields, which I'd like to not replicate via the backend templating language, if extracting data from HTML itself is a breeze in my case.
Of course I'm going to do that myself anyway, but I'd rather use an established library which also handles in browser page restoration/caching (possibly also fragments), instead of rolling my own JS lib.
Two questions. What would you recommend to build the backend in, some language that can parse xml/html well? And second question, are there any more extensive examples such as working authentication?
That’s part of the benefit of htmx and it’s hypermedia approach, you can build the backend in anything you prefer. Some like using language and frameworks that use templates. Others, like we do, used fairy basic HTML generation libraries. We love Clojure so we use the Hiccup library to generate HTML. We use the full power of clojure and functions to build reusable HTML type components and their fragments.
I stopped scrolling as soon as I noticed I have to ask myself what am I posting to this URL?
Maybe digging deeper I could find the reference docs explaining in very vague terms where the payload is coming from. But this was supposed to be simple.
This project has seemingly picked up a bunch of traction. The number of times it has appeared on the front page of this website serves as some indication, as well as the plethora of conference talks.
You seemed unwilling to put more than 2 minutes into looking at an example, or 10 seconds into checking what page you were on, yet felt that your experience warranted these dismissive comments which cumulatively proportionally surely took up just as much time.
You aren’t acting in good faith. This doesn’t add to the conversation at all.
Oh. My. God. This is amazing. I absolutely hate all the complexity of the modern front-end development. I hate it so much that I use `<meta http-equiv="refresh" content="3">` for status pages waiting for the result from the server. Just by looking at htmx, this is a breath of fresh air. Love the simplicity and how they managed to abstract all the complexity away. IMHO, this should become the HTML standard.
My only complaint with htmx is that it is _nearly impossible_ to Google search for info about it. You just get tons of noise from Google 'helpfully' deciding you really just want to search for 'html'. You need to search for "htmx" (including quotes) to find docs, articles, etc. about it.
i'm using it in production and I don't expect any major breaking changes before 1.0 (H1 2023)
i would stick with what it is designed for: light front end scripting, rather than writing a huge app in it, but within that domain I think it'll be pretty reliable
Makes me smile too. Around 2008 while I was at Yahoo! I built a standalone library called Dhaka (literally stuck a pin in a map and used the place name as the project name) that did almost exactly this. It was used on a few of the EU sites but I left before I got chance to open source it. The problem I was trying to solve was eliminating a bunch of duplicate JavaScript that was essentially sending/fetching data to/from a remote source and inserting/replacing it into the current page.
Or in a similar vein I remember Github making a mediumly big deal years and years ago about having no-reload moving between pages of the directory tree within a repo with... I think their library was called pjax? And it fetched some partial HTML from the server and updated a container, plus having some pushState/popState to make it work with browser history.
The most interesting part of it to me is that the mainstream has gotten so far out over to react and data payloads that the paradigm of "send some HTML and stick it in a container" is seen as revolutionary. Not to say that a well-designed library for doing this is a bad idea, just that... it's interesting to see how it's talked about.
I made some sites with Pjax. It was crazy fast and didn’t have the issues that React had. Back button works 100% of the time, users always had a working link to share and so on.
When I saw this I immediately had to search the comments for Pjax because the idea was quite similar.
I think the main problem was that heavy backends started to go out of style, especially C# ones that had good Pjax support.
Happy to see HTMx mentioned every month or two on here lately. A+, would recommend to anyone especially newbies. Been doing web dev since the Perl / pre-PHP3 / pre-jQuery/Scriptaculous days, and I feel reincarnated into a nicely crafted framework from that time.
I've been picking up Python for the past 6 months and adding as little as possible and slowly as possible. About 2 months ago I started building a Twitter client with HTMx + Flask and it's been nice. It now supports multilogins for Twitter and Mastodon, as well as Twitter Archive and RSS/Atom backends. Very similar to programming with PHP back in the day. Minimal JS, just a couple functions to integrate with my little Notes app that's not running HTMx (yet). Not trying to boast, just showing how far one can take it.
Using the server as an engine of state with the Facade pattern is something I've already become happy to do, having successfully used it for a pretty delicate use case involving multiple iOS App Store versions and a backend migration without impacting old App versions. I'm a little cautious about offline apps (SPA-domain), but have done a Service Worker demo and have some ideas to mess around with in mind. It's the one possible downside to not using JS (Node) on the backend that I can see: no shared code that can run on the backend and client/edge alike (but a language subset transpiler fills in the gap, eg. for validation/pure/non-mutant logic).
Documentation is pretty clear as well, I've been able to go a long way just reading it over and over and trying out features as I think of them.
HTMX is awesome. In a world of front end frameworks I don't understand and frankly don't care to understand, it lets me write nice, interactive websites in a very simple way.
I've normally extremely skeptical of anything like this, but HTMX just feels right when using it.
Is anyone here working with Java and HTMX ? we have faced a lot of resistance in doing this. Basically because java already has versions of server side rendered frameworks - specifically JSP & Thymeleaf.
So while, the value proposition of HTMX for the larger nodejs world (or anyone using React) is "back to Server Side Rendering". I'm kind of struggling to build a value prop on the JSP/Thymeleaf side which is already popular.
Not yet. Eventually, but right now it's just a hobby trying to become a business, and until I get a big enough database to provide a moat, I'm a bit nervous about giving it away for free.
I'm not sure if that's the best course of action, but I'm just a guy who's a bit embarrassed to really like to programming in python and playing golf.
I don't use it for that since it's a wiki. I just use a typical sign in page and flask session (which i think is an HMAC hash cookie), but users can obviously edit the wiki without signing in, though with some serious restrictions to discourage vandalism.
I still remember a time when recursivedoubts posted about intercooler.js which is the predecessor to htmx, and almost every comment was dismissive and a varition of “what’s the point of this?”.
It seems now the majority of commenters are positive about htmx now and I feel happy for recursivedoubts.
Most web applications today would benefit from using htmx more than JavaScript-heavy frameworks with the exception of applications like Figma and the like of it.
I'd like to make a small plug for a really awesome Golang web development starter kit I found recently called pagoda (https://github.com/mikestefanello/pagoda). It wires up HTMX, together with Alpine.js and Bulma CSS, onto a really fantastic collection of Go libraries on the back end.
htmx like all great ideas seems obvious in retrospect. Why can't other html elements do what links and forms do? Htmx simplifying it all back down to html - I had that "of course!" reaction.
I work on a collection of React applications at work and it is OK but at night I am building a workflow engine that trains a text classification model and automates its activities based on that model.
It is almost the kind of web application that I built in 2001 but I find it a lot easier to write today than I did back then thanks to my own maturity and numerous refinements to the web platform. The backend is written in Python and uses aiohttp without any "framework" other than some very basic stuff I write myself.
I worked for a company that had built something similar (that one was named "Themis", this one is named "Nemesis") that had parts written in Python, Scala and Typescript and we faced the problem of having to update three codebases whenever we made some change, having to deal with three kinds of "dependency hell", etc. It is all the more acute for an R&D project where adding a new task or model should be a day's work.
With very little Javascript I am getting performance close to a desktop application when my server is on localhost, it helps that I am paging out small screenfuls of data. I have to admit that a library like Htmx could be a big help for this kind of application but I've yet to really wrap my head around fitting it into my application.
I did something similar with Bun recently. I built a little finance / budgeting app (and some bookmarklets) to track, categorize, and visualize my spending. There’s almost no client-side JS. But when I need to sprinkle it in, I just write a function and it’s serialized and sent to the browser automatically by my JSX template layer (built into Bun). It’s quite nice.
I want to like - I feel like the frameworks are all too much ceremony now. You need to buy into a bunch of different build tools, a cli or two, and are left wondering "where is my app again?" I've tried htmx, though, and like the simplicity, but am not 100% sold. In the olden days, ASP.NET Web forms Ajax had "Update Panels", which were similar to this. You'd wrap a section of markup in an "Update Panel" and that made it refresh just that bit of the page while keeping the rest. The problem is your "api" then ended up being a bunch of pages that output html, and passing state was a huge problem. This seems better, but still similar concept.
At the end of the day, I want my backend API to be restful json(or grpc, graphql) any client can consume. I want the client to be written with as few dependencies as possible. Maybe I'm misunderstanding though. Put another way: suppose I have an existing backend REST API where input/output is json. Can I use htmx without any changes to the api or server-side code to translate json to markup?
Generally, I would recommend splitting your data and hypermedia APIs up, so you can take advantage of the features of hypermedia (the uniform interface) and still provide a good data API to clients that want it.
Also, this is pedantic, but a graphql JSON API is almost certainly not REST-ful, in the original sense of that term:
Question about this part of the hypermedia vs data APIs essay: "This new end point is driven entirely by hypermedia needs, not data model needs. This end point can go away if the hypermedia needs of the application change"
Presumably these hypermedia endpoints are all equally accessible - couldn't the removal of one break another application if the latter app decided to depend on a particular hypermedia snippet from the first?
If there are multiple teams in an org that own HTMX endpoints, aren't the set of endpoints effectively a sort of interface boundary? Or is there a good way of declaring certain endpoints "private" and ensuring they're only fetched from particular applications? (Maybe separate domains for every app?)
in the sense I'm using, an application is a single functional app: you wouldn't have two applications using a shared URL because that would break the uniform interface
you might have two separate apps that maintain their own hypermedia APIs and that, on the server side, then share a data API between each other
the idea is to take advantage of the uniform interface of a hypermedia APIs:
Thanks for the reply. I will have to give those essays some thought and revisit. I think some of it may boil down to the type of app, customer, etc. At first blush I’m hesitant to want two apis plus a client at least for my typical (admitedly smaller forms-on-data) type projects. But I do plan to revisit and see. The client template extension may be the gateway drug for me here.
I certainly didn’t mean to imply REST = GraphQL = grpc. “Data api” vs “hypermedia api” is a distinction that makes sense to me.
I'm aware that I'm abusing the tool, but I wrote a htmx extension that overrides the mimetype and JSON encodes all the parameters. The JSON is decoded into a data bag on the back end. Basically I can do "fuck it over HTTP"[0] with needing close to zero JS. HTMX has been a god-send to me.
I did something similar, for a dashboard type of web app that involves a lot of graphs. JS graph APIs pretty much all expect data as JSON-formatted JS variables, not HTML.
So I use HTMX to make the server requests, using triggers defined in HTMX, replacing a lot of JS code. It's really only with the JSON-based responses that I'm going rogue. HTMX is so elegant, I feel dirty going against the grain.
I showed this to a few frontend developer friends and they actually got a bit defensive and dismissive. What are they going to do if they can't build SPA monstrosities?
I know, it's a ridiculous thought, right? There's always going to be challenging work to do, but some people are entrenched in VueJS/React/Angular, and relish spending 10x the time building CRUD apps.
This is another project that teaches you to write non-standard, invalid code, with the hopes that a tool will come along and transform it into valid, standard code later.
And there's no need, because there are multiple ways in HTML they could already express this without violating HTML. Here are 2 ways that work, and then the way they've done it which is in violation:
Possible method 1: Data attributes. Any time you as an author want to add additional data to an element, you are free to invent any custom attribute names you want, so long as they begin with "data-".
Possible method 2: Custom elements. Any time you as an author want to add a custom element to HTML, you are free to invent any tag name so long as it follows a simple naming criteria (essentially [a-z]+-[a-z]+) and if you invent any custom element, you are allowed to define whatever attributes on it you like.
Invalid method chosen: To pollute standard elements with invalid attribute names in violation of the HTML standard.
> Possible method 1: Data attributes. Any time you as an author want to add additional data to an element, you are free to invent any custom attribute names you want, so long as they begin with "data-".
From the linked docs:
> It's worth mentioning that, if you prefer, you can use the data- prefix when using htmx:
Given the documentation actually list the data-* syntax as an alternative (and pretty much near the top), I’m assuming they are aware of the problem, but still prefer the non-standard-compliant attributes.
My problem with JS is that every framework we tried sucks in different ways. The worst is to handle the kind of silly crap that JS does (wat). The other big part is the every bricking API of pretty much everything. We are lucky if there is no warning about deprecation for a couple of day after updating a library. Minor version changes regularly break the build. The best is when yarn dev works and after building the app and deploying it to prod it breaks.
After dealing with these issues for years I am really happy to return HTML from a backend API that uses a language where [1, 2, 12, 3].sort() return what I expect from a sorting function sorting integers.
That is all, and that is what htmx gives us. I am not sure if we can replace our UIs that are written in Vue for now but at least it I have a good time porting some of the web things to htmx + Rust from Vue + Python.
> Now any HTTP verb, not just GET and POST, can be used
requires care. I'm assuming HTMX is just a JS library that attaches all these behaviors to HTML. That's fine, as that won't change anything as far as cross-site scripting goes. It's just that if this were coded in the browser, and the responses to these requests made available to the page, then bad things would happen.
Also regarding this:
> Note that when you are using htmx, on the server side you typically respond with HTML, not JSON. This keeps you firmly within the original web programming model, using Hypertext As The Engine Of Application State without even needing to really understand that concept.
it's much easier to write server-side APIs that produce JSON and static HTML + JS that consumes it than it is to generate HTML (and then also JSON for non-browser apps).
I'm using htmx in production since one year. From game (scrabble game with board refresh, chat and so on -with sse extension-) and cms to professional crud apps. With Go + stdlib template. Now looking at PWA, it seems to fit very well.
What i like with htmx is that it's very easy to upgrade step by step a legacy SSR app. And the opposite. I mean it will be easy to switch to an other ajax lib or if w3c add similar functionalities in 10 years. To use htmx is mostly to replace whole pages with fragments, that's interesting even when we don't use htmx, sort of server side web components.
In other world, just try !
I'm fighting myself to don't give back examples to the community but i'm so exited to upgrade my very old legacy apps !
We need improved DOM access for web assembly, followed by a new icon in the URL bar that indicates you're on a "legacy" site if it's using javascript (my vote is for a cute snail emoji)
> The fastest way to get going with htmx is to load it via a CDN
HTMLX is great and all, but loading it from a CDN is insecure and wrought with problems. Namely, the JS file in question could be hijacked and replaced with a malicious version that can steal data. It's unlikely, but still a plausible scenario. Also: the resource could just 404 and not be available due to work-in-progress scenarios on the CDN side.
I would much rather host it on my own domain that I control.
I like HTMX. But I got stuck with the fact that there is no url routing or history. After using things like React and Angluar, I am used to having well defined urls that can get me where I want. Perhaps there is some recommended way to add some other library ontop of htmx, but maybe I'm the only one looking for this?
Interesting, thanks. I stand corrected on the history part. But routing is still left to the user (its even explicitly mentioned in the doc you linked to.
For example if a user clicks a link in their email to /movies/2001, it does not know to show the movies frame with the 2001 content. We have to implement some kind of url parsing to determine what divs need updating and then update those on first page load.
If I'm understanding this correctly, this is a front-end only framework... is that right?
If so, what do people pair it with on the backend?
I can see how this approach allows for much more dynamic pages with just static content, but what about when there is a database involved?
Also, what do people use for "published" static sites (I mean where the site is static once published, but the publishing step can pull content from dynamic source. Not sure the common terminology for that, but in this case, there tends to still be app logic to be developed, but it's just executed at publishing time rather than run time.) I'd imagine a publishing framework that is htmx-aware/friendly would be powerful.
I have yet to use it in anything, but conceptually I'm a fan of this kind of freedom of choice. It's always a bummer to see something that looks cool for frontend use and find that it's tied explicitly to a particular back end.
Because HTMX is totally unopinionated regarding the backend, and also expects pure HTML responses, you have a ton of freedom.
In most cases, this means your choice of backend framework in virtually any language, anything from Django to RoR to Spring to http4k to Laravel, plus some templating framework/language such as Handlebars, Jinja, Thymeleaf, Moustache, JTE, etc.
I've been building a golang app that serves html via the go standard library template system. It works really well. You can define and execute templates inline so you can define entire pages in html and then wrap a "block" around any reusable bit that you want to serve up dynamically.
htmx is pretty agnostic with regard to the backend side of things. You can use anything you want, really. There are htmx extensions to Django and I am working on a similar one for Express. Basically, a very simple middleware to deal with custom request and response headers.
I'm curious about htmx, but all of the HTML mini-syntax very similar in aesthetic to Angular 1.0, which was pretty quickly supplanted by React. What excites people about htmx? Do people like the mini-syntax but dislike the ceremony of state management?
I think the general concept is spot on. Some of these features are sorely overdue for HTML.
However, looking at some of the more complex features it starts to feel like they are not all suited to HTML, but seem more fitting to CSS. Perhaps, even, we need something akin to CSS but dedicated to coordinating events and requests? I’m not sure. I get the feeling Htmx is a big step in right direction, but I don’t think we’re quite “there” yet.
I also think JSON has its place (b/c it’s pure data), and wouldn’t be too quick to completely chuck it out in favor of an all HTML replacement (data with markup).
If you just want to use plain HTML with JavaScript, take a peek at Joystick [1].
100% plain HTML, CSS, and JavaScript based components (zero attribute hacks or compiler tricks). No external libraries for basic functionality (state, data fetching, url handling—all included or relies on native browser functionality). All a part of one full-stack framework that works out of the box.
I had a quick look at joystick and wonder if you have even read anything related to htmx. Nothing against joystick but it seems more an alternative for frameworks like react and svelte. Those are also npm and jsx based. Htmx is nog ;)
Yes, I have. It was one of the things I looked at as part of my initial research before deciding to work on Joystick. What I don't like about is that it's a non-standards based pattern for implementing interactivity in HTML (the same reason I didn't like React, Vue, Svelte, etc).
All of these frameworks try to wedge stuff in between the core languages of the web (HTML, CSS, and JavaScript) for the sake of speed/being clever, but ultimately lead developers into a proprietary skills trap. It's all 100% unnecessary and will (arguably, has) lead to massive confusion and messes in the industry.
By contrast, Joystick uses plain HTML, plain JavaScript DOM events, and plain CSS to build your UI. It just adds some very thin API abstractions over those features to help you move faster.
Honestly, Joystick doesn't seem at all like React, Vue, or Svelte. You have a lot there in terms of email templates, database connections, and other "full stack" items that far exceed the scope of the others.
React is certainly a LOT more cognitive overhead than plain old HTML/CSS/JS. Vue, yes, to a lesser extent than React. But honestly, Svelte is closer to "just plain CSS and HTML" as I've even seen in a framework that also allows two-way data binding, which let's face it is a RPITA in vanilla JS. Automatic scoping of CSS to a component is also nice when you aren't trying to set a global style.
This by the way is coming from a guy who started writing for the web in 1996, back when document.write() was de rigueur. That said, I honestly do miss the old days of figuring out how to make something on a web page by simply hitting "View Source" and picking out the relevant tags.
> Honestly, Joystick doesn't seem at all like React, Vue, or Svelte.
The component framework (@joystick.js/ui) portion is best compared to those.
> Svelte is closer to "just plain CSS and HTML" as I've even seen in a framework that also allows two-way data binding
Joystick does this too but with zero need for a special compiler/extra syntax.
> Automatic scoping of CSS to a component is also nice when you aren't trying to set a global style.
Joystick also does this without any special compiler. Whatever CSS you define on a component is explicitly scoped to the HTML rendered by that component.
---
The compiler and data attribute stuff are the hang up for me. It's adding stuff in that's non-standard. Admittedly, it's neat/clever, but that line of thought has lead (JavaScript-driven) web development down a rabbit hole. I started about 10 years after you (2006) and want to get back to that level of simplicity—sans IE6 rendering bugs—without compromising productivity. I think Joystick hits the sweet spot on that.
This pattern is very pleasant and I sure hope browsers would embed as HTML standard a simple version of this (with simple hx-get/post, hx-target and hx-event to start)
Funny - top stories right now are Sveltekit 1.0 and htmx. At their heart, each is fundamentally going in a different direction.
I wonder how many people are upvoting both.
They serve different purposes though. SvelteKit is a great full stack framework using Svelte for the frontend, which is great for SPAs, PWAs, and any other kind of WAs you might want. HTMX serves essentially as an extension to HTML itself, allowing you to make web PAGES which are interactive. Not talking about Alpine or Hyperscript though since those two start mudding the water a bit.
I don't know any javascript, but is it really that bad of a language that you need new libraries every day and workarounds so that you don't have to write it?
The language itself isn't great, but the tooling it (appears to) necessitate and the fact that the browser isn't a great environment for what many people want to do combine to turn many people off.
a lot of people in the last 15 or so years felt strongly that writing javascript was not "real programming", and this facilitated the birth of a thousand solutions to avoid writing it
I like gymzaal and hyperscript - they solve few cases but those cover something like 99% of what a average app needs.
My biggest pain point lies with the docs, there are not many of them and it takes time to figure out what’s happening
For example, there was no simple way to understand that both libraries are loaded correctly, also it wasn’t immediately obvious where to use htmx and where to start using hyperscript
I was inspired by Htmx to simply fix HTML, and I believe HTMX is a great way to go if you are using a traditional backend.
However, I believe in a better way if you have a better backend. This is what I'm working on as I build a "vertically integrated online board game studio" where I own the infrastructure, the clients, the frameworks, and now gaming runtimes.
Has anyone cleanly bolted htmx into Flask or another similar Python framework?
I typically use mako for templates and htmx partials or components or whatever you want to call them would seem to cleanly map to mako includes - but I'm not sure how I might connect the render context which is typically collected for the top-level page in a tidy way.
Thanks, a couple of these look like rendering sub-templates, one actually just loads sub-templates over ajax even on first page render...
I'm thinking to have a function in the view that collects the context and renders a sub-template - and then making these functions callable from within a top-level template or from an ajax request... Seems simple enough.
It's take a special type of arrogance to just deny the reason why front end development has been moving heavily toward code (javascript) instead of mark up.
This same group of people recently has made a lot of noise about freaking form methods and that sort of thing, sorry we knew about them 20 years ago, didn't scale.
I have been trying to learn some modern-ish web development and had good luck with HTMX for a little toy web app that allows you to post a document and a set of search terms and then displays the search results on the same page, avoiding a full refresh.
For anyone curious, I used Quarkus & Qute templates for the backend and Bulma for CSS.
Stimulus is a way to attach behaviours to DOM elements. It has no remote concept and no rendering concept. It's freaking awesome, IMO. But it has nothing to do with the problems HTMX wants to solve.
Modern frontend is easy to get burn out not by the complexities of tooling. It's more about upgrade and backward compatibility. Same story as backend, but backend is likely less broken on that aspect.
slightly off topic but I've been having the best time getting back into rails version 7. (I left the rails world back in 2014) This tutorial https://www.hotrails.dev/turbo-rails/css-ruby-on-rails makes clean views with auto magical css that just works. It is amazing.
It would be nice if your pages are more tl;dr friendly than everything looking like part of a text book which exceeds the attention span to understand the page who's just getting into it.
I'd say it's more complementary, from my experience. Alpine serves the purpose of local state and rendering logic for user interaction in a manner similar to a SPA, whereas htmx services integrating w/ your backend service and handling DOM patching for updates/data oriented interactive bits.
htmx keeps getting posted here and choosing it comes down to "do you trust that your user's internet is stable" IMO. For a lot of interactive web apps, the answer is no, and htmx is not a good fit.
I don't see why it couldn't be used in a PWA with a service worker providing offline HTML responses to hx directive elements though. You can see an example here that uses a WASM-based service worker (but you don't have to do that, it could just be plain old JS generating HTML): https://github.com/richardanaya/wasm-service
I think this is a great idea and could eventually enable htmx projects to transition from server-side-only to being a PWA with very little code changes (given the right backend).
Unfortunately this particular implementation exhibits some blocking issues which I was not able to solve yet:
1. The Service Worker is eventually unloaded from memory, which means all data is lost because it currently stores everything in memory. This isn't a defect as much as it is lacking a persistence feature; this is a MVP (emphasis on minimal) after all. The most promising solution in my opinion would be to use the OPFS/File System Access API with SQLite, which is yet to be shipped in all browsers.
2. The bigger issue is that once the SW is unloaded it doesn't come back. The SW getting reaped after being idle is fine, that's part of the expected behavior. But there are no events or any other indication that it was disconnected, at some point it just stops intercepting requests. I don't know why. If anyone can chip in here to say why it does this and how I can detect or somehow restart SW fetch interception on demand I would be glad to hear it.
SPAs make tons backend calls to get data. This isn't particularly different. To me the main difference is it is hard to build an offline app out of htmx as compared to a SPA but so few webapps are offline anyway...
Django, DRF, Postgres, tailwind and HTMX.
I am so tired of all the front end frameworks and all the complexity that gets added. At some point I think you need it and you get returns from it but hearing more people in the industry recognize and talk about how JS everything isn't always the answer gives me hope.
I like what HTMX has to offer and I am excited to see it continue to get air time.