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

Please Just Try Htmx

Please Just Try Htmx

219 comments

·December 18, 2025

recursivedoubts

Hey, I created htmx and while I appreciate the publicity, I’m not a huge fan of these types of hyperbolic articles. There are lots of different ways to build web apps with their own strengths and weaknesses. I try to assess htmx’s strengths and weaknesses here:

https://htmx.org/essays/when-to-use-hypermedia/

Also, please try unpoly:

https://unpoly.com/

It’s another excellent hypermedia oriented library

Edit: the article is actually not nearly as unreasonable as I thought based on the just-f*king-use template. Still prefer a chill vibe for htmx though.

PaulHoule

If you are comfortable building web apps like the early adopters did in 1999 that later got mainstreamed with Ruby-on-Rails and related frameworks, HTMX adds a wonderful bit of extra interactivity with great ease.

Want to make a dropdown that updates a enumerated field on a record? Easy.

Want to make a modal dialog when users create a new content item? Easy.

Want a search box with autocomplete? Easy.

As I see it the basic problem of RIA front ends is that a piece of data changed and you have to update the front end accordingly. The complexity of this problem ranges from:

(1) One piece of information is updated on the page (Easy)

(2) Multiple pieces of information are updated but it's a static situation where the back end knows what has to be updated (Easy, HTMX can update more than one element at a time)

(3) Multiple pieces of information but it's dynamic (think of a productivity or decision support application which has lots of panes which may or may not be visible, property sheets, etc -- hard)

You do need some adaptations on the back end to really enjoy HTMX, particularly you have to have some answer to the problem that a partial might be drawn as part of a full page or drawn individually [1] and while you're there you might as well have something that makes it easy to update N partials together.

[1] ... I guess you could have HTMX suck them all down when the page loads but I'd be worried about speed and people seeing incomplete states

librasteve

azangru

> No Jobs

> Another practical reason not to use htmx is that there are, rounding off, zero htmx jobs.

> I just did a search for htmx jobs on indeed and found a grand total of two: one at Microsoft and one at Oak Ridge National Laboratory.

> A search for “react”, on the other hand, gives 13,758 jobs.

> Seriously, developer, which of these two technologies do you want to hitch your career to?

I do not advocated for htmx; but this take is so bad!

Resume-driven development should not be a thing. If you are a professional developer, building a product for a user, your primary concern should not be the job market for when you quit the company you are working for, but rather making the best product possible for the user within the context of the current company. And if the product is such that it does not call for react, or some other javascript-rich client, then you shouldn't use it however many react jobs there may be on Indeed.

barrkel

The author of the article is the creator of htmx. There is some tongue in cheek here.

lynndotpy

The evidence is so damning that htmx.org even opted to host it. That's not all- the author of the document is the one who developed HTMX!

(In all seriousness, this entire article is facetious and is highlighting the strengths of HTMX. They are not sincerely advocating for 'resume driven development'.)

null

[deleted]

almosthere

Everything in that resonated with me.

viiralvx

Damn, Unpoly looks great! Never tried HTMX but have been a fan of it, it solves a UX problem that frameworks like Django and Rails suffer from, without needing to bring in something heavy like React.

I'm currently working on a side project in Rails using Stimulus but sometimes I wonder if Stimulus is overkill with all of the controllers and stuff as well. Do you have an opinion on when you should reach for something like Inertia or Stimulus over htmx?

dpifke

https://unpoly.com touts "progressive enhancement."

Third link on the page ("read the long story") points to https://triskweline.de/unpoly-rugb/, which renders as a blank page with NoScript enabled.

Sigh.

nrclark

fwiw I'm the CEO of htmx, and I am a huge fan of these types of hyperbolic articles.

jadbox

How does Unpoly and htmx differ?

recursivedoubts

unpoly is a more complete framework with concepts like layers and best in class progressive enhancement

htmx is lower level and focuses on generalizing the idea of hypermedia controls

https://dl.acm.org/doi/abs/10.1145/3648188.3675127

ZeroConcerns

LLMs know nothing about Unpoly, and quite a bit about htmx. This requires you to actually learn Unpoly, because, well, even pointing your LLM-of-choice at the Unpoly docs (which are quite okay!) makes it regress-to-the-ugly-Javascript-workarounds-mean pretty much on try #1.

