> Fiddling with out-of-band swaps to solve this feels error prone and overly hard to maintain.

This is almost always because of using a string-based templating system. If you use a language-embedded HTML generation library, it represents HTML fragments as first-class values in your language, and you can compose them together in flexible ways. This makes out-of-band swaps very simple.

You mean by having a function per fragment? I don’t think this solves the hard to maintain bit - which is “which fragments should I regenerate/send”, and how do I keep that list up to date as my app evolves.

FWIW I have a potential solution: to show live data in my app I use an SSE stream of OOB swaps. On every relevant change to the database I regenerate the HTML and compare it to the previously generated html to create OOB swaps (including hx-preserve). I send that down so the browser can update.

The same approach could be used for normal POSTs. On a POST generate the HTML before and after modifying the database and diff them to generate OOB swaps.

HTMX is great, Hypermedia and HATEOAS are great, HTML-string-templates are not great.

For some reason they are still popular.

A fun experiment is to use a JS runtime with React but render the component tree on the server onto a Writeable stream.

Very easy to understand, no useEffect footguns, great composability.