Farewell Jekyll! Hello, Astro.js!

Farewell Jekyll! Hello, Astro.js!

- 6 mins

Migrating from Jekyll to Astro.js is shockingly easy. You won’t regret it.

Leaving Jekyll and Ruby

Jekyll has been my goto framework when working with static-site generators, and for years I had no issues at all. I loved the level of automation, the easy to learn Liquid template language and the flexibility. In the last two years following the upgrade to a Mac M1, however, the number of problems increased, and they have been increasingly difficult to solve. The issues has not been with Jekyll itself, but with Ruby, some selected Jekyll third party plugins and their incompatibility with different versions of Ruby. With every update of MacOS and Mac’s command line tools, I had to reinstall or upgrade Ruby, the plugins and the libraries needed by my project. A tiresome process taking away the focus on creating content. I used Ruby Version Manager to solve the discrepancy between Mac’s older version of Ruby and the actual newest stable release of Ruby. Getting Ruby working, I too often found myself fighting with Jekyll’s plugins, and after numerous cryptic error messages and endless build errors I just had enough. I had to find a better way forward.

Transitioning from Jekyll to Astro.js

Astro.js is a modern web framework designed for building fast, content-focused websites using any frontend framework or no framework at all. I did consider alternatives, like Next.js, but I wanted to be vendor and UI-library independent. Astro.js being a part of the rich JavaScript ecosystem means huge advantages and flexibility. Furthermore, Astro.js has support for Markdown files with YAML-frontmatter, making me able to copy over the content from my old Jekyll-site directly over to Astro.js with almost no change at all. Amazing!


First, head over to the Astro.js migration guide

  1. I recommend starting with a blank Astro-template. I used the one suggested by the migration guide:
    npm create astro@latest -- --template blog
  2. Add React and TypeScript, or any other UI-library/framework of your choice to your project:
    npm run astro add typescript and npm run astro add react.
    Follow the on-screen details and accept the suggested configuration.
  3. Move all the assets to the public folder and stylesheets to styles folder. I use SASS and Astro makes a very good job preprocessing, compressing and embedding the stylesheet into the build. You can also use CSS-modules or any other way of styling you prefer.
  4. To get started with the migration of your content, start by migrating your landing page. In order to get your first page up and running, you need to recreate the layout files and any other nested layouts. This is a step-by-step process where you need to rewrite your old Jekyll-includes and components to their equalling Astro and React components.
  5. Within the content folder, code the schemas representing your YAML front-matter for your blogs. This is optional, but when using TypeScript it will save you from a lot of type checking hassle.
  6. Copy your content from your old Jekyll-site into the content/blog folder
  7. Repeat step 5 and 6 for every content folder in your old Jekyll-site
  8. Create the pages and the dynamic routes your website uses. In Astro you do this through static files within the pages folder with .astro, .md, .mdx or .html files. At this step you will need to rewrite older Jekyll Liquid code to Astro and React code. More importantly, Astro does not use permalinks, so you will need to think about how you want route your pages. See Astro routing guide for more info.

During the process I rewrote

  1. Jekyll-template files => to Astro-components
  2. Jekyll-components => to reusable React and TypeScript components

The reason I did it like this, is because it makes future migration easier. Astro-components can make use of built-in Astro-functions, while the reusable React-components hold the essential UI-constructions that make up my site. I use Astro-components only for layout-specific setup and layout-specific root pages on certain routes that I can’t, and likely won’t, migrate later.

Pagination in Astro

Making a pagination component in Astro is extremely simple and easy. However, figuring out the correct typing with TypeScript can be challenging. Here is the code and the correct typing I use on this site.

You can then use this component in a dynamic page called [page.astro]:

This will produce, with the stylesheet used on this site, to this:


I experienced some minor issues within IntelliJ while migrating my code. It’s small things that are worth paying the price for, rather than troubleshooting Ruby:

  • Type checking issues: When using Astro together with TypeScript, make sure to add the appropriate types within your Astro-components. The information about getStaticPaths() types are especially important. Without proper tying IntelliJ will warn you about what it believes are type mismatch errors. This can be very confusing when following the guide and using code that otherwise is correct.
  • Astro redirection: The default setup of Astro’s redirection mechanism creates a file that uses a meta refresh of 2 seconds to redirect to an url you specify. This creates an annoying 2-seconds delayed redirection that looks like the picture to the right. For this site, I extracted as much as possible to small and reusable React-components and created static copies of the dynamic root pages (such as the pagination dynamic rout page shown above).
  • Since Astro does not support permalinks, I haven’t found a way to create alias pages for url paths that uses dynamic routes. One specific issue is for example pagination, which creates /blog/1, /blog/2 etc. but I can’t create /blog that lists the content of /blog/1 (I fixed it with shared React-components for this site).
  • JSX/React components can’t import Astro-components. But Astro-components can import other framework-specific components. This hasn’t been a very big issue, but you do need to plan and think about how it affects your routing and old permalinks used in Jekyll.


Learning and using Astro.js has so far been a great experience, and I can finally focus on my content again rather than debugging Ruby. I really like the default config of Astro, as it is tuned by default to generate a complete static-site output with correct routing.