What I Like About Astro
Tags: astro, performance, jamstack
Published: 2023-01-22 03:26:29

---
title: What I Like About Astro
published: true
date: 2023-01-16 05:00:00 UTC
tags: Astro, performance, jamstack
canonical_url: https://macarthur.me/posts/what-i-like-about-astro
---

This site’s been on Next.js since 2021, and I’ve had very few complaints about it. I’ve appreciated things like its slick developer experience, the first-class support it enjoys from Vercel for features like incremental static regeneration, and the constant innovation driven by its community. It’s a great tool, and my high view of it hasn’t really changed since I first took it on.

But in the meantime, a couple of things started to happen. First off, I began to feel more uncomfortable with the amount of JavaScript I was shipping for a very small amount of interactivity on my site (it’s mainly just content). In terms of standard performance metrics, Next does a great job at generating a fast experience by default. The built output loads assets in the right way, at the right time, and with the right priority. But even so, it still comes with a lot of code that users needs to download, parse, and execute, even though they’re only there to read a blog post. “Irresponsible” is too strong of a word, but the feeling I started to foster was in that same vein.

Second, the tooling landscape changed (as it always does), and Astro came onto the scene. It promised a lot of the ergonomics Next offers, but even more flexibility (you can use any mainstream framework you want while also shipping no JavaScript by default). It touted some big value propositions, but it wasn’t a bandwagon I immediately joined.

