Migrating Ladybird.org; from raw HTML to Astro

Ladybird.org is the main site for the Ladybird Browser Initiative, it serves as an overview of the project and it’s goals. But more importantly it required that the entire page render out in a usable fashion in a pre-alpha browser being built from the ground up. This meant no react, no fancy UI libraries, and fallbacks to keep things clean and usable before features get added.

Challenges of Raw HTML & CSS

To achieve compatibility with the early stage Ladybird browser the initial site was made of raw HTML files linked to one large stylesheet. This obviously brought some challenges with maintenance and scaling, every page needed the same header, footer, content wrapping, and meta tags added and kept in sync. On top of that adding new content required framing out HTML and setting CSS classes for a simple update post or monthly newsletter. Given that most of these posts will be written by C++ browser devs this wasn’t particularly practical for usability let alone a good use of their time.

Why Choose Astro + Tailwind?

Astro itself solved the main issue with the base HTML system of heavy repetition with no way to declare shared components such as a base layout with a header and footer, while being a drop in swap for the raw HTML that could be converted to cleaner dynamic handling step by step. Tailwind went along with this for the same reason, providing an easier maintenance experience over the hard to track behaviour of classical CSS while having complete interoperability with the existing styling allowing for a progressive migration. The final win to Astro came with it’s great MD/MDX integration with the ability to simply drop a markdown file into the pages directory and add a layout import in the frontmatter and have it all work out of the box before committing to a proper MDX system.

Migrating Content to Markdown


The migration at the start was as simple as a HTML to MD converter to get the base posts in MD and plopping them in the pages dir with a layout and some basic frontmatter for the title and description. When deciding to scale to something with proper validation that dynamically displayed the posts on the landing page and allowed custom components it was as simple as adding @astro/mdx and moving over to the src/content directory, from there the option to add zod validation over the articles for some extra compile time checks and linking default components such as a custom handler for list tags was only a few lines of code. In the end adding a new article became a simple as one mdx file, this would be validated, added to the /posts/[slug] route on the site and based off the data and type display in the news section of the landing page.

Lessons Learned

  • Raw HTML is a pain
  • The C in CSS was a poor decision
  • Astro MDX is a great experience if you want a more content oriented site it has a much better developer experience then NextJS + Contentlayer
  • You can do static site middleware using injected HTML files in compile time check it out
  • Astro makes incremental migrations from legacy HTML sites easy and convenient
  • Check it Out

  • The Site: https://ladybird.org
  • The Source: https://github.com/LadybirdBrowser/ladybird.org
  • The Browser: https://github.com/LadybirdBrowser/ladybird