exupero's blog

HTMX versus ClojureScript

I was recently asked to present in a group Mad Libs activity, and it seemed like a good opportunity to play with HTMX. For the activity, each reader supplied a list of needed word types in a shared spreadsheet, then at the beginning of the activity the audience collectively provided their choices for those word types, which readers transferred into their stories. I don't know how the other readers transferred their words into their blanks, but I wanted it to be as easy as possible to do on the fly, so I did some pre-work to make the on-the-spot work easier. Since I'd been reading about HTMX, this provided a nice excuse to try it out.

I based my script on this Babashka HTMX todo app, though my needs were much simpler and needed only two endpoints: one for fetching the full HTML page, and one for fetching the story with words filled into its blanks. The resulting code was about 120 lines long and didn't require anything noteworthy, except maybe one function I've written about before. You can find the code here. In this post I wanted to capture some observations.

Instead of writing the script as an HTMX server, I could have written a client-side ClojureScript app. That would have had some advantages, such as making it easier to share with other readers. As an HTMX app, sharing it required spinning up a public server, distributing a script and requiring users to install Babashka, or compiling the Clojure code to something that could be with just Java installed. A pure client-side app, however, could have been distributed as just HTML and JavaScript, or deployed via GitHub Pages.

The nicest part of using an HTMX server was its simplicity. One hundred and twenty lines of code in a single file felt like the right amount of cognitive load for the feature set. There were no build configurations, no generated JavaScript or source map files, no deps.edn or bb.edn, and only one dependency. That simplicity was a major point in HTMX's favor.

One last comparison between HTMX and a ClojureScript app is the live reloading experience. A ClojureScript app using shadow-cljs has live reloading built in, and while I did write the HTMX server using an nREPL and re-evaluating functions as I changed them, the browser had no awareness of the changes and had to be refreshed to get the latest outputs.

I'd definitely use a small HTMX server again, though it will depend some on whether I really need server-side logic or could do everything client-side. If you have suggestions for improving the reload or distribution experience, please email me.