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.

> 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.

(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.

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.

You won't keep those performance numbers if the network conditions are bad, unfortunately. For things that require a network round trip, that's fine, because doing it via JSON (or some other serialization format) won't save you anyway. On the other hand, if it can be done entirely on the client, adding network round trips will slow the interaction down. It sounds like you're mostly doing the former (otherwise loading indicators and serialization wouldn't matter), but it's a point that should still be emphasized.

I think you misunderstood me. I use htmx where most people would use fetch. I do not just use htmx willy nilly for no reason.

I use pure front end manipulation to set state, then I send the state to the stateless back end with pure functions, and I get amazing performance: www.multicardz.com public test bed, 1M records, round trip usually around 160 ms for anywhere between 1 to 100K hits

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.

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.

This is what doesn't get discussed enough around htmx, in my opinion. So much of the difficult steps are left for the templating system, and template systems aren't great in general. You need to track a lot of identifiers for htmx to work properly, and your template and view logic needs to make that make sense. For the templating systems I've seen, that's not so simple to do.

1000% this. I actually am using htmx at ${JOB} and this is essentially the only downside to htmx. I want to know which template partial is getting swapped. My IDE doesn't know. I need to track countless html ids to know what will be swapped where... how? It hasn't been a big deal because I alone write the frontend code so I have all my hacks to navigate and my intimate knowledge of the code, but if we need more devs on the frontend, or if the frontend drastically grows feature wise, i will need to tackle this issue post haste. I think template partials could help, but then we also would end up with giant template files and that would also be annoying.

How does it feel to be one of 3 HTMX related jobs in the universe (according to the comments in this thread)? heh.

Last time I dabbled in a front-end I tried out Astro but felt like it just added another layer of complexity without much gain when all my components were just wrapping React in different ways. I went with react router instead.

I can see the value of the "islands" concept when you have a huge front-end that's grown over generations of people working on it.

For my constrained front-end debugging Astro errors on top of React errors on top of whatever all the turtles down felt a like a step too far.

Am I in my Rust centered back-end driven brain missing something?

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

I'm playing with JSX, Hono, and Bun right now to do just that. It's early but will see how it goes.

Astro is great. If you are familiar with React, you can pick it up pretty much instantly. The design is simple enough to extend when needed as well for custom things.

>Where do I add the JavaScript for that? Is it raw, inline, or are we back to packages and bundling and a build step?

That’s really your call to make. I’ve never went the full build step with it, but I’ve only built some internal dashboards and crud apps with it.

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?

What's your decision tree for when you feel you need a SPA in 2025?

At least some of what you may not be getting in this space is how many developers right now seem to be hugely deprioritizing or just dropping SPA from their decision trees lately. Recent advances in CSS and ESM and Web Components such as View Transitions and vanilla/small-framework JS (ESM) tree-shaking/"unbundling"/importmaps give MPAs more of the benefits of a complex SPA with fewer of the downsides (less of a "mandatory" build process, smaller initial bundle load). It is easy to feel less of a need for "complex SPA" to be on your architecture options board.

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.

Hello world in react is just a few lines of code that mounts a react component to a dom element. There should be zero network requests beyond the initial download of html and js.

You’re either doing something wrong or not actually doing a hello world.

I don’t know but vite was involved, looks like it was setting up live updates. This is part of the problem, you can’t just include a script apparently.

vite adds additional things to your page in dev so that it's easier to debug. when you are running it in production, it is just one js bundle & one css file.

That’s just Vite’s dev mode. I think React is way overused but your example here is a bad one. You just weren’t aware what the dev tool was doing, it has nothing to do with the experience end users will have. It isn’t even anything to do with React.

Was it in Dev mode?

> 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.

Plain react is arguably just as simple if not simpler than jquery.

And I’m not saying every site needs to be an SPA. I’m saying if I can write everything from a simple site to an SPA in a single framework then why not use that for everything?

How do you handle routing with plain React?

React is an implementation of View component of MVC, View is responsible for displaying Model contents, not for handling routes. You are trying to use the wrong tool.

Using built-in browser apis. Not sure what you’re getting at.