But after many months of waiting for the hype to cool down, I decided to try building an integration for [JamComments](https://jamcomments.com/). I was floored by how easy it was. So, I took the next step and moved over my entire site. As I made that migration, I began to mentally organize some of my favorite things about the framework. Here they are. Keep in mind, these items don’t take into account the breadth of what Astro can do. It only considers what I encountered in migrating over my personal blog.

## #1. It supports extremely unopinionated data sourcing.

I was a victim of the Gatsby.js hype a few years ago. It was one of the first React-based static site generators with some momentum behind it at the time, and it also went all-in on using GraphQL as the protocol that supported its “[content mesh](https://www.gatsbyjs.com/blog/2018-10-04-journey-to-the-content-mesh/).” These bold opinions and big words wooed me and several others, making us completely blind to the overabundance of complexity the approach brought with it. It didn’t take long for the excitement to wear off and the overbearing friction to become apparent.

Next was better. It didn’t care about how you sourced your data, so long as you did so using hooks like `getStaticProps()` within a file that exists inside the `pages` directory. (This was before the entrance of React Server Components and Next 13+ that permits you to [collocate your components & data fetching](https://nextjs.org/docs/data-fetching/fundamentals).) Still, there were some moments when I wished I could break free from those constraints a bit.

Astro takes it multiple steps further, however. There’s no particular function I need to export. In fact, I don’t need to use a separate function at all — top-level `await` is [supported out-of-the box](https://docs.astro.build/en/guides/data-fetching/#fetch-in-astro). All I need to do is set my variables and use them in my template. Done.

```
---
const response = await fetch('https://an-endpoint.com/api');
const data = await response.json();
---

<p>{data.a_property}</p>

```

Crazily enough, you can even do stuff like this (stolen straight from [their documentation](https://docs.astro.build/en/reference/directives-reference/#sethtml)):

I imagine many don’t find this prescriptive enough. There are probably very good reasons to be wary of the risk this introduces for shooting yourself in the foot. But for a dude just looking to build a simple blog, I highly appreciate this freedom.

## #2. There’s first-class (or readily available) support for integrations to take care of the boring stuff.

It’s easy enough to spit out some posts and pages. That’s the fun part. But if you’re going to build a site that’s syndication-ready, SEO-friendly, and as fast as possible, you also need worry about things like RSS feeds, sitemaps, and asset optimization. In my opinion, these are pretty boring processes to set up.

These are things that Gatsby, with its rich ecosystem of plugins, does well. If it doesn’t have an official plugin available, there’s likely one supported by the community at large. I recall relying on these plugins for [my sitemap](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sitemap), [image optimization](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-image), and [RSS feed](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-feed) with little issue. And for the things they didn’t directly support, there was often dedicated documentation on standing it up on my own. Like [how to build an SEO component](https://www.gatsbyjs.com/docs/how-to/adding-common-features/adding-seo-component/) for my blog.

Next, however, has some room for improvement. To be fair, I don’t believe Next has ever billed itself as a content-focused framework to the same degree as Gatsby. At any rate, I remember it being more than trivial to get my site going with these must-haves. I ended up rolling my own [sitemap](https://github.com/alexmacarthur/macarthur-me-next/blob/main/scripts/generateSitemap.ts) and [RSS feed](https://github.com/alexmacarthur/macarthur-me-next/blob/main/scripts/generateRssFeed.tsx) (with the help of a couple other dependencies), and I believe I built [my own component to handle basic SEO configuration](https://github.com/alexmacarthur/macarthur-me-next/blob/main/components/meta.tsx) after seeking inspiration from some other blogs.

Doing all of this with Astro was pretty darn straightforward. It has official support for things like [generating a sitemap](https://docs.astro.build/en/guides/integrations-guide/sitemap/), [exposing an RSS feed](https://docs.astro.build/en/guides/rss/), and [optimizing images.](https://docs.astro.build/en/guides/images/#astros-image-integration) And for stuff like managing SEO meta data, some [pretty good open source packages](https://github.com/jonasmerlin/astro-seo) exist. In the end, there wasn’t much pain in setting up these non-negotiables.

## #3. It’s really hard to write an unperformant site.

This is where Astro really shines. By default, there’s no JavaScript shipped to the client for an Astro site. Coming off of multiple React-based frameworks from the past few years, it’s still a little bonkers to me that I get to keep the ergonomics of writing modular components, but without consequence to the user.

In fact, I’ve been so happy with the feel of [Astro’s proprietary component syntax](https://docs.astro.build/en/core-concepts/astro-components/), that I’ve been using them exclusively. The learning curve was minimal, especially since it’s so heavily inspired by React’s API. As I built out the pieces of my site, I came to truly realize how much I didn’t enjoy writing _React_ so much as I liked the _mental modal_ that React’s adopted. With any given Astro component, I get all the benefits of writing basic presentational components — a bit of logic, a templating system that I like, and even props. But unlike React, _none_ of that code results in any more JavaScript being shipped to my users. And that makes it _really hard_ to build a slow, bloated site.

But there’s more available in Astro to aid in strong site performance too. It’s been really pioneering its [“islands” architecture](https://docs.astro.build/en/concepts/islands/), which allows you to easily opt into client-side interactivity on a per-component basis. But even if you don’t go that route, you’re free to use a good, ol’ `<script>` tag in any of your components. [Each of them will be automatically hoisted](https://docs.astro.build/en/guides/client-side-scripts/#using-script-in-astro), deduplicated, and optimized on build. So, where interactivity is needed, it’s easy enough to sprinkle it in without a huge impact to your bundle. You get the banana without the gorilla.

## #4. Much of the API is built on web standards.

This is a smaller one, but still something I really admire. Much of Astro’s lower-level API is based on web standards, which makes the learning curve a little smoother. For example, the `Astro.request` object is just an [instance of Request](https://docs.astro.build/en/reference/api-reference/#astrorequest). You can freely use `fetch()` for [retrieving any data](https://docs.astro.build/en/guides/data-fetching/#fetch-in-astro). Its [server-side rendering mode](https://docs.astro.build/en/guides/server-side-rendering/#response) depends heavily on basic Response objects.

For my migration, I didn’t use these a whole lot. Even so, in a world where frameworks run rampant and so many tools are introducing new DSLs and syntax, it’s refreshing to have something so fundamental to the web remain consistent.

## Honeymoon’s Not Over Yet

This post will likely need an update at some point, because I’m admittedly still in the honeymoon phase. So far, there really hasn’t been much of what I’d like to see changed or introduced (aside from [built-in support for parsing remote Markdown](https://docs.astro.build/en/guides/markdown-content/#fetching-remote-markdown)). But that’ll undoubtedly shift as my site does. That said, I don’t recall feeling quite the same way about first adopting Gatsby or Next. For both of those tools, despite enjoying the experience and being generally pleased with the result, I always felt a tinge of guilt at the end of the day, mainly because I knew there was so much code being sent on every page load that my site didn’t really need.

So, yes, I could be caught up in a haze of hype as I continue to dive into Astro. Or, maybe it’s actually a tool that has finally struck a good balance between developer experience and build quality. Time will tell.