HTMX | Bringing back the joy of development

Frontend doesn't need to require 2 hours of setup time. Learn how HTMX provides access to all modern JS features directly from HTML.

HTMX | Bringing back the joy of development
simpler the better | HTMX Banner

In most modern web applications you start off by creating RESTFul APIs to serve data to your web app. This is fine if you're planning to create a mobile application or something alike. For most applications, this is overkill and more often than not, backends get designed to optimally serve data to the frontend framework of choice rather than serving the needs of the user.

The plight of modern frontend frameworks

Go ahead and try to create a new project in Angular, React, Vue, or whatever new framework just dropped. See how much time it takes you to ship "production ready" code.

You end up installing a million different dependencies, packages that you don't even know the functionality of. Then you set up Webpack, Gulp, Babel, and a tonne of different build tools to get things to "compile" and run. The funniest part is, you literally write in a language version (ES6+) that needs to be "dumbed down" for the browser to understand (ES5).

It's like the old saying, "Give me six hours to chop down a tree and I will spend the first four sharpening the axe." but here, you end up gathering so many items as if it's a Zelda quest and then only can you start sharpening your god damn axe. If Lincoln used React he wouldn't have been able to free the slaves because he'd be stuck in dependency hell.

Oh and how about this, if you already have a project setup, run npm audit and see what happens. Oh, you see a few vulnerabilities? That's easy, run npm audit fix that will solve all your issues. Hmm... doesn't seem to be working now, is it? How about npm audit fix --force  ? Oh well that did it! Wait a minute... now your project won't run? You know what? git checkout . The infosec team can deal with this.

Problems don't end here, but I don't wanna start bitching.

Enters HTMX

I am a big fan of not doing unnecessary work, server-side template rendering, and Taylor Swift. Enter HTMX.

htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext.
htmx is small (~14k min.gz’d), dependency-free, extendable, IE11 compatible & has reduced code base sizes by 67% when compared with react

HTMX allows you to make HTTP calls, and trigger events, from any HTML element. You can also replace certain components of the page instead of having to reload the entire page. You can make your entire web application feel just as UI / UX friendly as any other Framework would without having to put in a SHIT TONNE of work.

Implementing HTMX

All you need to do is source it via the <script> tag in your HTML file.

<script src="https://unpkg.com/htmx.org@1.9.2" integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h" crossorigin="anonymous"></script>

sourcing HTMX in your HTML

Here's a small example of "Click to edit" implemented in Django (you can grab the project from my Github) without installing any HTMX-specific dependencies on the backend.

The following code lists out all the users and renders a button to edit their details.

{% for user in users %}
<div class="container">
    <div hx-target="this" hx-swap="outerHTML">
        <div>
            ID {{user.id}}
        </div>
        <div>
            Username: {{ user.username }}
        </div>
        <div>
            Email: {{ user.email }}
        </div>
        <button hx-get="/user/{{ user.id }}" class="btn btn-primary">
            Click To Edit
        </button>
    </div>
</div>
{% endfor %}
HTMX code for editing a User

Here's what is happening here. The HTML lists all the users in the DB and adds and Edit button to fetch the form and render it in its place. Here's what the HTMX attributes are doing.

  • hx-get:  Will make an HTTP call to the endpoint /user/:id and get the response.
  • hx-swap: This will swap the contents of a specific HTML element with the incoming HTML that is fetched by hx-get
  • hx-target: This lets you specify which element to target for the swapping of incoming HTML.

This is the HTML that is returned when the HTTP call is sent by hx-get.

<form hx-post="/user/{{user.id}}/edit" hx-target="this" hx-swap="outerHTML">
    {% csrf_token %}
    <div>
        <label>ID - </label>
        {{ user.id }}
        <input name="id" type="number" value="{{ user.id }}" hidden />
    </div>
  <div>
    <label>Username - </label>
    <input type="text" name="username" value="{{ user.username }}">
  </div>
  <div>
    <label>Email Address - </label>
    <input type="email" name="email" value="{{ user.email }}">
  </div>
  <button>Submit</button>
  <button hx-get="/">Cancel</button>
</form>
HTMX code for saving a form

Anything that doesn't have hx- prepended to is pure HTML or Jinja2 (templating language to process context/data sent from the backend). Here's what's going on.

  • hx-post: Makes a POST HTTP call to the endpoint /user/:id/edit. It will also send all form fields value to the backend that has the name attribute attached to it.
  • hx-swap=outerHTML: This means that replace an element (target element can be specified by hx-target) entirely with the incoming HTML.

So, all in all, once the form data is submitted, whatever gets returned as the response replaces the Form. There's a demo down below for a better understanding.

Demo of HTMX in action.

Conclusion

For me, HTMX is an absolute game-changer. From now on I can hit the ground running and start writing the UI rather than having to wait for npm install it to finish. I will also be rewriting a side project Jiffy - A web app that helps you turn your notion and obsidian docs into websites in a matter of seconds. I am really excited about it and I'll keep you guys updated on its progress.

Also, I wholeheartedly urge you to please go and check out htmx.org/examples/, see what it is capable of, and give it a fair shot. I am SURE you will fall in love with it.