I'm not yet sure whether this is a good thing or not -- I'll let you know once my latest iteration of my web framework is finally working as I envisioned, he-said sort-of-jokingly, which should be Soon Now.

But yeah, either alternative still beats React by a country mile, since everything related to that descends into madness right away.

recursivedoubts

I don’t think there is anything in unpoly that a good llm couldn’t figure out with a look over the docs pretty quickly. It’s pretty simple and has some great functionality, especially if you are shooting for progressive enhancement.

dec0dedab0de

I haven't really tried htmx yet, but I used to love intercooler, and your essays are always a fun read. When I saw the title I thought it was some kind of joke from you, because it's like the opposite of your normal style.

naasking

I didn't find it too hyperbolic, I think they were very clear on where htmx can help, eg. the section "you're not building Google docs".

recursivedoubts

Agree updated my comment

g947o

I am tired of people using the smallest "Hello World" example to demonstrate how something is better than React -- "See, you don't need all these things to get a website up and running!"

Of course it will work. I can vibe code the most terrible web framework you have seen within 20 minutes and claim it is better than React, but what does it prove?

> You write zero JavaScript > The whole library is ~14kb gzipped

Oh sure, if there is nothing else in your UI, and if your Python/Go/whatever backend server has 0 dependency, which almost never happens.

mikepurvis

To put a bit more colour on this, I think the fear of most devs with an ultra-simple framework like this is that eventually you hit a wall where you need it to do something it doesn't natively do, and because the only thing you know is these magical declarative hx-whatever attributes, there's no way forward.

I appreciate the basic demos, but I think what would really sell me is showing the extensibility story. Show me what it looks like when I need it to do something a bit beyond what it has in the box. Where do I add the JavaScript for that? Is it raw, inline, or are we back to packages and bundling and a build step? Am I building application JS, or some kind of extension or plugin to htmx itself? How chained am I going to be to its specific paradigms and opinions?

The page says htmx isn't for writing a true SPA like Google Docs, but where's the line? Show me an app that has pushed up against the limits of this system, and what happens in that scenario.

gregmac

> To put a bit more colour on this, I think the fear of most devs with an ultra-simple framework like this is that eventually you hit a wall where you need it to do something it doesn't natively do, and because the only thing you know is these magical declarative hx-whatever attributes, there's no way forward.

I'm not sure "fear" is exactly the right word here, but it's something I consciously evaluate for when looking at any new framework or library. Anything that has a lot of "magic" or "by-convention" type config is subject to this.

You start with the "hello world" example, and then you hit that wall. The test of an awesome framework vs a fundamentally limited (or even broken) one is: can you build on what you have with extensions, or do you have to rewrite everything you did? There's a lot of these where as soon as you want to do something slightly custom, you can't use _any_ of the magic and have to redo everything in a different way.

This isn't just libraries either. Another almost worse example is AWS Elastic Beanstalk. Simple way to get an app up and going, and it handles a lot of the boilerplate stuff for you. The problem is as soon as you want to extend it slightly, like have another custom load balancer route, you actually have to completely abandon the entire thing and do _everything_ yourself.

This is a really hard thing to get right, but in my view is one of the things that contributes to a framework's longevity. If you hit that wall and can't get past it, the next project you do will be in something else. Once enough people start posting about their experiences hitting the wall, other people won't even pick it up and the framework dwindles to a niche audience or dies completely.

lunar_mycroft

