Astro - A Framework Review
After spending 8 hours a day in React for the past few years, I admit I’m getting tired of it. I’ve begun exploring ideas for projects that don’t require a SPA framework, and maybe just embracing either a vanilla experience or as close to vanilla as one can achieve. I chose Astro for this simple personal site after some consideration.
This type of website does not require anything complex and could have been satisfied with static files served up from whatever hosting solution. Despite this, I chose Astro because I was feeling adventurous and curious about exploring CMS, something I’ve never worked with professionally. Astro was very easy to set up and get rolling with, despite my overengineering in other aspects as well, and I assume it will be something I’m glad to have in my toolbox later. Maybe.
Content Collections
I think this feature is what initially drew me in (I’ll get to islands in a second). An Astro codebase has a special directory content
that holds collections of data in markdown or JSON format. Astro provides APIs for querying collections of content, as well as describing an enforceable schema for metadata that can be provided to these files (see example below). This blog post, for instance, is just a markdown file in the blog directory of my content, and using a special [..slug].astro
file, it was pretty easy to get routing and rendering going for this blog post and future ones.
A more interesting application is that I had an idea for tagging projects in my portfolio, which as of now consists of this site. Essentially, I defined a collection of “tags” which I would consider potential tools in a tech stack I may want to later reference, but also could really be anything.
/src
|___content
|___tags
|___astro.json
|___nanostores.json
|___tailwindcss.json
These tags are then referenced via reference('tags')
in the collection schema for projects.
const projectCollection = defineCollection({
type: 'data',
schema: z.object({
source: z.string(),
description: z.string(),
title: z.string(),
year: z.string(),
tags: z.array(reference('tags')).default([]),
displayOnHome: z.boolean()
})
});
This made it pretty easy to add/remove tags on a project like so. No need to muck around with any backend services/calls, and very simple to update the tag itself or outright remove it. One future idea is to go back and add a way to search or maybe filter on tags if I get enough on this site that I feel like it’s necessary. For now, I like it as a convenient way to link to documentation and remember maybe random tech I used.
{
"source": "https://github.com/luke-hays/portfolio-site",
"description": "Source code for this website.",
"title": "lukehays.com",
"year": "2024",
"tags": ["astro", "nanostores", "tailwindcss"],
"displayOnHome": true
}
Islands
One of the most intriguing features of Astro is its concept of “islands.” Different parts of your applications can be defined as “islands” and you can use whatever framework you feel best meets your need in that island. So shove React, Angular, Vue, Svelte, future hipster frameworks, anything you want into the Astro codebase.
I struggle to find a use case for this feature on my site, and honestly, not for other sites. To me, switching frameworks sounds like a maintenance nightmare, but at the end of the documentation on this feature has the line “the secret to Astro’s fast-by-default performance story”. In any case, I’m not familiar enough to really talk much more about it.
Setup
For my own memory: I made this as easy as I could for future updates. Essentially using Cloudflare Pages and GitHub Actions as hosting and CI/CD. Ideally, I can just update content or my resume going forward if I didn’t want to add onto this site anymore. Diving slightly deeper into the stack, I feel like I always regret picking Tailwind at some point and question why I don’t just bother with CSS or SCSS. I think it’s due to missing a few things like scroll bar styles and its Grid classes feel inadequate (defining grid-template-areas, for example).
Conclusion
It’s a cool framework. I may explore its CMS capabilities in detail later. I started off by saying I was getting tired of React, but honestly, using an alternative does sort of refresh the boredom of staying in one codebase for too long.