Rewriting My Astro Blog with Eleventy

I have been a huge fan of Astro ever since it launched. I was an early adopter and that meant as Astro learned its footing I would constantly face breaking changes. That was fine, but after a few years, it became less understandable. So when Astro decided to end 2024 with version 5 they decided to introduce yet another new breaking change. The documentation explaining how to adapt was incomplete and not helpful. They had a way to preserve compatibility but I know what that means: delaying the inevitable. Besides, I had already gone through enough, it was time to leave.
I had heard of 11ty from a lot of people I respect and I didn't know anyone using Astro. Hell, one of my favorite mentor's photos is at the bottom of every 11ty documentation page. That is a pretty good endorsement. My wife's favorite animal, the possum, is 11ty's mascot. Another good sign. The way 11ty works is quite new to me, so it took a lot of endurance to get accustomed to it. At different parts of my journey, I would briefly consider a hosted blog solution, but lol, I had just gone through the shit with a particularly transphobic blog host last summer. Never again.
Okay, so, let's dig into what I did and what my pain points were. I tried to map out all the features of my blog and what I could improve or upgrade. I was trying to find a good way to do PostCSS with Autoprefixer. I didn't see any ways to do this that didn't repulse me, but I did learn that the beta for TailwindCSS v4 has CSS auto-prefixing built in. So I took this to bring my JavaScript-based Tailwind config to a CSS-based config. It was challenging at times, but ultimately I feel good about it.
My main pain point with 11ty was learning where all the variables live. Would the data I need be in {{ page }} or {{ post }} or somewhere else? Is the front matter exposed like {{ title }} or do I need to do {{ page.title }}? Getting that right was frustrating. Knowing where I could use variables and where I couldn't was another issue.
Sometimes, variables can be used in the front matter, but sometimes, they can only be used under a eleventyComputed definition. Here's a case where the title is valid, but if I put it in the root where you normally would, I couldn't get it to work. Why does permalink work?
---
permalink: "{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber + 1 }}/{% endif %}index.html"
eleventyComputed:
title: "{% if pagination.pageNumber > 0 %}Page {{ pagination.pageNumber + 1 }}{% endif %}"
---
I'm sure I could figure out exactly why, but I figure I will learn over time. I kept hoping I would have more access to the {{ metadata }} object in places where I couldn't. I wonder if it would be possible to expose all the variables accessible (and where) for an 11ty dev tool browser extension or something?
11ty has grown fast over the last five years. It makes finding out what the current best practices are hard. In trying to preserve the functionality of my features like "see a list of link posts pointed to a domain" or "paginate through many posts tagged with a specific tag" I realized that the built-in pagination feature of 11ty wasn't going to save me. This is, apparently, called Double Pagination and this blog post by Desmond Rivet helped me figure out what I needed to do: program my own custom collection definitions. Luckily, a lot of the code I wrote to do this with Astro just copied over with almost no changes needed.
The best part of 11ty I've found is how images are handled with their image plugin. It's neat because it works like how I would have wanted Astro or NextJS to handle them: by asking very little of me. Unfortunately when I was playing with deployments, converting to avif image files took over 5 minutes and took my entire VPS offline before the process was eventually killed. I wasn't using avif with Astro either, so no real loss.
Let's talk build times. 11ty loves to talk build times. My Astro blog took around 1 minute to build, while the 11ty version takes around 50 seconds. That's not a huge difference from Astro. The 11ty performance page seems to show around 11x performance gains on markdown builds, a far cry from my ~1.2x real performance gain, but I'm doing more than just building 4000 random markdown files. And who knows, maybe I could, god forbid, fix my code to help speed things up.
The best part about the change is that I only needed to change one of my markdown files. An old post with a JSX code block was causing my build to break. I didn't find any of the errors to be helpful, but thanks to Robb's help I was able to fix it by wrapping that code block in a Nunjucks raw tag so it would know not to try to make sense of my code.
Speaking of code blocks, since Prism works well with 11ty, I decided to make a mashup of Catppuccin's latte and mocha themes for Prism so they change with the user's choice of dark or light mode.
Ultimately, I'm happy I'm on 11ty now. Zach Leatherman sounds like a great maintainer. Thanks to Bob Monsour for showing me The Stability of Eleventy, a post about how they have successfully avoided breaking changes for years.
As always you can see the code! Let me know what I should fix or what I should do better on. I would love to hear from you.