chromakode / astro

Astro

This weekend I replaced chromakode.com’s backend with a new static site generated by Astro.

When I first stumbled upon it, I found Astro’s marketing page quite impenetrable. It was unclear to me what it was. In brief:

Astro is a templating/component language for mostly-static content sites which uses JSX-style syntax and composition. It provides an integrated build system for CSS / JS / etc as well as support for lazy-loading JS-heavy components.

It’s a wonderful feeling to stumble upon a great new tool for a familiar problem area. For me, Astro ticked a lot of boxes, particularly:

  • A component system which scopes and dedupes CSS / JS, enabling separation of concerns and granular reuse between templates.
  • Built-in pagination.
  • Markdown flat file data source (my dir of .md files was drop-in!)
  • Low config with good defaults, yet few limitations of route structure and layout.

So, this weekend I took Astro for a spin in a long-overdue rework of my personal site.

First impressions using Astro

It’s hard to assess any tool without building a real app, so here’s my anecdata. Adopting Astro took me about 8 hours: 80% of the time was spent reworking old logic/layout, 20% learning and using Astro. This is a terrific result. It took only hour or two of tinkering to learn Astro’s concepts. From then on I made rapid progress. Here’s the resulting source.

To get this good of a component system, it used to be necessary to pull in JSX / React. YMMV, but after nearly two decades of cranking on web templating systems (even writing my own!) I personally find the ergonomics of JSX to be unmatched; particularly how un-magical the semantics are. The surprising and hard to explain thing about Astro is how it’s not React: it’s a lower level static templating system that you integrate your client stack on top of.

Astro’s component system is eminently familiar if you’re coming from a React or Vue backgound, and that’s a very good thing. Astro Components render entirely on the backend but seamlessly integrate build-time logic. Effectively, Astro is a backend demake of popular React static site generation patterns. In this respect, it reminds me a lot of Gatsby.

Astro’s DX is impressive for a project which had its first public release a little over a year ago. astro.new and its StackBlitz integration were a fantastic way to peek at project layout before starting my own. There’s a CLI flow for installing addons which walks step-by-step through each specific code change it will make. Build times are nearly instant thanks to Vite under the hood, though I ran into cases where restarting the dev server was required to reflect structural changes to Astro Components.

Mostly, the assumptions baked into Astro saved me time, but I did run into a puzzle with Markdown-driven pages that ate a couple hours. Each Markdown file specifies a “layout component” which wraps the rendered Markdown and outputs an HTML file. I also wanted to render full blog posts in the index page. Rendering them using Astro.glob() yielded a list of entire pages, multiple <head>s and all. I couldn’t remove <head> from the layout component, because the single page render needed it. I suspect it’s possible to opt out of Astro’s default Markdown routing via a parameterized route, but this feels like fighting the tool.

Overall, I’m genuinely excited about Astro’s future. I see it replacing many cases where I’d reach for Next or CRA. It maps exceedingly well to the set of challenges I’ve experienced building contentful sites. A testament to that is that the low complexity of building this site with Astro. Simplicity pays huge dividends: there’s less to learn, less to build, and so importantly, fewer details a maintainer (me) will have to piece together many years from now.

Farewell for now, “been”

This post also heralds the end of been / wake, my homegrown lifestream collector. It had a long, 12 year run. Born in the era of FriendFeed, been’s purpose was to hoover up my various activity feeds across the web and archive them into CouchDB. wake was a simple Flask web frontend which rendered been events (including markdown files) into a blog-style feed.

My hope was that by archiving activity that mattered to me (e.g. Last.fm scrobbles, Github commits, reddit comments, tweets) into been, I’d gain a durable backup of my activity across the web. In practice, I never used the data for much, and the relevance of these data sources faded. The writing has been on the wall for years: one after another, feeds broke as services discontinued them or added API key requirements.

This is perhaps emblematic of a web that’s become less syndicated and much more centralized, and social spaces which are less public. I’m looking forward to the next swing of the pendulum.