Alpine JS

In my last update I briefly mentioned choosing Alpine as a way to fetch the listening statistics, on the journal page. I previously used SWR, a plug-in created by the Next team. Without React I had to find a new method way. Firstly I wanted to find a lightweight library to do this, while possible I did not want the headache of writing vanilla JS, which might mean finding a compiler and adding extra build steps.

Recently I’ve been hearing lots about Hotwire, a suite of libraries that to build reactive applications using declarative markup and semantic JS. This is super interesting and an excellent example of progressive enhancement. However, I would still need to compile the JS, which means choosing a build tool etc. Ugh! Also the JS bundle is quite large for such a small application.

Fairly soon after getting hyped about Hotwire I stumbled upon a lighter, but very philosophically similar alternative, Alpine!

Alpine shares a similar declarative markup syntax, but removes the need for the separate JS controllers, everything is inline. There is also no need to install any dependency, you can simply include a <script> tag in the document head. It’s about 8kB compressed, super compact.

The Alpine documentation has plenty of useful examples to get started with, for example tabs:

<div x-data="{ tab: 'foo' }">
  <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
  <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>

  <div x-show="tab === 'foo'">Tab Foo</div>
  <div x-show="tab === 'bar'">Tab Bar</div>
</div>

For my use case I can simply store the result of a fetch in the state (x-data), then pass the data to a string. It’s also simple to add an empty state using an isLoading boolean:

<section
  x-data="{ totals: {}, isLoading: true }"
  x-init="fetch('/api/music/lastweek')
    .then(response =>  response.json())
    .then(json => { isLoading = false; totals = json })"
>
  <p x-show="isLoading">Loading...</p>
  <a href="https://open.spotify.com/user/lkemitchll"
    target="_blank"
    rel="noreferrer"
    x-show="totals.tracks"
    x-text="`${totals.tracks} Tracks, from ${totals.albums} Albums`"
  >
  </a>
</section>

I’m a big fan of Alpine and its brutalist approach, the entire functionality is laid bare in a readable and sensible format. Inspecting the source code in a browser reveals the inner workings in a readable and accessible format. No obfuscation or minified JS to trawl through. It’s also very easy to get started with, and pairs with Eleventy perfectly.

Mentions: 0

No webmentions yet 😿

Recent changes
  1. Update eleventy to v3

See all changes