From Middleman to Astro

Finding the modern JavaScript way of static sites

RÉMINO Bits

Using Middleman

Remember when Ruby was all the rage in the late 2010s, mostly thanks to the Ruby on Rails framework?

It spawned quite a few popular libraries back then. One of them was Jekyll, a static site generator (SSG), still used today by GitHub Pages, hosting countless sites on the web for free out of git repos.

Another SSG I came to like years ago was Middleman. While I found the directory structure of Jekyll repos to be messy at best, Middleman provided something cleaner. I found it easier to extend with custom helpers and layouts too.

It served well…

However, I stuck with it for maybe too long… There was no more development of Middleman, except for some occasional maintenance fixes, and version 5 never came.

But I still found it to be the simplest, most predictable SSG out there, so I persisted with it. I even made some weird jerry-rigged Middleman site template that worked with modern Sass and JavaScript tools like Rollup. (And in some cases, privately, with PostCSS.) I called it Mansite. Yeah, okay… weird macho-sounding name—yet we have “manpages”—but it was simply a portmanteau of “Middleman” and “site.”

As weird as that stack sounds, hey, it worked. It was fairly quick to just spin up a new repo, write some pages, generate them, and get it published somewhere. So, what’s so wrong with sticking with it?

Time to let go

Ruby’s ecosystem isn’t what it used to be. While Rails still pops up now and then, I haven’t touched it at work in a decade. The gems break, the updates are fussy, and rolling back is a pain. Time to move on.

I tried a few “modern” SSGs in the past few years.

First, I tried Eleventy (11ty) in JavaScript. It seemed promising… but I just find the way it works to be a mess. The documentation is all over the place. I had to make weird “passthrough copies” of files just to include some CSS & JS in my build. There’s also no built-in Sass support. Cool idea, but no thanks.

Second, Hugo. Appeared to be good, and actually quite popular. However, since it’s written in Go, I can’t use code to add helpers or middleware. The library is compiled, so all I can use to customise my site are Go templates. That reminded me of how much gymnastics I had to do with templates in Jekyll to get anything rendered the way I wanted. So, I’ll pass…

Switch to Astro

Finally, I settled on Astro. I’ve been watching it grow for a while. At version 5, it seems to have matured quite well, with sponsorship and community support.

The RÉMINO Turnpike, now made with Astro.

Last week, I converted my homepage, which I call “the turnpike,” from Mansite (Middleman + Sass + Rollup) to Astro.

If you look at it today, it doesn’t look different at all — which is the point.

There’s no one way to migrate a site to Astro, especially with the way I was generating mine. But so far, I have a good impression of the framework. Some pros and cons:

Pros

Works with JavaScript, both on backend and frontend.

✅ Made to work with TypeScript built-in, yet optional.

Built-in Sass support, if you still care about that. Though, I’m personally moving to nested CSS when possible, so Sass is starting to feel unnecessary.

✅ Support for components of any kind: native, Astro, Vue, React, Svelte, etc. Honestly, when’s the last time you saw all these getting along?

Fast startup and hot reloads.

Highly customisable, including options for where built JS files should be stored — no need to use _astro if you don’t want to.

Supports middleware. Just like Rack in the world of Ruby, Astro lets you run middleware to intercept browser requests to its web server.

Cons (or at least weird points)

No first-party i18n string support. I find Ruby i18n to be pretty on point: simple YAML files of strings for every supported locale, helpers for localisation of strings, dates, and other objects. I get that full-stack JS is another game, but some i18n integrations I’ve seen for Astro are overly complicated. That said, Astro does support i18n routes, so building whole pages in diffe