- Published on
Why HTMX is Gaining Popularity: A Hands-on Guide with Examples
- Authors

- Name
- Mehdi Akiki
HTMX has been steadily gaining attention in the web development world, and once you dive into it, you’ll see why. It offers a way to simplify web interactivity without the need for complex JavaScript frameworks like React or Vue. HTMX operates in the space between pure static HTML and complex, full-blown JavaScript applications. It allows you to make your web apps more dynamic by leveraging declarative HTML attributes.
In this article, we’ll go beyond just theory and explore four hands-on examples that demonstrate why HTMX is a game-changer. Plus, we’ll dive into the versatile hx-on attribute to see how you can attach custom event listeners with minimal effort.
Example 1: Simplified AJAX Requests with hx-get
Let’s start with a classic scenario: fetching data from the server on button click. Normally, this involves setting up JavaScript event listeners, making an XMLHttpRequest or fetch call, and then updating the DOM. HTMX makes this process almost trivially simple:
<button hx-get="/data" hx-target="#content">Load Data</button>
<div id="content">
<!-- Data will be loaded here -->
</div>
Here’s what’s happening:
hx-get="/data": Sends a GET request to /data when the button is clicked. hx-target="#content": The response from the server will be injected into the #content div.
Why it’s better: There’s no need for JavaScript to handle the request or update the DOM. HTMX makes your code cleaner and easier to maintain.
Example 2: Submitting Forms with hx-post
Imagine you have a form that needs to send data to the server and update part of the page with the response. With HTMX, it’s as easy as adding a couple of attributes to your form:
<form hx-post="/submit-form" hx-target="#result">
<input type="text" name="inputField" placeholder="Enter some data" />
<button type="submit">Submit</button>
</form>
<div id="result">
<!-- The server response will appear here -->
</div>
hx-post="/submit-form": Submits the form to /submit-form via POST when the button is clicked. hx-target="#result": Injects the response into the #result div.
Why it’s better: You don’t need JavaScript to handle the form submission. It’s all managed declaratively, allowing you to focus more on HTML.
Example 3: Event Handling with hx-on
HTMX allows you to attach custom event handlers using the hx-on attribute. This lets you manage more specific events in a declarative way without needing additional JavaScript event listeners.
For example, let’s say we want to display an alert when a button is clicked:
<button hx-get="/data" hx-on="htmx:beforeRequest:alert('Fetching data...')" hx-target="#content">
Load Data with Alert
</button>
<div id="content"></div>
In this example:
hx-on="htmx:beforeRequest:alert('Fetching data...')": This triggers an alert box right before the request is sent. You can bind to almost any event that HTMX triggers, like htmx:afterSwap, htmx:beforeOnLoad, and htmx:responseError, allowing you to add interactivity easily.
Why it’s better: By using hx-on, you can attach custom behaviors in-line with your HTML, eliminating the need to jump between HTML and JavaScript files. This keeps your code focused and organized.
Example 4: Real-time Search with hx-trigger
One of the most useful features of HTMX is its ability to trigger requests based on user actions. You can build a real-time search with just a few attributes:
<input
type="text"
name="search"
hx-get="/search"
hx-trigger="keyup delay:500ms"
hx-target="#search-results"
/>
<div id="search-results"></div>
hx-trigger="keyup delay:500ms": Waits 500ms after the user types to issue a request. hx-get="/search": Fetches search results from the server. hx-target="#search-results": Injects the response into the #search-results div.
Why it’s better: Implementing real-time search usually involves debounce logic, event listeners, and manual DOM updates. HTMX simplifies this entire workflow, letting you add real-time search with only HTML attributes.
Example 5: Polling with hx-trigger and Event Handling with hx-on
You can create auto-refreshing content by combining polling and event handling. For instance, a live notifications feed that updates every few seconds:
<div
hx-get="/notifications"
hx-trigger="every 5s"
hx-on="htmx:beforeRequest:console.log('Polling...')"
hx-target="#notifications-list"
>
<!-- Notifications will update every 5 seconds -->
</div>
<div id="notifications-list"></div>
In this case: hx-trigger="every 5s": HTMX will send a GET request every 5 seconds. hx-on="htmx:beforeRequest:console.log('Polling...')": This logs a message to the console before every request.
Why it’s better: HTMX handles both the polling and the event handling in a declarative and straightforward manner. You don’t need to manually manage intervals or event listeners with JavaScript.
Example 6: CSS Transitions with HTMX
HTMX makes it easy to apply CSS transitions to swapped elements. Consider the following example:
<div id="content">Original Content</div>
<!-- HTMX will replace this content with new content -->
<div hx-get="/new-content" hx-trigger="click" id="fetch-new-content">
Click me to get new content
</div>
<!-- CSS Transition -->
<style>
#content {
transition: all ease-in 1s;
}
.new-state {
color: red;
}
</style>
Once HTMX swaps in new content for #content, the transition will apply smoothly because the transition CSS is triggered by changing the element’s class or content.
Example 7: Out-of-Band (OOB) Swaps
Out-of-band swaps allow you to inject content into a different part of the DOM using the hx-swap-oob attribute. Here's an example:
<!-- Target element -->
<div id="status">Old Status</div>
<!-- Button to trigger the swap -->
<button hx-get="/status-update" hx-swap="none">Check Status</button>
<!-- Response returned from /status-update -->
<div id="status" hx-swap-oob="true">Updated Status</div>
In this example, HTMX swaps the returned content into the element with the matching ID (#status), even though the request came from a different element.
Example 8: Triggering Requests with Filters
You can apply filters to event triggers using HTMX's hx-trigger and square bracket filters. This allows for conditional event handling.
<div hx-post="/clicked" hx-trigger="click[shiftKey]">Shift+Click Me</div>
Here, the hx-post request will only be triggered when the user holds down the shift key while clicking.
Example 9: Polling with HTMX
HTMX enables automatic polling for server updates by using the every keyword within hx-trigger. Here's a polling example:
<div hx-get="/check-updates" hx-trigger="every 5s">
Latest update will appear here every 5 seconds.
</div>
This setup will issue a GET request to /check-updates every 5 seconds and replace the content inside the div with the response.
Example 10: Using hx-on for Advanced Event Handling
HTMX allows you to use the hx-on attribute to bind JavaScript events dynamically:
<button hx-get="/content" hx-on="htmx:beforeRequest: console.log('Request started!')">
Fetch Content
</button>
In this example, a message will be logged to the console before the HTMX request is initiated. The htmx:beforeRequest event allows you to hook into HTMX's lifecycle and execute custom logic.
Why HTMX is a Game-Changer
HTMX stands out by simplifying complex interactions with just HTML attributes. You don’t need to manage JavaScript-heavy frameworks to create dynamic web applications. Instead, HTMX enables you to:
Reduce complexity: Keep your code declarative and lean by handling interactivity directly in HTML. Avoid unnecessary JavaScript: Most interactions, from AJAX to event handling, can be done without writing JavaScript. Increase productivity: Less boilerplate means faster development and easier maintenance.
Last Words
HTMX is gaining popularity because it offers an elegant solution to a common problem: reducing JavaScript bloat and simplifying dynamic web development. Whether it's handling AJAX requests, managing custom events with hx-on, or implementing real-time updates, HTMX makes it easy for developers to build dynamic UIs while keeping their code simple and maintainable.
Give HTMX a try in your next project, and you’ll likely see why so many developers are turning to it for web interactivity.
I build and scale reliable production systems. Open to full-time and freelance work with U.S.-based teams that value ownership and execution.
Got something in mind?
Book a Discovery Call