Skip to content

Jekyll to Astro: an AI-assisted migration

Published: at 06:00 PM

TL;DR: I used AI tools to move my blog from Jekyll to Astro. Cursor helped me finish in about 3-4 hours (half the usual time), and I spent $10 testing out Aider. The site’s faster and easier to maintain now.

My Jekyll blog worked fine but felt a bit dated. I decided to switch to Astro after hearing good things about how it handles Markdown and builds pages quickly. Here’s what I started with:

Blog homepage and post list Blog post

The traditional approach

I started with the Astro migration guide. It’s helpful but leaves a lot of details up to you. The community filled in some gaps with guides about migration trade-offs and URL structures. Still, it looked like a lot of manual work ahead.

Instead of doing everything by hand, I decided to try some AI tools: Aider (powered by Claude) and Cursor (also Claude).

Using Aider

I started with Aider. My first request: “Convert this Jekyll blog to Astro.” The result:

Aider homepage
Aider attempting the migration - lots of dev server restarts and changes without much progress.

The experience was frustrating. Aider kept asking to start the dev server, which blocked other input. I couldn’t guide it or course-correct beyond answering yes/no - I just watched it make decisions.

I tried again with a smaller scope. This time, I cleaned up my branch and focused on metadata conversion:

Round two with Aider - focused just on metadata but still hit some snags.

Even with the narrower scope, the automated approach required significant manual intervention. While it managed to update a few posts, I lost track of which files still needed changes and hit API throttling issues.

Using Cursor

Cursor clicked right away. The autocomplete was snappy, I could see exactly what it planned to do, and everything just felt smooth.

Cursor anticipating formatting changes while editing Python interpreter output in a blog post.

After seeing how smoothly that went, I moved on to something more challenging: the URL structure.

Check out how quickly Cursor handles the URL conversion - no waiting around, just clean transforms from Jekyll to Astro format.

The URL rewrite came together nicely:

export async function getStaticPaths() {
  const posts = await getCollection("blog", ({ data }) => !data.draft);

  return posts.map(post => {
    console.log(`Processing post: ${post.slug}`);
    
    const [year, month, day, ...titleParts] = post.slug.split('-');
    const slug = `${titleParts.join('-')}.html`;
    
    console.log(`Generated path: /${year}/${month}/${day}/${slug}`);
    
    return {
      params: { year, month, day, slug },
      props: { post },
    };
  });
}

The metadata conversion impressed me even more. I asked Cursor to “Migrate the date field and add descriptions for the blog posts” and it delivered:

Before:

---
layout: post
title: Reflections on my Amazon Career
date: 2022-06-03 07:57:01.000000000 -07:00
---

After:

---
title: Reflections on my Amazon Career
pubDatetime: 2022-06-03T07:57:01-07:00
description: "After four years at Amazon, I wanted to share what made Amazon
successful across so many industries. Here's what I learned about engineering
culture, Leadership Principles, and building customer-focused teams."
tags:
  - career
  - amazon
  - leadership
---

Not only did it handle the format conversion, it also wrote reasonable descriptions and added relevant tags. Sure, the descriptions are a bit formulaic, but when you need to update 40+ posts, it’s a great starting point.

Cost and time

The whole thing took about 3-4 hours with Cursor. In that time, I:

A manual migration would’ve easily taken 8-10 hours. Sure, I spent $10 testing Aider first, but sometimes you need to experiment to find what works.

The site’s better now - faster loads, cleaner look, and better scores on Page Speed Insights:

Final homepage Final post

For pagespeed comparison (mobile, desktop):

Original pagespeed for mobile Original pagespeed for desktop

And the new site: New pagespeed for mobile New pagespeed for desktop

Lessons learned

A few things I learned along the way:

Looking forward

AI tools aren’t quite ready to handle full migrations on their own, but they’re amazing at cutting down repetitive work. The way they’re improving, who knows - maybe in a few months this whole thing could be done with one prompt. For now though, the sweet spot is letting AI handle the mechanical stuff while you keep an eye on the overall direction.

And honestly? I’m just glad I didn’t have to write 43 blog descriptions by hand.


Next Post
In Python, Rose == 'Red', Violet is not 'Blue'