What is HTMX?
What this covers:
- Introduction
- Installation and Basic Usage with Examples
- Community and Ecosystem
- Security Considerations
When I first learned HTML and started building simple websites it was liberating. It felt empowering to build something and put it on the internet. Back then the business logic and presentation would generally all happen on the server. User interaction was limited to forms sent from browsers, that would return as brand new web pages, happily rendered by their patiently waiting recipients. Servers sent HTML and browsers rendered it. We call these hypermedia APIs.
Modern Web Development
Over time AJAX and frameworks like React and Angular enabled the kind of user interaction that early web pioneers could only dream of. But they have introduced a lot of complexity, and generally require some duplication of data models from backend systems which are likely returning JSON objects.
HTMX aims to enable rich user interactivity with only html attributes. It is a tiny javascript library that shifts some front end work to the domain of the server by extending the functionality of basic HTML. It enables some seriously cool patterns, and there are UI examples for most modern web tropes. (click to edit, dialogs, lazy loading, animations, active search, etc).
Installation
HTMX is dependency free, so to "install" htmx you simply add a <script>
tag to any html document. You can use the free content delivery network (CDN) or cache your own copy if you are the nervous type (npm install htmx.org
). The official htmx account jokingly offered a "create-htmx-app" script in this post on X that would create one html file with the following:
index.html
and opening it inside a web browser. You have officially created your first HTMX app!Usage - Custom Attributes
HTMX adds superpowers to the html in our document. The docs give lots of useful details, but the core idea is that any element can issue an HTTP request, and any element can be updated with the result of that request. The most important new functionality we get is hx-get
and hx-post
(both transform HTML elements into fully fledged AJAX request machines) but there are several other new attributes that will let us build amazing, responsive apps with no javascript on the front end.
Attribute | Description |
---|---|
hx-request | Issues an http request (eg request = "get") to the given URL |
hx-trigger | describes when to trigger (default = 'click') |
hx-target | replace any element on screen (transclusion) |
hx-swap | specify how to swap content into the dom |
hx-swap-oob | used for out of bounds swaps (advanced) |
hx-indicator | show an indicator during the AJAX request |
hx-include | include with request via a css-selector (e.g. "[name='email']") |
hx-disable | disables the element if set |
hx-headers | JSON object to be passed as headers with request |
hx-encoding | changes the request encoding from "application/x-www-form-urlended" |
hx-request | request level parameters (e.g. '"timeout":100') |
hx-vals | JSON submitted with the ajax request (e.g. hx-vals='{"key":"val"}') |
hx-push-url | controls url pushed to browser, defaults to false |
hx-sync | synchronize AJAX requests between multiple elements (eg - "replace") |
hx-ws | connects element with a websocket |
hx-sse | used for consuming server sent events via websocket |
hx-preserve | allows you to specify an element to remain unchanged |
The three most important to learn initially are hx-<request>
, hx-target
, hx-swap
. These will tell the browser what rest action to perform, where and how to place the results.
Any element can issue an HTTP request, and any element can be updated with the result of that request.
hx-<request>
The core of htmx are the attributes that allow you to send AJAX requests from any element. We have access to all of the traditional REST verbs: post
, put
, delete
, and even patch
and you can substitute any one of these for <request>
.
In particular, we can add hx-get
to any element, and when it is clicked, it will execute a GET request to the address we provide:
hx-swap
This attribute defines what to do with the response of our get call.
- "outerHTML" will replace the element entirely
- "innerHTML" will replace anything nested inside of it. (this is the default)
- can take a
settle:<time>
where time is a time value such as "1s" or "500ms" to put a delay on the swap.
hx-target
We can also add hx-target
to any element that has an hx-get
attached to specify exactly where htmx should put the result of the request.
hx-boost
Boosting any element will cause links inside of it to do a great impression of a single page app. It essentially transforms any links into get requests with a target of the entire body of the document. Boosted anchor (<a>
) links will replace the entire body
of the HTML document. Boost can be applied at the parent level.
Partial Updates with hx-select
The hx-select
attribute allows you to specify which part of the server's response should be used to update the DOM.
Request Indicators
Of course modern web sites need loading spinners. Set the attribute hx-indicator
to a css selector that specifies an element that should become visible while loading and go away after.
Lazy Loading
By setting the attribute hx-trigger
to revealed
, we can gate requests until objects scroll into view. Simply put a div like this at the bottom of your data and new elements will get fetched when a user scrolls to the end.
<div hx-get="/lazy-load" hx-trigger="revealed">
<!-- Content will be loaded when this element comes into view -->
</div>
There's a lot more you can do with this little library. I have built a handful of apps and I'm excited to share everything I have learned with you.
Community and Ecosystem
The community and ecosystem is growing in popularity (there are extensions available). You can inject them using the hx-ext
attribute and apply them to specific elements. HTMX is young, but will naturally grow over time. It has received a lot of attention lately and was even
The documentation is very straightforward, and can be a fantastic resource when you are getting started.
Security
Since elements are rendered server side, you can take advantage of this model to handle data validation before returning any content to a user. In theory, htmx can be very secure. Your templates and html partials are going to get delivered to front end users though, so you should be cautious.
- Serve your front end and back end from the same place (Only make requests against routes that you control).
- Use an auto-escaping template engine (eg - jinja, handlebars, blade)
- Authentication cookies should be set with
Secure
,HttpOnly
, andSameSite=Lax
- Only serve user defined content in html. Don't use any user defined values in
<script>
tags. Don't ever use user defined attribues.
For a full consideration of web security as it relates to htmx, check out the official advice.