All Articles

Escaping Gatsby, and moving to Eleventy

A common saying is that switching JS libraries or frameworks is a rite of passage and often just a form of procrastination. Conveniently, I was immune to that flavor of putting things off by the lack of any front-end skills. So I kept going with Gatsby powering my blog.

However, Gatsby is a poor piece of software and an even worse fit for running a personal blog.

Gatsby and Lumen

A few years ago, I picked Gatsby on a whim. I saw someone else’s blog powered by the Lumen theme, and I liked the clean, modern design. I knew nothing about Gatsby, but I could get started quickly. Lumen offered everything I needed to write Markdown, push to Github, and have Netlify render it momentarily.

I implicitly bought into a promise that I could treat Gatsby as a large black box that I would use with minimal maintenance of occasionally upgrading Gatsby and Lumen to the latest versions. Gatsby doesn’t have a great story around themes that act as extensions; Gatsby provides starters instead which are project templates. Lumen is a starter, so it’s easy to set up the blog, but it offers no help keeping Gatsby up-to-date. Gatsby’s themes implement a flypaper product adoption technique.

Gatsby: overengineered mess

I didn’t know much about the front end, so I was oblivious that Gatsby is built on top of React and GraphQL. Don’t get me wrong - both are excellent pieces of technology for the problems they’re trying to solve. React is great when you’re building a rich UI on the web and need to handle complex state <> view relationships. It was made precisely for that. GraphQL solves the problem of waterfall requests, where a result of one request generates a subsequent request.

Gatsby uses React to render static pages - there’s no complex state <> view relationship to manage. Gatsby uses GraphQL internally and locally; there’re no request waterfalls to solve.

You could say so what. Use React to tap its rich ecosystem of components, and GraphQL is a convenient query language for a unified data layer that Gatsby builds out of Markdown files, CMSes, etc.

However, pulling in these two complex software universes makes a static site generator blow up in complexity and fragility. This is where problems arose and persisted, swallowing my time into a black hole of debugging mysterious breakages in JS packages I had never even heard of. By the time I fixed these problems, I would run out of time to write.

This cycle would repeat itself every 2-3 months, and I finally had enough. Funnily enough, I wanted to show an example of the latest papercut, but by the time I finished porting my blog, the abstruse Gatsby/GraphQL build error had gone. Why? Who knows, but I suspect an upgrade of a Homebrew package that fixed it.

To be clear, this is not a criticism of the Javascript ecosystem but more of a sky-high tower of complexity that Gatsby built for a relatively straightforward problem of rendering static content.

Choosing another platform

The next obvious choice was Hugo. Yet, my experience with Gatsby taught me I couldn’t be entirely oblivious to the framework’s language ecosystem. There’s always some obscure native dependency that breaks. And for better or worse, I got rather proficient with the JS ecosystem, and I don’t mind learning it more because I’ve been moving from building technology to building products.

While Googling around, I kept seeing praise for Eleventy from builder-type people. The “a simpler static site generator” pitch sounded really appealing after being burnt by the overengineered mess of Gatsby.

What I liked about Eleventy is its low-touch approach. You can get your head wrapped around how Eleventy works in 20 minutes and be confident there’re no hidden layers. It has a data-first design heavily inspired by Jekyll, the OG of static site generators.

Another notable praise for Eleventy is its speed. This site builds in less than a second on a cold start.


I used eleventy-base-blog and copied my Markdown files. Eleventy is very flexible, and I could bend it to understand the content structure I had in my Gatsby project. Once I got a dopamine rush from rendering my content, I refactored it to fit Eleventy’s directory and file name defaults.

The more significant challenge was migrating the Lumen theme to Eleventy. For a brief moment, I considered using a community Eleventy theme, but I didn’t find any theme I liked aesthetically. Eleventy seems to attract more of the DIY/builder crowd than great designers. The look of Eleventy’s homepage doesn’t help.

As I mentioned, my front-end skills were pretty much non-existent. However, I kept hearing about AI-enhanced development and decided to try it on the Gatsby -> Eleventy theme migration. I also wanted to learn the basics of Tailwind, so I decided to port the Lumen theme to Tailwind classes. If you’re reading this sentence, you’re reading it rendered through a combination of TailwindCSS and its prose plugin. I’ll write about the process and my impressions in the next post, but it’s needless to say, I’d never venture on such a project in a completely unfamiliar territory without ChatGPT. And it’s been a blast!


If there’s one thing I’d love to see improved the most, it’s Eleventy’s image handling. Eleventy comes with no special handling of images, so one has to figure out how to optimize images manually. There’s the eleventy-img official plugin, but I found configuring and using it confusing. I spent roughly 40% of the time migrating to Eleventy, figuring out what to do with images. I wish Eleventy would match Gatsby’s image optimization out of the box.

All in all, migrating to Eleventy has been a success. I no longer fear my blog will break unexpectedly, precisely when I want to publish a post. And I plan to publish more often!


Deep Learning ∩ Applications. A recent pivot from a 'promising career' in systems programming (core team behind the Scala programming language). Pastime: Ambient Computing. Grzegorz Kossakowski on Twitter