I replaced Alpine.js in my app with this alternative 🔥

i-replaced-alpine.js-in-my-app-with-this-alternative-

Typically, things like Alpine.js are compared to frameworks like Next.js because of their advantages over them.

Now we’re diving into something far more relevant. Both modules (Alpine.js and HMPL) work directly with HTML, and both are meant to bring logic closer to markup. That makes this comparison much more grounded.

Today, we’re replacing Alpine.js in a project with HMPL.

Let’s get started! 🏎️

⚙️ From simple examples

Let’s start with the most basic clicker example. With Alpine.js, you’d probably write something like this:


  x-data
  x-fetch:clicker="{
    url: '/click',
    method: 'POST'
  }"
  x-init="$fetch.clicker"
  class="clicker-container"
>
  

Alpine Clicker

class="click-count" x-text="$fetch.clicker.data?.count ?? 0">
class="click-button" @click="$fetch.clicker">Click

It looks great and, most importantly, works. Now let’s look at the HMPL.js version:



As you can see, we have two different philosophies: Alpine.js works declaratively inside the HTML itself, while HMPL compiles templates and dynamically renders them via JS. But the interface is conceptually similar – actions tied to events, data updates in the DOM. The difference lies in control and flexibility.

Also, it would be great if you supported the project with your star! Thanks ❤️!

💎 Star HMPL ★

🔍 Built-in limitations

Alpine.js, while powerful in its simplicity, isn’t inherently built around a server-oriented paradigm. It’s a client enhancement tool meant for light interactivity, not full templating or server-side rendering. This makes it great for progressive enhancement but somewhat limiting when building applications that rely heavily on server-driven content.

Because Alpine doesn’t natively treat the server as a central part of the UI lifecycle, integrating complex request flows or handling server state often feels bolted on. Even with plugins like @alpinejs/fetch, you’re still mostly wiring client-side logic, manually coordinating fetch calls, and managing reactive state in the browser.

This client-heavy approach can get cumbersome as your app scales. Form submissions, conditional loading, dynamic content updates, all require increasingly verbose JavaScript bindings or hacks involving x-init, external methods, and nested directives. Alpine gives you control, but often without abstraction.

In contrast, a templating language like HMPL is designed with the server at the core. It embraces server-rendered HTML and fetch-driven reactivity natively. You don’t have to manually coordinate state or requests – it’s declarative, context-aware, and built for scenarios where the server and the UI work in unison.

🔗 Complex example

Let’s take a more advanced example, a registration form with loading indicator. Here’s what it might look like in Alpine.js:

 x-data="formComponent()" id="wrapper">
   @submit.prevent="submit">
     class="form-example">
       for="login">Login: 
       type="text" name="login" id="login" x-model="form.login" required />
for="password">Password: type="password" name="password" id="password" x-model="form.password" required />
class="form-example"> type="submit" value="Register!" />
x-if="loading"> class="indicator">

Loading...

id="response" x-text="responseText">

Now let’s see how the same can be done in HMPL:



With HMPL, we gain granular control. You can intercept the event, access the FormData, customize headers, control indicators, all within a declarative template structure.

📊 Size comparison

Let’s not ignore the size difference.

Alpine.js is incredibly small, and with minimal functionality it stays tiny. Here’s a quick visual:

📦 Alpine.js:

Alpine

📦 HMPL:

HMPL

So yes, Alpine lose the size game. But the gap isn’t massive — and if you’re building something more interactive or server-driven, the slight size increase might be worth the added flexibility.

Also, in a broader comparison, HMPL still performs surprisingly well:

comparison

Of course, the smaller the feature set, the smaller the final JS bundle, but that also means you’ll need to write more imperative logic outside the HTML.

✅ Conclusion

Alpine.js is a great choice for projects that need simple, inline reactivity without the complexity of larger frameworks. But in this article, I wanted to present an alternative.

HMPL offers a more modern, customizable approach to server-driven UI. If your app requires dynamic data handling, advanced request logic, or full fetch control — HMPL might be a better fit.

In the end, it’s all about the right tool for the right job.

Thanks for reading this article ❤️!

What’s your take on this comparison? Let me know in the comments!

Useful links:

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
the-first-30-days-of-your-pmo:-a-week-by-week-setup-guide-for-small-teams

The First 30 Days of Your PMO: A Week-by-Week Setup Guide for Small Teams

Next Post
your-first-pmo-toolkit:-the-essentials-you-actually-need

Your First PMO Toolkit: The Essentials You Actually Need

Related Posts