Skip to content

Is Astro and htmx the future of web development?

Published: at 21:28

Examples can be found in my GitHub repository.

Table of contents

Open Table of contents

What is Astro?

Astro is a new static site generator that aims to combine the best of both worlds: the performance and simplicity of static sites with the interactivity and flexibility of dynamic web applications. It does this by allowing developers to build sites using a mix of server-rendered and client-rendered components, enabling them to create fast, interactive, and accessible web experiences.

Astro philosophy

By default, every Astro component is server-rendered, meaning that it is pre-rendered at build time and delivered as static HTML. This approach ensures that the content is available to users as soon as they load the page, providing a fast and accessible experience.

If you want to add interactivity to your Astro components, you can use client-side rendering (CSR) to fetch and render dynamic content on the client. Because Astro is framework agnostic, you can use any framework like React, Vue, or Svelte to build client-rendered components.

The downside of this approach is that it requires you to download and execute a sizable amount of JavaScript code, which can slow down the initial page load and affect the performance of your site. It also requires you to write and maintain complex JavaScript code to handle client-side rendering, which can be challenging and error-prone. Frameworks like React, Vue and Svelte are powerful, but not every project needs a full-fledged client-side framework. For many projects, a simpler, more lightweight approach is sufficient. Is there a better way?.

What is htmx?

This is the definition of htmx from the official website:

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.

What this means is that you get helper attributes that you can add to your HTML elements to make them interactive.

<input
  id="input_with_htmx"
  type="text"
  name="q"
  hx-post="/partials/search-results/"
  hx-target="#search-results"
  hx-trigger="keyup changed delay:500ms"
  hx-swap="innerHTML"
/>
<div id="search-results"></div>

Notice, we are using the hx-post attribute to send the form data to the server, the hx-target attribute to specify the element that will be updated with the response, the hx-trigger attribute to specify the event that will trigger and debounce the request, and the hx-swap attribute to specify how the response will be used to update the element.

This is the JavaScript code you’d have to write to achieve the same functionality:

import { debounce } from "../../utils/input";

const input = document.getElementById("input_without_htmx");
input.addEventListener(
  "input",
  debounce(async e => {
    const query = e.target.value;
    const res = await fetch("/partials/search-results/", {
      method: "POST",
      body: new URLSearchParams({ q: query }),
    });
    const html = await res.text();
    e.target.nextElementSibling.innerHTML = html;
  })
);

This is a simple example, but you can imagine how complex the JavaScript code would become as you add more features to your application. Htmx also appeals to backend and fullstack developers who are not comfortable with JavaScript, dislike its loosely typed nature or don’t agree with how TypeScript handles types.

There is, however, a downside to using htmx. It is not a framework, so it doesn’t provide a way to manage state, handle routing, or create reusable components. You’d have to use a separate library like Alpine.js or Stimulus to handle these features or do it on the server side.

Another downside is that it requires you to write your JavaScript code directly in your HTML, which can make your code harder to read and maintain. It also requires you to learn a new set of attributes and their corresponding JavaScript API.

Combining Astro and htmx

Astro provides a way to build static sites and dynamic web applications using a mix of server-rendered and client-rendered components, while htmx provides a way to add interactivity to your components using simple HTML attributes.

Astro 3.4.0 introduced a new feature called “partial hydration” that allows you to use client-side rendering (CSR) to fetch and render dynamic content on the client. This means that you can use htmx to add interactivity to your Astro components without having to write and maintain complex JavaScript code.

Here is an example of how you can use htmx to add interactivity to an Astro component:

search-results.astro

---
import { getLocation } from "../../utils/data.js";
import { getAddress } from "../../utils/address";
let locations: any = [];
if (Astro.request.method === "POST") {
  const formData = await Astro.request.formData();
  const query = formData.get("q");
  locations = (await getLocation(query)).results || [];
}
export const partial = true;
---

{
  locations.length > 0 && (
    <div class="dropdown">
      {locations.map(item => (
        <div class="dropdown__link__search_item">
          <div class="dropdown__link__search-item__text">
            <div class="dropdown__link__search_item__title">{item.name}</div>
            <div class="dropdown__link__search_item__subtitle">
              {getAddress(item)}
            </div>
          </div>
        </div>
      ))}
    </div>
  )
}

This code is run on the server and the pre-rendered HTML is sent to the client via an asynchronous HTTP request.

Astro and htmx seem like a great combo, but are there any other server side rendering (SSR) or static site generation (SSG) frameworks that can be combined with htmx? Yes, there are. Here are a few:

Htmx is aslo being noticed by the Golang community. Here is a quote from the official website:

htmx is a great fit for Go developers. It’s a small, simple, and powerful library that can be used to build modern web applications with the simplicity and power of hypertext.

What will happen to htmx in the future?

htmx reminds me of lodash and underscore, popular libraries that provided utility functions that were later added to JavaScript specification. I think popular htmx features will be added to the web platform in the future, and we will be able to use it without having to include a library.