htmx in Clojure using kit framework

2022-07-18 - Create a htmx based application using the kit framework

1. About HTMX

htmx is an alternative approach to making dynamic web applications. Instead of having Javascript (or Clojurescript) heavy frontend, and pass around a bunch of json data that gets transformed to html by the javascript code, htmx takes the other approach.

It basically passes html directly as a response, and it gets applied to the existing html page directly. Best of both worlds, according to the htmx guys.

2. Creating a kit project

Thanks to the Kit Framework it is easy to get started with htmx. Kit framework has an extensive documentation with a lot of examples. It provides htmx setup using its module system.

So, let's go.

First set up kit, and create a new kit project called todohtmx

clojure -Ttools install com.github.seancorfield/clj-new '{:git/tag "v1.2.381"}' :as new
clojure -Tnew create :template io.github.kit-clj :name marko/htmxtodo

3. Add :kit/htmx module to the project

Once the project is created you can switch to its folder and start a repl to add htmx support.

cd htmxtodo
clojure -M:dev:cider

Once in the repl, execute the following commands to get the htmx module installed.

;; first sync kit modules from the remote repository
(kit/sync-modules)
;; now list the available modules
(kit/list-modules)
;; we need to install :kit/htmx module, so let's do it
(kit/install-module :kit/htmx)

After that we need to restart repl to make sure everything is installed correctly. Exit the repl and start it again. Once started, we need to start our application simply by executing (go) in the repl.

If everything was fine, you should see a success message, and be able to go to localhost:3000 to see your application running. Clicking on a button will call the handler, fetch the html response, and update the button with the response received from the server.

4. A peek at the source code

Bulk of the source codde is in the ui.clj file. Let's take a look at it.

First, we have a definition of the page that is displayed when we access localhost:3000

(defn home [request]
  (page
   [:html
    [:head
     [:meta {:charset "UTF-8"}]
     [:title "Htmx + Kit"]
     [:script {:src "https://unpkg.com/htmx.org@1.7.0/dist/htmx.min.js" :defer true}]
     [:script {:src "https://unpkg.com/hyperscript.org@0.9.5" :defer true}]]
    [:body
     [:h1 "Welcome to Htmx + Kit module"]
     [:button {:hx-post "/clicked" :hx-swap "outerHTML"} "Click me!"]]]))

Here we generate the html output using hiccup library syntax. We include required htmx Javascript file, and an optional hyperscript file.

Page body is a simple button, which as :hx-post that defines the url of the on-click event, and :hx-swap attribute that basically instructs htmx engine to swap the whole button html with the output of the /clicked handler.

Handler for the cliked is relatively simple. It just defines the html to be returned.

(defn clicked [request]
  (ui
   [:div "Congratulations! You just clicked the button!"]))

These two handlers are wired to the reitit route as following:

(defn ui-routes [_opts]
  [["/" {:get home}]
   ["/clicked" {:post clicked}]])

Now that we have the basics running, you are ready to start working on your htmx based app.

5. What's more in kit htmx module?

Well, not much. It just wires the kit routes to the handlers returning html generated by the hiccup library and adds a few utility functions on top in the htmx.clj that can be used when creating a html response.

(defn page [opts & content]
  (-> (p/html5 opts content)
      http-response/ok
      (http-response/content-type "text/html")))

(defn ui [opts & content]
  (-> (h/html opts content)
      http-response/ok
      (http-response/content-type "text/html")))

6. About Kit framework

Kit framework provides an easy way to start a new Clojure application. Unlike its predecessor Luminus, it has a nice module system to add additional functionality after project is started.

It provides a lightweight kernel created around Integrant component library and Aero configuration engine which makes creating a new module and development a breeze, especially since it provides and excellent support for REPL driven development workflow.

It is still in an early phase, but fully functional and worth taking a look into if you haven't already. And it has an extensive begginer friendly documentation.

Keywords: clojure htmx kit