HTMX gives you access to AJAX, CSS transitions, web sockets and server side events directly in HTML using attributes so you can build modern user interfaces with the simplicity and power of hypertext.

There is a surge of modern JavaScript libraries whose whole goal is to deal with HTML instead of JSON. Apparently, this makes the whole development process simpler and much more productive. And it works with any back end language. So if you've already got a back end application written in PHP, Ruby, Python, or Go or Rust, even JavaScript... Anything that produces HTML - It all works.

The following, is where I take a look at setting up HTMX using Laravel Bootcamp's Chirper application as a starting place.

Installing HTMX

Let's take a look at what it would take to install HTMX. So we've got a few options. It looks like we can just add a script tag in the header that brings in information or we can download our own copy and host it with the application, or we can do an npm install if we're using something like Webpack or Vite. Just for the sake of simplicity, I'm going to bring in the script tag from the CDN.

Progressive Enhancement

Okay, then the next step is it looks like I can progressively enhance all my links and forms in one shot by just adding an hx-boost attribute to the body. Okay, so already it's much faster. Even if I throttle my connection down to 2G and I switch between pages, there's no flash of unstyled content. And they're still just links, so if I were to click them before JavaScript was ready, it would still take me to the page that I'm expecting to go to. So that's a win!

Creating a new chirp

The next part of this would be that when we create a new chirp, it simply just gets appended to the to the list of chirps that we already have without having to re render the entire page. The way that I decided to do this was, the container that sits around the whole page, the div that sits around both the create chirp form and the feed the chirp feed list, so the direct parent of both of those, I'm adding three things: an hx-select, an hx-target and an hx-swap. These three things combined will make it so that any form or link that is a descendant of this container will inherit these (attributes). And so our create chirp form should just refresh just this small container.

So this is good because it feels like pretty simple solution that we might have to modify later to accommodate other things. Like maybe what happens when you edit a chirp or what happens when you delete it? Do those things still work and do they still work efficiently We don't know that yet.

It looks like our chirp form is just refreshing the page container. So none of this navigation gets re-rendered, which is good.

Now, the second piece is I would want to make sure that this also works with form validation. So if I try to submit with an invalid chirp... say an empty chirp, or something like that, that case still gets handled correctly. Now that we've got the create chirp scenario taking care of, let's take a look at how editing a chirp works.

Editing a chirp

If I click on edit now nothing happens. The whole page just kind of goes away. So let's see what we need to do to fix that. One way that we could fix this is we just add an id of "page" to the container around the edit form and that fixes it. That replaces everything on the page. This is basically bringing us back to where we were in the beginning, at least from a user experience perspective that the entire page and the entire... So the that the form and the feed both get replaced by this edit form. And then if I change it, same thing happens. Okay, great.

But what if we wanted to take this a step further? Instead of replacing the entire feed, could we just edit the chirp in line keep all the other things in the feed? It turns out that updating this to accommodate an inline editing strategy is really, really easy. I still have yet to write a single line of actual JavaScript. All I've done is re-target and re-select on this edit link. And Bob's your frickin' uncle! It's working like a beast. When I click edit, it replaces the chirp with the edit form, lets me make an edit and when I save it replaces it again, brings it right back.

And the really cool side effect of this, as you'll notice, is that when I hit the edit button and it replaces the content inline that it actually updates the history API so that it looks like we're on the edit page. And so if I were to, let's say, walk away for a couple of hours and my session cookie expires and then I have to log in again, it redirects me back. It redirects me back to the edit page. So what I was doing before I left. Even if I just hit the refresh button, it takes me to the edit page, the full edit page. I can still edit this the same as I could before I hit Save. It takes me right back.

Deleting a chirp

The last thing obviously is getting it to where when I hit delete, it simply just removes this guy from the DOM and that's it doesn't re render anything else. That's what we want to accomplish. To delete one, it's the same exact procedure. Make sure that the delete button is re-selecting and re-targeting the chirp id. And so if when the response come back, if the chirp has gone, it gets replaced with nothing. Well. And we're done.

Final thoughts

Is this going to replace your react app? Let's be honest. Maybe. Maybe not. The cool thing here... and I think what the takeaway should be is that there's now another option. And not just HTMX. There's Hotwire. There's Unpoly. There are more and more libraries coming out like this that shifts the work from the client to the server back to the server. Even react is moving more and more work to the server. There's just some things that you don't want to do in the client.

Man, I'm just kind of soaking this in. You know what I didn't even think about is there's no build step here. yeah, I, kind of cool. I think the pendulum is finally swinging back a little bit the other way.

20 years ago, we were building 100% server side apps and it was full page refreshes and flashes of unstyled content. And then the pendulum just flew the other way and we found out that we actually don't want to be doing everything in the client. Having fat clients comes with its own costs, and so I'm very happy to see the pendulum swinging back the other way just a little bit. Because it makes sense.

See ya!

So listen, that's going to be everything. let me know in the comments what you really think about this. If there's something that I missed, let me know. Anyways. Thanks for watching. I'll see you in the next one.

Modern JavaScript is Changing

There is a surge of modern JavaScript libraries whose whole goal is to deal with HTML instead of JSON. Apparently, this makes the whole development process simpler and much more productive.