The changes you're describing are already here in standard HTML + JS.
Every element can be replaced with custom Web Components that can cause requests. Content can be partially displayed with just a click, tap, keypress, etc. and it doesn't even require scripting!
There are over 200 extant discrete methods that can be used to send network requests in web applications running in modern browsers.
If I understand correctly, the main selling point of htmx is that _html_ is extended with the attributes from GP: the idea being that a bulk of the interactivity of SPAs can be achieved via hypertext alone
I think a more precise reading of GP's "changes just 4 things in browser behavior" is "changes just 4 things in html behavior"
> the bulk of the interactivity of SPAs can be achieved via hypertext alone
except that with htmx the backend is supposed to return htmx markup, so now the hypertext is smeared between two systems. this lack of separation is the main thing holding me back from using it in any serious effort.
it feels like the "full stack dev" problem writ large. should my backend devs also be experts in front end? should my front end devs be digging into backend code? I'm a generalist myself but it's not reasonable to expect everyone to be a generalist, nor does it make good business sense.
then there's the backend-for-frontend argument, which the manager in me always reads as "we need to double the number of backend services". it's a bit hyperbolic but still.
You should be using the same templates/partials/fragments/components that render in your initial page load as your responses to page updates.
So to render a table you render each row from a row component - then in response to updating a row in the table your backend end point returns the row component and then htmx swaps it out and rebinds everything.
Also, one big aim of htmx and this approach is to remerge the backend and frontend, like the old days.
This is the aim of HATEOS (hypermedia as the engine of state) and if you came up in web dev in the past 12 years or so then it’s going to feel very alien.
And honestly? Yes I think everyone should be a generalist otherwise you have just siloed your stack in away that increases both tech and business risk. Sure have someone who is an expert where needed but they should also be able to touch the full stack.
If I was to tackle a simplified view of the problem I think you're describing: your frontend devs should provide the markup template the backend would interpolate and return
In the scenario you've alluded to, your backend devs are currently producing json data and your frontend devs are interpolating that into markup in the browser. In the simplest case then, your frontend devs would just provide a markup template that can be interpolated with the json already being produced. In slightly less simple cases, they can provide a function to be called instead
The gist is that the logic of taking data and producing markup should remain in the frontend dev's wheelhouse
with JSON, frontend devs can ignore chunks of it, or work with the backend devs to modify the payload.
HTML, being a representation of a desired state rather than a neutral information exchange medium. is tricky to do that with. the frontend and backend devs would have to remain in lockstep with any changes made to the payload, ie the frontend and backend applications become tightly coupled.
I don't really see how having front end devs hand off a spec saying "we need this exact result format" is better than a loosely coupled result in a standard format
In a team where the backend devs can't work with the HTML templates for whatever reason, the frontend devs would be directly managing those.
I definitely wouldn't ask my frontend dev to write a spec and hand it to me to make their template, the spec spec would effectively have to be the template source code anyway. Just get in there and work with the HTML templates themselves.
I think this htmx essay [1] addresses the tradeoffs you may be getting at if you're thinking "why html vs js+json": the gist is that html is self-describing to the browser, so the backend can make changes to the html it produces and the browser will understand it without the frontend code needing to be updated
If you're instead thinking more broadly in terms of "structure vs layout", I think the same reasoning for using something like tailwind css or higher-level web components may apply: i.e. the material you interact with is closer to your problem domain
htmx mixes logic with "templates" in the same manner that HTML mixes logic with templates: hypermedia control information is embedded in the hypermedia in the form of attributes
Maybe I should clarify the type of logic I mean. Standard HTML contains instructions for how content should be rendered. But it has no control flow structures to control what content should be rendered.
Embedding loops and if/else logic in htmx tags creates scenarios where the content is potentially modified in the rendering step, meaning you can't rely on just looking at the data the backend sent over the wire to determine the source of a result that renders incorrectly. Instead of having control flow in one place, and a single source of truth, it creates an additional point of failure.
Stock price showing up wrong? That might now be a problem in your backend logic or in your complex htmx engine, buried in some template tag.
You don't need to mix logic with templates. I just produce a context (result from database queries and some such) and pass it to a function that produces HTML from the data in the context. The data must not be changed in the templating function. This is something I try to avoid as well in order to maintain separation of concerns in the backend code.
Edit for clarification: The context holds the data that is rendered as-is by the templating function. So any transformations from the "raw" database data and the context data happens beforehand and the templating function just turns it into HTML.
Accessibility is a royal pain in the ass if you replace every built-in element with a custom element.
We'd be in a much better spot if browsers supported extending the built-ins. Without that, every custom element can only extend HTMLElement and all accessibility features in things like select menus are entirely up to you to reimplement.
You might want to read the TFA, it's describing a "whole other language" they call Hyperscript
on click send htmx:abort to #contacts-btn
on htmx:beforeRequest from #contacts-btn remove @disabled from me
on htmx:afterRequest from #contacts-btn add @disabled to me
hyperscript is a completely separate technology from htmx, it is designed to be an alternative to javascript and is very speculative
htmx generalizes hypermedia controls, that's pretty much it, and it can be used with any scripting tool you'd like: AlpineJS, hyperscript (if you are brave), vanilla js, etc.
All the hx-* attributes constitute a separate DSL with its own semantics and it requires the server to conform to this DSL that also subsumes a bunch of existing HTTP semantics like redirects.
<!-- Some kind of inline DSL in an attribute? Check -->
<div hx-get="/example"
hx-swap="innerHTML show:#another-div:top">
Get Some Content
</div>
<!-- Some kind of inline DSL that is sorta kinda JS? Check -->
<div hx-get="/clicked" hx-trigger="click[checkGlobalState()]">Control Click Me</div>
<!-- Some kind of inline DSL that is marked as Javascript and with magic values passed in? Check -->
<div hx-get="/example" hx-trigger="keyup" hx-vals='js:{lastKey: event.key}'>
<input type="text" />
</div>
<!-- Is it Javascript? Jinx, it's custom DSL -->
<button hx-get="/info" hx-on::before-request="alert('Making a request!')">
Get Info!
</button>
<button hx-get="/info" hx-on="htmx:beforeRequest: alert('Making a request!')
htmx:afterRequest: alert('Done making a request!')">
Get Info!
</button>
we are tentatively working on a proposal with the chrome team that takes the most important concepts of htmx and integrates them into HTML using more standard attributes. Alex Petros, a core htmx dev, gave a talk at Big Sky Dev Con on this idea here:
I'm convinced you can get most of htmx by extending standard attributes to other elements and using the standard on* attributes. htmx basically acts as a "universal/general event handler" that translates DOM events to requests and back to DOM events and modifications. It breaks down like this:
* use on* html attributes to delegate events to a universal event handler
* event handler pulls out the form attribute (if set), then pulls out action, method, target from element, or from the form if unset on the element (elements inherit these from the form they are tied to)
* if action is a URL, then initialize a fetch request using specified URL and method; if method is POST, then add a FormData payload for the specified form
* on fetch complete, the returned MIME type should match with the target attribute, which is extended to also accept a css selector:
yep I think you could do a lot in this direction (see Alex’s talk) I would be hesitant to hijack existing attributes for more than a proof of concept at this point but maybe that’s me being too timid.
htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes: https://htmx.org/reference/#attributes
--- end quote ---
All my examples come directly from htmx documentation
sorry! Got you crossed up w sapling-ginger above and thought I was talking w the same person.
agree that htmx has a regular language core for config options but, as hyperscript indicates, I’m not afraid of even a recursive language when I think it’s useful.
Hopefully we can get some of the ideas into HTML in a more standard form!
I would love for the authors to consider a book on Hyperscript.
I initially dismissed wanting to add another scripting language to an app, but after some experimenting I have used it to replace 100s of lines of JS. Mainly for UI animations.
It’s not for the faint of heart, but enjoyable to learn.
I find the docs difficult to follow and would enjoy another hardback manual to sit next to this book, which is superb.
The point isn’t to erase the need for JavaScript entirely, but to make it possible to integrate and interact with a backend in a meaningful way using just mainly html.
It's enough to read the context of the discussion, don't you think?
Original complaint: "it's describing a "whole other language" they call Hyperscript"
Response: hyperscript is a completely separate technology. htmx generalizes hypermedia controls, that's pretty much it, and it can be used with any scripting tool you'd like
My response:
In reality [1] htmx defines its own non-optional DSL that you have to use.
---
I will add that as with any organically grown nice-to-have utility DSLs it's quite haphazard (it's hyperscript-like in one place, js-like in another place, both in some other places etc.). But that's the nature of such ad-hoc informally specified DSLs
[1] which can be easily verified by just visiting https://htmx.org
The only place where it talks about anything else is a small section on scripting with a link out to a huge meandering essay with small examples lost in all the philosophical discussions.
Edit: Don't forget also that this is entirely non-optional because if you use htmx, you will load the full support for it whether you use it or not
Every element can be replaced with custom Web Components that can cause requests. Content can be partially displayed with just a click, tap, keypress, etc. and it doesn't even require scripting!
There are over 200 extant discrete methods that can be used to send network requests in web applications running in modern browsers.