I moved my blog tech stack from NextJS to Astro

Written by Phumrapee Limpianchop on 01 Sep 2022

2 weeks ago, I embark on a journey to opting out of my blog from NextJS to Astro. Turns out the result that I got, in the end, is worth it… but you might not want to.

Part 1: Old stack

The last major migration of Riffy Blog happened 2 years ago when I move the framework out from Gatsby due to a high maintenance effort to keep Gatsby’s GraphQL magic stable over time. I chose NextJS as a replacement because of Automatic Image Optimization feature, and ability to statically generate pages efficiently.

Riffy Blog: built with Next

I mean this stack is perfect on paper but here’s a problem. My blogs only have static content, and almost no interactive components built into the site. That means every page load browser will try to load 50-100 kB of gzipped JavaScript bundles (in this case 66kB), which includes Preact/React for post hydration process and NextJS magic features, in which I don’t need any of those in my site.

So, I want to move out from Next and look for a new framework where…

  1. Still be able to do static site generation
  2. Generated site must serve JavaScript bundle as small as possible
  3. Build process should still be fast ⚡
  4. Future proof in case I want to make content interactive by using MDX.

Then I found Astro frameworks that claim it can be built static site with almost no JavaScript at all. And better news for me than that is it just released the first stable version as well.

Astro frontpage

Part 2: The pain of migrating content

I will not get into technical on how to actually use Astro frameworks. But you can quickly try it for yourself.

$ pnpm create astro@latest

At the moment, I store all of my content in Contentful. Astro provides getStaticPaths functions where you can also pass props into the pages as well. But sadly if I did with Markdown content like that, Astro does not provide any method to parse Markdown content programmatically yet. That means Astro only process file-based Markdown/MDX contents only.

That’s a real pain, so I have to write a file generator to generate Markdown files before actually starts to build Astro site.

Part 3: The pain of migrating plugins

Other than parsing Markdown and MDX contents, those contents can also be manipulated by using Remark, or Rehype plugins as well. So in my old NextJS stack, I already built custom Remark plugins to optimize an image within the content, and process iframe transformation. But to actually use it, I have to pass plugins into astro.mjs config file, which is unable to read the TypeScript file. So, I have to rewrite the plugin from .ts into .mjs with typed JSDocs instead.

/** @type {import('@astrojs/markdown-remark').RemarkPlugin} */
export const imageParser = () => {
	return async markdownAST => {
		// get image nodes
		const nodes = selectAll('[type=image]', markdownAST)

		// transform magic below

Well, that’s not a pain. The real pain is about my future proof with MDX. While I am experimenting with Astro content parsing, I found out that MDX will not call Remark plugins whatsoever. That means if I want to make interactive content in the future, I have to migrate plugins from Remark to Rehype again.

Part 4: The results

As you can see on the Astro front page, it says that the initial load of JavaScript bundles is 7kB. Well, that’s a lie…because it’s better than that!

Riffy Blog: built with Astro

4 kB!?!? Oh my goodness, it’s actually doing what it claims for. So my blog is fully HTML static, now it’s time to consult with PageSpeed Insights to benchmark the speed, and overall performance.

PageSpeed Insights

As I thought, when there are no JavaScript bundles to load then there’s nothing to block page interaction. So, we get a full Total Blocking Time score of (+30 points) when put into the Lighthouse score calculator (at the time of writing Lighthouse score V9 is being used for SEO indexing).

Other than that overall page rendering time has been reduced to under sub-2 seconds as well. And even better than that, my build time of the site has been dramatically reduced from 4 minutes to 38 seconds



To keep it short. If you already built your own static site and are already satisfied with the performance, you might not need to actually migrate your site to use Astro unless you’re really obsessed with optimizing performance.

But if you’re really obsessed with optimization, and automating impossible workloads. You might be fit to be a platform engineer. Yes, I’m hiring. DM me if interested or you can check other available jobs at brikl.com/jobs