News for hackers. Stuff that matters.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by mg on Wednesday November 01, 2023 @11:30AM (#38099605)
I wonder what to think of htmx.

Their primary example is this:

    <button hx-post="/clicked" hx-swap="outerHTML">
        Click Me
    </button>
But that is rarelly what I want to do when a button is clicked. My typical example would be I have list of - say - cars, and each car provides a button to delete it:

    <button onclick="carList.deleteItem(this)">
        Delete this car
    </button>
And then in deleteItem(), I typically:

    let item=getItem(e);
    if (!confirm(`Really delete ${item['name']}?`)) return;
    let item_id=getItemId(e);
    items.splice(item_id,1);
    document.getElementById('items').innerHTML = template(items);
Where "template" is a handlebars template.

Would htmx have anything to say about this?

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by monknomo on Wednesday November 01, 2023 @11:37AM (#38099723)
I think where htmx would differ in your example is that it would not maintain the state of the list of cars in javascript, but would instead keep that state in the html, and the server.

I think the button might be something like this, I'm borrowing from their [delete row example](https://htmx.org/examples/delete-row/).

  `<button hx-confirm="Really delete {{item.name}}?" hx-target="closest tr" hx-swap="outerHTML swap:1s">Delete this car</button>`
In terms of your update example, yeah I think that's what htmx would do, just on the server, and returning rendered html.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by budafish on Wednesday November 01, 2023 @11:41AM (#38099773)
Also if you didn't want to do a hx-confirm, you could pop up a separate modal on button press. And then when the delete is pressed in the modal use a hx-target to update the specific row.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by mg on Wednesday November 01, 2023 @11:45AM (#38099856)
Hmm.. I don't think you can simplify their example to just that one line. For example, where is the url which is supposed to be requested to delete the item on the server.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by naasking on Wednesday November 01, 2023 @11:48AM (#38099912)
Add the hx-post="[url]" attribute.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by monknomo on Wednesday November 01, 2023 @11:51AM (#38099982)
good point, though I think hx-delete matches better
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by monknomo on Wednesday November 01, 2023 @11:50AM (#38099945)
You are right! There would need to be more.

but also, I'm not trying to provide a complete solution, just a direction to look in.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by kodapoda on Thursday November 02, 2023 @12:38AM (#38109055)
Beyond these very limited examples I just cannot see any appeal of HTMX... The real world large web apps have a ton of state that needs to be updated, UI elements that need to be swapped, multiple remote calls that need to be made on these actions. Why would you push all of that to the BE?

A simple click is almost never just "delete a row": you need to update the row count in the UI, validate whether it's the last row and therefore can't be deleted, send a log message that pulls data from user state (are you going to construct this state in the API handler every time a row is deleted?), update a heavy graph that shows a visualization of the data in rows, etc...

Maybe some very basic websites can survive with HTMX but that's incredibly not future-proof.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by recursivedoubts on Thursday November 02, 2023 @08:11PM (#38122340)
in htmx you would do all that through a single action and target the area necessary to update

if you had something like a count that was outside that area you could use an event, an out of band swap or just expand the target. we also have morph-based swaps that make it possible to retain more UI state while expanding the target area, if you'd like

if you have some sort of visualization, you'd recompute it server side and stream it back, or use events to trigger an update

adam james has done some cool stuff w/clojure and htmx visualizations:

https://twitter.com/RustyVermeer/status/1701048955105391044

a little bit of hypermedia-friendly scripting can go a long way:

https://htmx.org/essays/hypermedia-friendly-scripting/

you are correct that htmx isn't for every application, but it can likely pull off a lot more than you think, and at much lower complexity levels than reactive options, which has been borne out by real world experience:

https://htmx.org/essays/a-real-world-react-to-htmx-port/

as far as htmx being future-proof, I would point to it's predecessor, intercooler.js, which was released in 2013 and is still actively supported, simply because the code isn't hard to deal with. you could probably figure out and maintain htmx.js in a day or two, as a good JavaScript developer, something that can't be said for most other javascript frameworks.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by dragonelite on Friday November 03, 2023 @03:49AM (#38125704)
I started working in the early 2010s doing stuff on the backend was pretty normal with asp.net razor pages. Going from razor pages + jquery to AngularJs was one hell of transition.

I think i can like HTMX because its backend agnostic just template it out and return the html. Given 99% of the angular work i do is "get the json, render the returned json to html in angular". I think HTMX can pretty much replace angular with those sort of tasks. That makes being full stack dev quiet easy only need to know my backend stuff, html(x), css(tailwind). Maybe you need some lightweight frontend state framework to do a bit more in the frontend. But its a shitload less to learn than angular, node, typescript, build tools etc etc.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by kodapoda on Sunday November 05, 2023 @01:18AM (#38148810)
I would argue that HTMLX is far less backend agnostic than something like React. In most cases, a React SPA just consumes an API. You could switch to an entirely different backend with no impact on the users. How easy would it be to migrate all your HTML templates to a different backend?
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by dragonelite on Sunday November 05, 2023 @10:04AM (#38151718)
Well from experience backend tech stacks are way less mutable.

But let assume you did want to change backend you will take into account your HTML templates and find the right template engine where you might just copy past your templates folder and do some light configuration work.. If that is not possible refactoring the templates parts shouldn't such a big issue.

I see HTMX more as a way to keep far and far away from frontend frameworks, I can focus on being productive with Html, CSS and HTMX and call it a day. With react you need to learn HTML, CSS, moderate amount of javascript/typescript, state management, build tools etc etc.

But you make a good point about React SPA just consuming json or whatever other non html data format.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by recursivedoubts on Monday November 06, 2023 @02:30PM (#38167591)
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by kitd on Wednesday November 01, 2023 @11:37AM (#38099718)
Here's Htmx's "Delete a row" example, which I think is what you're after:

https://htmx.org/examples/delete-row/

The Examples page in general shows most typical use cases.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by stavros on Wednesday November 01, 2023 @11:38AM (#38099732)
You make the delete button load the /delete/ID URL, and return the fragment of the entire car list, to replace the existing fragment.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by pier25 on Wednesday November 01, 2023 @11:53AM (#38100010)
So the button would call a URL that would delete the car, and return the full list of cars to be replaced.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by dll on Wednesday November 01, 2023 @12:04PM (#38100238)
You'd use the hx-delete attribute and have a server side handler that responded to that by deleting the item & returning a new list of items. You can see an example of that approach (with Rust + Actix Web) here that I'm currently working on (the partial to list todo items is in templates, and you can follow the delete link to the relevant handler in routes/todo/delete.rs):

https://github.com/welshdave/actix-htmx/tree/main/examples/t...

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by stmblast on Wednesday November 01, 2023 @12:15PM (#38100417)
Normally I attach the ID to any newly created item via a templating engine so that when you use `hx-delete` to send a DELETE request, you'll be able to easily refer to what item you want to delete.
Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by BiteCode_dev on Wednesday November 01, 2023 @12:33PM (#38100764)
Something like this:

    <button
        hx-delete="/car/{{car['id']}}"
        hx-swap="delete"
        hx-target="closest .carcontainer"
    >Delete this car</button>

When you come to HTMX, it's normal to wonder about those kind of things, especially if you have being learning web dev post JSON era.

If this is your case, I'm writing a series of 5 tutorials on HTMX with this in mind:

https://www.bitecode.dev/p/a-little-taste-of-htmx-part-1

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by mg on Wednesday November 01, 2023 @12:39PM (#38100876)
This is approaching the code size of the vanilla js version. And it does not have the confirmation modal.

If there would be additional computational logic involved (say calculating how many rides this car has done this year so far to say "Really delete this car? It delivered 124 rides this year.") - would you also cram all of that into the button element?

What I am trying to say: I don't see which real world use cases are tackled by htmx. I usually don't have a use case as simple as "When element X is clicked, load url Y and replace element Z with it".

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by npilk on Wednesday November 01, 2023 @01:11PM (#38101380)
From an htmx perspective, you would probably calculate things like that on the server. So the row delete button might have an hx-get="<delete-confirm-url>" that returns an HTML snippet with your modal content ("Really delete this car?") and then the button in that modal would have hx-delete="<delete-url>".

Of course you can still add vanilla JS with htmx, and/or send the car.rides_delivered value from your model as part of the initial page load, etc. You don't have to do everything with the hx- attributes.

In my opinion htmx is excellent when you have a state that can be easily managed on the server, because it makes it simple to get an interactive SPA feel while still keeping state on the server. I think a lot of the htmx fan base would argue that most web apps don't need to manage their state client-side and therefore don't need all the overhead of React, etc. But of course htmx isn't a cure-all.

You can check out the writing on htmx.org if you're curious to hear more of the author's perspective and goals.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by BiteCode_dev on Wednesday November 01, 2023 @01:11PM (#38101384)
I would say, yes, in this case if you count your html for the button + the ajax request you would need to do to notify the server HTMX is shorter.

But, let's talk about the confirm. For a simple one, you would use hx-confirm and be done.

However, for a more complex confirm, you would make a delete request that would answer HTML.

The HTML would be showing the confirmation with the data calculated from the server (124 rides this year).

The response doesn't have to be a button, the server can answer a modal or a new subpage, which would contain a hx-delete with a "userconfirm=1" in qs and a cancel button to go back.

You don't have to limit yourself to replace the current element with the response, and the response is not limited to basic workflow.

Also HTMX is mostly about using hypermedia to communicate and favor the server to manage the state, but there is nothing saying you can't use JS.

You can even be naughty and have new HTML responses inject new JS in the page.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by naasking on Wednesday November 01, 2023 @02:00PM (#38102228)
> This is approaching the code size of the vanilla js version.

Code size isn't everything. The htmx version is more restricted, consistent and declarative. Assuming you get familiar with htmx, if you come back to both code snippets in 6 months, which one will you able to figure out faster?

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by listenallyall on Wednesday November 01, 2023 @02:11PM (#38102392)
The HTMX-oriented response would be, if you anticipate needing to know how many rides a car has completed, why not calculate that on the server or in the database, as opposed to in real-time on the client (in which case, presumably, you need to deliver a LOT more data to the client, such as a full list of all rides so you can calculate those which this one car was involved in).

> I don't see which real world use cases are tackled by htmx

Because you are prioritizing state on the client. Free yourself of that, and the use cases for HTMX start expanding enormously.

Re:Htmx, Rust and Shuttle: A New Rapid Prototyping Stack by smallerfish on Wednesday November 01, 2023 @02:19PM (#38102534)
Sure, but you've gotten rid of a shit-ton of complexity from your stack. No REST+JSON api/graphql. No frontend SPA. The templating system you use can call your db layer directly (or go through an intermediary layer if that's your preference). You solve the "single language" problem, with the backend being favored (rather than the "use npm on the backend because the browser speaks js/ts" approach of the last 10 years). Performance is kept reasonable because you're swapping out elements mainly rather than rerendering the whole page (i.e. it's not a return to servlets/cgi).