(Disclaimer: I haven't actually run into a case where I had to move from HTMX to a SPA framework, even partially, so this is largely an educated guess)

I think this scenario would either be very apparent early on in the project, or wouldn't actually be that challenging. There are a couple ways you could run into the limits of HTMX:

1. You require purely client side interactivity. The right (IMO) way to use HTMX is as a replacement for sending JSON over the wire and rendering it into HTML on the client, so if your app has features that _wouldn't_ be done that way, you should reach for something else. Fortunately there's lots of solutions to this problem. You can use built in browser features to achieve a lot of the basics now (e.g. the <details> tag means you don't really need custom scripts if you just want an accordion), write simple vanila scripts, or adopt light weight libraries like alpinejs or the creator of HTMX's (only slightly deranged) hyperscript.

2. Maybe your purely client side interactivity needs are complex enough that you do need a SPA framework. At that point you can adopt the islands architecture and create interactive components in your fraemwork of choice, but continue to use hypermedia to communicate with the backend.

3. If you can't easily separate client side state (handled with javascript, potentially with the aid of frameworks) from server state (handled on the server and sent to the client via hypermedia), you can again adopt the islands architecture and have your islands manage their own network requests to the backend.

4. If the above applies to all of your app, then hypermedia/HTMX is a bad fit. But this should generally be pretty obvious early on, because it's about the basic, fundamental nature of the app. You probably know you're building google docs when you start build google docs, not mid-way through.

adamzwasserman

multicards is almost purely client side interactivity. I STILL use htmx for a number of reasons:

- No JSON serialization: HTMX sends form data natively no JSON.stringify() needed - Less JavaScript: Declarative hx-* attributes replace imperative fetch code. in my world declarative always wins. - Automatic headers: HTMX handles X-User-Id and other headers configured globally - Built-in error handling: hx-on::error instead of .catch() chains - Swapping flexibility: Can show success/error feedback via hx-swap without custom JS - Request indicators: Free loading states with hx-indicator - Debugging: HTMX events visible in browser devtools; fetch requires console.log

and most all: performance. multicardz goes like stink. 100/100 lighthouse scores, First Contentful Paint 0.4 s, Largest Contentful Paint 0.5 s, Total Blocking Time 0 ms, Cumulative Layout Shift 0, Speed Index, 0.5 s

still prerelease, but cautiously hope to go general availability by and of year.

chrisweekly

This is where I think Astro shines, with its "islands of interactivity" approach. Keep things as simple as reasonably possible, and provide an idiomatic, first-class mechanism for supporting more complexity where appropriate.

alfonsodev

I overlooked Astro for a long time, I didn't really get it, and my journey back to it went something like this:

- 1 Getting burned out by Nextjs slowness in a complex production project that shouldn't be that complex or slow on the dev side, (this was 2022 approx)

- 2 Taking a break from React

- 3 Moving back to classic server side rendering with python and Go and dealing now with template engines. Hyped with HTMX and loving it, but my conclusion after so many years of react was that template partials don't feel right to me and templates engines are somewhat not maintained and evolved as used to be. I found my self not feeling naturally inclined to reach for the htmx way and just let the coding agent do it the way they wanted AND stating to notice again the burn out.

- 4 Looking with some envy to co-workers using shadcn how fast they are getting things done and how good they look.

- 5 Wondering would be a way to use JSX with HTMX server side, I miss components, I don't want partial templates.

And then I found Astro, ahhh now I get it, Astro prioritizes generation over run time, and that unlocks a lot of gradual complexity where you can choose how to mix things ( islands ) you get something way more interesting than a template engine, and it uses JSX so you can benefit from React ecosystem.

This where I am now, but yet I have to complete a side project with it to know if I fully get it and love it.

So far seems to me is the answer I was looking for.

CooCooCaCha

What I don’t get is why I’d use it if I can’t write a reasonable complex SPA with it.

React is easy for small websites so why would I use a separate framework when I can use one framework for everything?

mixmastamyk

I recently tried a hello-world in react. It made ten network requests on page load and probably had a sizable first download. That’s why web pages are so slow today.

krzyk

> What I don’t get is why I’d use it if I can’t write a reasonable complex SPA with it.

Because most webpages don't need to be SPAs. I miss the days of jquery and html+css, where everything was snappy, and wasn't an SPA.

yoyohello13

For what it's worth. Our intranet apps run on a combination of Python + HTMX. We haven't run in to anything we couldn't do yet. The paradigm of swapping parts of the DOM in and out is very easy to work with.

null

[deleted]

adamzwasserman

DecisionMe is one the apps I created using htmx. I am not the owner of the company, so I cannot comp you, but I can promise in good faith: this is not a toy app.

foldr

In fairness, the article has a section titled “The Numbers” which links to this: https://htmx.org/essays/a-real-world-react-to-htmx-port/

g947o

Different teams/projects have different needs and require different solutions. While it's good it worked in their favor, I am quite confident that someone else can tell a completely different story. In fact, there are some comments in this very HN discussion that detail their negative experience with htmx. I would not use one or the other to "convince" anybody to go with either solution like what this article attempts to do.

komali2

Right, it's also bothered me that the Vue docs spend so much time showing how it's a "progressive" framework. "Just use it for one component!" And show examples of how it can be lazy loaded in for your special complex spot that needs vue.

Like c'mon, if I'm using Vue, I'm using Vue. Same for React. Strap me into the native state management solution for your framework, your router, your preconfigured bundler. I'm not here to mess about or I'd have just stuck with vanilla.

jtbaker

Not having to deal with npm and a build step can remove a huge barrier to adoption for a large number of potential adopters, or people that just want some lightweight interactivity in an app.

mos_basik

Yep, can confirm. I first used Vue in 2016 to write some simple calculators for my group's use in Eve Online. Without its "progressive" affordances, I don't think I would have gotten anything off the ground. I had no idea how to set up a build pipeline at that point, and I think Vue was new enough that there weren't many vue-specific tutorials so I'd have been learning from React tutorials and trying to figure out what to change with zero JS background.

Austizzle

That's what got me into Vue and I still use build less Vue all the time for tiny little sites that aren't worth setting up a whole CI process for. It's really lovely that it's an option.

Just like how easy jQuery was to get started with back in the day, but a whole framework

perardi

I did.

My startup did.

And now we’re going to rip it all out and move to a React front-end.

HTMX makes response handling much more complex. Every endpoint returns 3–5 different HTML fragments. Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.

And HTMX is still a fairly obscure library. The documentation and examples are lacking, there isn’t a real set of established best practices at scale, and not for nothing, LLMs aren’t great at it.

React is mature, used at scale, provides separation of concerns, and is great for agentic AI coding. HTMX has its place for simple projects, but for anything non-trivial, it’s a no for me.

adamzwasserman

I was able to find architectural patters that work smooth as glass.

Here is what my htmx apps have: - Single-purpose endpoints: Each endpoint returns ONE thing (a card list, a tag cloud, a form fragment) - Optimistic UI: Preferences like font/theme update the DOM immediately; the save is fire-and-forget with no response needed - Simple error handling: Most endpoints either succeed (return HTML) or fail (HTTP error code) - No fragment orchestration: Not returning 3-5 fragments; using hx-swap-oob sparingly

Here is how I update fonts on screen in user prefs: User selects font → JS updates body class immediately → htmx.ajax() saves in background → done

vs. the anti-pattern you're describing:

User submits form → backend validates → returns success fragment OR error fragment OR partial update OR redirect signal → frontend must handle all cases

No language or programming paradigm is perfect. All programming is an exercise in tradeoffs. The mark of a good CTO or architect is that ability to draw out the best of the technology selection and minimize the tradeoffs.

krzyk

> Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.

Well, frontend and backend always need to agree on every scenario, that's why I prefer to do validation on backedn and frontend to just display it and not do any validation.

mixmastamyk

I found the book (hyper media systems) to be better at explaining full integration than the library site, which gives nuts and bolts and big picture, but not much intermediate info.

MrPowerGamerBR

> Every endpoint returns 3–5 different HTML fragments. Frontend and backend must agree on every scenario — success, validation errors, system errors, partial updates, full reloads.

And why would that differ from React?

When I was building a website with React, I needed to model a "apply coupon" endpoint with different states (coupon applied, coupon does not exist, coupon exists but has reached its max usage limit) and it was so annoying because you needed to

1. The backend route that returns JSON with a different model depending on the coupon state

2. The JSON models for each response type

3. And then on the frontend you need to load the data, parse the JSON, figure out which "response state" it is (http status code? having a "type" field on the JSON?) convert the JSON to HTML and then display it to the user

In my experience it added a lot of extra "mental overhead". It is something that should be extremely simple that ends up being unnecessarily complex, especially when you need to do that for any new feature you want to add.

When using htmx, a simple implementation of that would be

1. A backend route that returns HTML depending on the coupon state

2. Some htmx attributes (hx-post, hx-swap) on the frontend to make the magic happen

Don't get me wrong, there are places that you wouldn't want to use htmx (heavily interactive components) but that's why htmx recommends the "islands of interactivity" pattern. This way you can make the boring things that would add unnecessary complexity when using React with htmx, and then you can spend the unused "mental overhead" with the interactive components. (which, IMO, makes it a more enjoyable experience)

At the end of the day it is just choices: Some people may prefer the React approach, some people may prefer the htmx approach. All of them have their own upsides and downsides and there isn't a real answer to which is better.

But for my use case, htmx (truth to be told: I use my own custom library that's heavily inspired by htmx on my website, but everything that I did could be done with htmx + some htmx extensions) worked wonderfully for me, and I don't plan on "ripping it all out" anytime soon.

dubcanada

Just to be completely clear... you do not need React just so you can turn JSON into HTML. HTMX can 100% can do that.

You're argument is fine assuming you wish to become another react frontend in a sea of react frontends.

But the documentation example is a terrible argument, the benefit of HTMX is it is easy to understand what is actually happening. There is no magic, you don't need to dive through millions of lines of code to figure out what this is doing like react. It's very basic javascript. Just read the library, frankly you don't even need any documentation. Just take 15 mins and read the entire library.

xXSLAYERXx

> become another react frontend in a sea of react frontends

Whats the big deal here?

naasking

> Frontend and backend must agree on every scenario

When is this not the case?

wrs

I suspect the hidden assumption here is that frontend and backend are written by different people/teams with a narrow interface between them. Because they use different technologies and build tools it’s easy for them to end up being competely siloed, which IMO is one of the worst aspects of how webdev evolved in the last 20 years.

Thus, it’s considered normal that the backend team spits out some JSON and doesn’t know or care what the frontend team does with it.

With HTMX that distinction doesn’t exist so much (the frontend consists of fragments generated by the backend) so you will need a different organizational approach. The “frontend” folks will need to write a lot of “backend” code, but presumably in a separable layer.

samtheprogram

When an API returns JSON, your JS framework can decide what to do with it. If its returning HTML that's intended to go in a particular place on a page, the front-end has far less flexibility and pretty much has to put it in a specific place. Hence why they said endpoints can return 3-5 different versions of HTML.

naasking

> When an API returns JSON, your JS framework can decide what to do with it.

The JS framework is the frontend, so you're still coordinating.

> If its returning HTML that's intended to go in a particular place on a page, the front-end has far less flexibility and pretty much has to put it in a specific place.

Well yes, because presumably that's what the app is supposed to do. If it's not supposed to put it in that place, why would that be the specified target?

If this kind of static assignment of targets is not flexible enough for some reason, then use OOB updates which lets you replace fragments by id attribute. That lets you decouple some of these kinds of decisions.

Although "endpoints can return 3-5 different versions of HTML" is also a bit of a red flag that you're not using htmx correctly, generally endpoints should be returning 1, maybe 2 fragments in unusual cases.

In any case, you might find DataStar more to your liking, it's partway between React and htmx.

stefan_

It's terrible, why would I want my endpoints to return random HTML fragments? I realize thats how you did it in the JQuery times, but I was never in those - at that time we simply had template engines in the backend so this HTML slop wouldn't contaminate everywhere..

Most of the frontend stuff I do is for internal pages on embedded devices, and I'm very happy with a structure where I have the frontend being a full React fancy component lib SPA that is eventually just compiled down to a zip bundle of files that the backend needs to know nothing about and can serve as dumb files. The backend is a JSON API of sorts that I would need to build anyway for other use cases.

bottlepalm

Returning HTML sounds like a styling nightmare, if anyone changes the structure, unintended consequences. Plus it’s difficult to reason possible states of the UI with fragments sitting on the server, possibly dynamically built on the server. Very jquery/PHP ish. I had my fun and don’t want to go back.

drcongo

The HTML fragments aren't random.

ErroneousBosh

> It's terrible, why would I want my endpoints to return random HTML fragments?

What would you return instead? It's easy to generate HTML, because that's what your server is already generating (and that's about all it should generate).

stefan_

HTML is the last thing I would ever want to generate on my embedded device, it's a terribly verbose string-based mess invariably coupled with stylistic choices. Which is why my servers don't generate any of that, they serve static files - and any interactive information in something that looks a lot more like an interface definition.

0x3f

The thing is React is usually fine, and even if you don't have to build _this_ thing in React due to simplicity, why bother learning two paradigms when you can just use the heavier one for everything and most likely never encounter any real practical showstopping issue?

avisser

> why bother learning two paradigms

Objection. Your React is ultimately turning into HTML so you DO have to learn HTML + CSS. You just have an abstraction over it.

xnorswap

That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.

Yet I know roughly what it is, but I couldn't begin to actually write the stuff myself.

Good abstractions mean you don't have to worry about the layer below.

Now of course it's not really the case that React holds up to being a good abstraction, especially when it comes to CSS and styling, but I don't think it's a forgone conclusion that abstractions force you to learn the level below.

Otherwise we'd all spend half our time learning assembly.

I do have sympathy though for a developer who just wants to focus on the higher level paradigm and let the library maintainers worry about the innards.

forgotpwd16

React is an abstraction over UI state, not the platform (ie HTML/CSS). This is by design and non-parallel to C#/CLR case. If you want something akin to this, then Flutter is what you should be looking at.

komali2

> That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.

For a good part of your career this is true, but eventually you will need to justify your senior salary by being able to debug react via looking at library code itself, or understanding the event bubbling under the hood, or figure out why the output css isn't working.

Saw a video, wish I could remember who, someone developing a game in c-something. There was some bug they couldn't figure out so they jumped into I guess the assembly for that block of higher abstracted code, and was able to find some kind of memory issue. Vague, sorry, but point is I remember being really impressed, thinking oh shit yeah if I really want to be an expert in my field I better be able to really understand my stack all the way to the bones.

naasking

> That's like saying my C# is getting turned into CLR bytecode, so I do have to learn CLR bytecode because I have an abstraction over it.

That's not a valid analogy, 99.99% of C# developers never see or touch CLR bytecode, where every React developer is still working with HTML+CSS.

0x3f

That just makes HTML/CSS part of the React paradigm though. You can still use all those features in a React app, after all. The 'new paradigm' to learn with HTMX is how it does reactivity/interactivity.

purerandomness

The reality of React is that you have to keep re-learning and un-learning stuff if you want to keep up with React's ecosystem, because the surface area of the libraries is so large. (see "JavaScript fatigue")

Whereas with HTMX you learn a very, very basic concept in 15mins, and you're good to go for the next decade(s), and it will be more than enough for 80% of your projects.

Same as with vim and Emacs vs. proprietary IDEs and text editors.

0x3f

I agree that people often do this but I don't think you _have_ to. You could have freely ignored SSR, RSC, etc. and kept on making boring old React SPAs. The churn is largely opt-in.

the_other

My current app is a boring SPA. SSR, RSC wouldn’t make sense for it. My previous app was a video player with UI drawn in React: couldn’t SSR that.

krzyk

React (and Angular) is an MVC framework pushed on top of a MVC framework in the backend. Why make things so complex?

ajross

> you can just use the heavier one for everything

Because people don't like using heavyweight solutions needlessly. That's the logic that begat C++ and Ada and Multics and ASN.1 and CORBA. All of which were good solutions useful for "everything" in their domain. But people hate them, mostly.

Historically big "everything" solutuions end up losing in the market to lighter weight paradigms with more agility and flexibility. Almost every time. React[1] was such a solution once!

[1] Which really is a shorthand for "modern node-based web development with tens of thousands of npm dependencies and thirteen separately-documented API and deployment environemnts to learn".

0x3f

The thing is most of us have jobs where we can't unilaterally switch to the 'cooler' solution, and I value my own context-switching overhead much more than I value a slightly smaller bundle or dep tree. I'll much sooner optimize the former than the latter and so the general purpose solution that will solve both my own projects and the work ones typically wins.

ajross

> most of us have jobs where we can't unilaterally switch to the 'cooler' solution

Which is exactly why the uncool solutions persist in the market. They're useful and practical! If they weren't they never would have been successful at all. I'm just saying that that this is fundamentally the logic of the frumpy old curmudgeon, and the kids will always have something better to offer along with their confusing new ideas.

And to be clear, I'm also just saying that as someone looking in from the outside (I do firmware!) the front end webdev developer onboarding story has long since jumped the complexity shark and things are quite frankly an impenetrable disaster ripe for disruption.

adamzwasserman

Performance

hard_times

Not HTMX but Alpine.js has been a complete revelation to me. What clicked for me was that you're enhancing server-rendered HTML, not replacing it. Need a dropdown menu? Add x-data="{ open: false }" and you're done. Want to show/hide elements? x-show does exactly what you expect etc.

No bundler required, no compilation step.

null

[deleted]

kitd

Alpine even has a plugin to perform the same function as Htmx if you need it

https://alpine-ajax.js.org/

CodingJeebus

I worked on a large commercial AlpineJS app and grew to really, really hate it. It's great for smallish projects where the limits of the tool are known, but it is in no way a drop-in replacement for something like React (and I am no fan of React). People like to throw around how easy it is to do basic things, but building a real app using Alpine is an absolute nightmare.

Alpine data objects can grow to be quite large, so you wind up inlining hundreds of lines of JS as strings within your HTML template, which often limits your editor's ability to do JS checks without additional config.

State management in Alpine is implicit and nested and not a serious solution for building commercial apps IMO.

And don't even get me started on unsafe-eval.

If it's your hobby app and you are the developer and the product owner, go for Alpine. If you're working at a company that is asking you to build a competitive web product in 2025, use a more robust tool. Hotwire and Stimulus has scaled much better from an organization standpoint in my experience.

fzumstein

Have you tried the CSP build of AlpineJS? It takes the code out of the template into a proper JS file, no unsafe-eval. Isn't state management mostly handled on the backend when you use AlpineJS?

65

On the contrary, I've built some very complicated apps with Alpine and it handled the use cases every time. You are right with string methods creating it hard to click to go to the function in your IDE, but I'vd never had a problem with state management. Perhaps it depends on the setup.

adamzwasserman

Declarative is the way.

null

[deleted]

asim

Man I did try htmx, and I was hopeful, right until I saw how it polluted my codebase. I can't say I have the answers, but writing a pure Go app, I'm currently using one giant css file, custom styling and inline html.

And now I'm at the breaking point. So I'm planning to move to tailwind and Go templates, but honestly, i was hopeful for htmx, so I need to properly see the usecase. Which i don't know is this. It reminds me of Angular a lot...

kitd

This is the thing. Htmx is great if you only consider the frontend. But it does require fixing up the backed to match. A framework like that needs to integrate the front & back ends fairly tightly to have good UX. You may be interested in Datastar which does this better IMHO

https://data-star.dev/

qingcharles

My current plan is to switch to Datastar too, although the devs seem a little odd. The guys writing HTMX seem like a more professional bunch.

asim

Thanks I'll look into it, but on first glance I feel like I just got space blasted by the website! What happened to simple websites eh

kitd

Lol, it's ... a feature ... I think

yxhuvud

Turbo with a small sprinkling of stimulus may be closer to what you are hoping for - turbo especially is a lot more opinionated than htmx.

elevation

> it polluted my codebase

HTMX is less noisy if you integrate it into your backend framework.

A contact of mine build a python/flask app. To simplify coding, he wrote a file to extend the flask framework to support the HTMX patterns he needed with just a single line of boilerplate. Took him about a day, his team is happy with the results.

zihotki

It's not less noisy, you just move the noise to the backend

benji-york

> polluted my codebase

I'd love to hear more about that.

asim

Well listen, we have two modes of operation. It's either html/js/css in the classic sense, or Go templating with some tailwind and JQuery (or whatever the kids are calling it these days). In the case of react, something totally different. But essentially when you try to go that middle path with something that defines its own syntax, it starts to bleed into everything. It's not self contained. I'd argue maybe tailwind is like that as well, so you want to put it in templates or something. But if your htmx code lives in your actual code the way it does with Go a lot of the times because they promote building these partial functions, it looks horrible, very hard to reason or manage. I'm not talking one or two snippets, I'm talking when you have a full blown web app.

The reality is it's going to suit some people and some languages really well and others not so well. I think I like html/css/js and using AI to generate that. But I also like Go templates and trying to isolate that in a programmatic way. I find htmx in principle, a good idea, but when I actually tried to use it, fundamentally the wrong tool for me.

philipwhiuk

The proselyting over frameworks is the worst bit of the web ecosystem.

If your solution is actually good, it will get adopted eventually...

Forget React, there's still stuff written in jQuery and JSP.

Why the rush to convert everything - you're not a missionary on a mission, just build your stuff in stuff you like?

The attack on npm is ridiculous, when (apart from introducing a permanent vulnerability in the form of a runtime dependency on a third party site), you still need npm for htmx.

dubcanada

> If your solution is actually good, it will get adopted eventually...

This has never been more incorrect. The entire world of software is people using garbage solutions because the CTO is convinced Oracle/Microsoft/what ever new random software is the best thing since sliced bread. In no fashion has the best software solution ever been a factor.

dec0dedab0de

You definitely don't need npm for htmx, it's one file with no dependencies.

jollyllama

For all of the esoteric talk about hypermedia and things like this, this is the greatest advantage of HTMX, why I use and, and also why GP is dead wrong.

purerandomness

> If your solution is actually good, it will get adopted eventually...

I wish this were true.

Unfortunately, often the things that get adopted are the things hyped up the most, not the ones which are technically superior.

Popularity, marketing budgets and inertia often dictate what's popular.

As with all biases, we need to actively and deliberately work against these forces, if we value craftsmanship and professionalism.

komali2

Nextjs, great example of this. I've yet to find an actually valid use case to choose it outside of "our incestor's relationship got us unlimited vercel credits for like three years."

bobjordan

I’ve been a fan of this philosophy since the Intercooler.js days. In fact, our legacy customer portal at bomquote.com still runs on Intercooler. I spent the last year building a new version using the "modern" version of that stack: Flask, HTMX, Alpine, and Tailwind.

However, I’ve recently made the difficult decision to rewrite the frontend in React (specifically React/TS, TanStack Query, Orval, and Shadcn). In a perfect world, I'd rewrite the python backend in go, but I have to table that idea for now.

The reason? The "LLM tax." While HTMX is a joy for manual development, my experience the last year is that LLMs struggle with the "glue" required for complex UI items in HTMX/Alpine. Conversely, the training data for React is so massive and the patterns so standardized that the AI productivity gains are impossible to ignore.

Recently, I used Go/React for a microservice that actually has turned into similarly complex scale as the python/htxm app I focused on most of the year, and it was so much more productive than python/htmx. In a month of work I got done what took me about 4-5 months in python/htmx. I assume because the typing with go and also LLM could generate perfectly typed hooks from my OpenAPI spec via Orval and build out Shadcn components without hallucinating.

I still love the HTMX philosophy for its simplicity, but in 2024/2025, I’ve found that I’m more productive choosing the stack that the AI "understands" best. For new projects, Go/React will now my default. If I have to write something myself again (God, I hope not) I may use htmx.

grugdev42

Ultimately the complexity does have to live somewhere.

The idea that HTMX removes all the complexity is false. However it does remove some of it, and moves the rest onto the backend.

I find the backend easier to work with, so that's a win for me.

And a batteries included framework (like Laravel or Django) makes HTMX even more appealing. They already have everything you need! :)

geoffeg

> After the user downloads 2MB of JavaScript, waits for it to parse, waits for it to execute, waits for it to hydrate, waits for it to fetch data, waits for it to render... yes, then subsequent navigations feel snappy. Congratulations.

In my experience, a lot of SPAs transfer more data than the front-end actually needs. One team I worked on was sending 4MB over the wire to render 14kb of actual HTML. (No, there wasn't some processing happening on the front-end that needed the extra data.) And that was using graphql, some dev just plunked all the fields in the graphql query instead of the ones actually needed. I've seen that pattern a lot, although in some cases it's been to my benefit, like finding more details on a tracking website than the UI presented.

g947o

even for "downloads 2MB of JavaScript", it is often simply because the site is badly written (e.g. not careful about managing dependency), not necessarily because "JAVASCRIPT BAD".

Just look at the source code of amazon.com. It's a mess. But I bet it is more of an organizational problem than a tech stack problem, for a website worked on by literally hundreds of teams (if not more) where everyone crams their little feature in the website home page

superjose

Datastar has been garnering my attention https://data-star.dev/

werdnapk

I've had good success with Turbo (previously Turbolinks). The newer versions (ie. Turbo) really fixed up the shortcomings of the older versions (ie. Turbolinks) and I enjoy using it.

Any big reason to use HTMX instead? Is Turbo not really discussed much because of it's association to RoR?