HTMX — New Hype, new problems — Jails for the Rescue.
The moment we’ve all been waiting for has arrived. Htmx is gaining momentum amidst the front-end frenzy. While it may not be my preferred solution, given the unnecessary complexity introduced by modern front-end frameworks in the majority of web applications, it serves as a catalyst, prompting the community to reconsider its approach.
Htmx is not the sole player in reshaping perspectives; other agnostic tools and metaframeworks, such as Astro and Tailwind, are also contributing to this paradigm shift. What I find intriguing is how Htmx, in its own way, exposes the superfluous intricacies that have become commonplace in today’s web applications. However, for specific reasons, it doesn’t align with what I was seeking.
The complexity is still there, it just moved to the back-end
Hey, just a heads-up: diving into HTMX means you’re still in for rendering pages, handling components, and getting down with validations and business logic. But here’s the twist — those aren’t just your usual front-end squad problems anymore. Now, it’s a back-end party, and they’re the ones managing the mix.
From day one in my front-end journey, I picked up on the fact that mixing things up usually leads to some serious headaches. Trust me, it doesn’t age like fine wine. I’d steer clear of tossing all these concerns into one pot — it’s a recipe for future regrets.
Here’s the deal: rolling with this approach means you’re signing up for a Fullstack Team gig. The cool part? You get to pick your poison when it comes to the back-end language.
The whole “Fullstack” buzz is a bit of a head-scratcher, and personally, I’m not its biggest fan. Finding someone rocking both disciplines like a rockstar is like spotting a unicorn — it’s rare, especially considering the ever-expanding sea of info and skills needed nowadays.
Now, if you’re all in on the “fullstack” vibe, be ready for a potential pitfall. Instead of unlocking the full potential of your developers’ expertise, you might end up settling for an average skill level across the board.
Here’s my hunch: sooner or later, your fullstack dream team will naturally split into two squads. One comfy with HTML and UI jazz, and the other rocking it in infrastructure, reliability, integrations, security — the whole shebang.
And voila! You’re back to the good ol’ Front-end and Back-end Teams. For a startup, sure, it might be a decent kick-off strategy, but for a well-established company? Not so much. You risk missing the chance to outshine your rivals and might even drag down your team’s performance with a less-than-optimal setup.
Again, being in the extreme…
I’m convinced that many of the challenges we face in today’s modern web apps stem from our love for extremes. It’s like we can’t decide whether everything should reside in JavaScript — HTML (JSX), CSS (CSS-in-JS), images, SVGs — or if we should push all JavaScript into HTML, embracing tools like Alpine.js and the latest sensation, Htmx.
Anyone with a solid 5 years in the realm of JavaScript web applications knows this extreme approach doesn’t hold up in the real world. Take Alpine, for example; debugging and scaling become real headaches when your code is directly embedded in HTML files.
Then there’s Htmx, where you end up needing an additional library or framework if you want to handle things that don’t warrant a server request. Some teams opt for the middle ground, going with vanilla JavaScript alongside the Htmx library. While I’m personally inclined towards vanilla JavaScript over heavy frameworks like React and Angular, I’m aware that treading this path leads us down the same road we traveled back in the day when we realized we needed some kind of engine, framework, or library to enhance how we abstract and organize our apps.
Here we are again, caught in the same cycle of extremes.
So… what then?
The sweet spot lies in finding a middle ground.
I’ve been deep into a JavaScript library for quite a while now — Jails. The name drew inspiration from Rails because, for me, Rails is a framework that seamlessly aligns with the language and back-end context. I wanted to create a similar vibe but for the front-end.
It’s been nearly nine years since I kicked off this journey, constantly fine-tuning and simplifying. Currently rocking its fifth version, it’s all decked out with modern HTML5 and DOM API features.
So what is Jails in a nutshell?
A Web Component library that is focused on mounting in specific areas ( DOM elements ) in your web page, bringing a simple and short list of html directive language and keeping your Javascript logic separated from your html, it means very lite bundle files.
- It's made for Island Architecture Apps & Micro-Frontends.
- It's Functional Oriented, but in the Javascript way.
- It's Event Driven.
- It's ready for Hypermedia-Driven Applications.
- It's only ~6kb gzipped.
Hypermedia Driven Applications ? How so?
Htmx boasts an extensive range of HTML attributes and pre-built event behaviors, making it a powerful tool. However, there might be scenarios where a specific behavior you’re after isn’t readily available, or you might need to take a workaround route to achieve your goal.
What would I do using Jails? Well, let’s say you want to update a list of users after a form submission:
<x-form>
<form action="/service/hypermedia/user" data-target="#user-list">
<button>Send</button>
</form>
</x-form>
<div id="user-list"></div>
The component could be something like this: ( A simple version of it )
export default function xForm ({ main, on, elm, innerHTML }) {
const target = document.querySelector(elm.dataset.target)
main(_ => {
on('submit', onsubmit)
})
const onsubmit = (e) => {
const form = e.target
const url = form.action
const formData = new FormData(form) //Needs a little work here before send
fetch( url,{ body: formData, method: "post" })
.then( response => response.text() )
.then( html => innerHTML(target, html) )
e.preventDefault()
}
}
The initialization would be:
import jails from 'jails-js'
import * as xForm from 'components/x-form'
jails.register('x-form', xForm, {})
A Jails component is just a High Order Function that gets some built-in functions in order to make your life easier then if you had to do it in plain javascript.
The above example shows the benefit of using event delegation, accessing scoped dom element, and using a dom diffing version of innerHTML in a html element.
You could write such component, document it and share with the other teams in your company, so it would not be a generalized solution but a customized module to your business.
So because it's a programatic library, you can create your own system for observability, errors handling, cross component communication using built-in pub / sub event bus.
I would be very happy to show more about the library, but let's keep it for another post. Take a look at the Jails repo, and examples if you got interested…
That's all I got for you now… Thank you for reading.
Until the next time!