Abandoning Wilson and migrating codepunkt.de to Astro

Header image: Italian alps with a starry sky

First iteration: gatsby

After building dozens of other websites, I created this personal site to write about software engineering in 2020. I wanted to use my go-to frontend framework, React, but render the pages of my site as static HTML for performance reasons.

The most promising static site generator using React at the time was Gatsby, which had a certain community momentum and sported a plugin system with a sizable amount of plugins. After creating the initial version of this site with it, I ran into several issues that made my experience less than ideal.

Convoluted GraphQL layer

The initial learning curve was quite steep for me, and the overly convoluted GraphQL layer put me off right from the start.

For a site like mine, the complexity of setting up and querying static data like the site’s title through GraphQL seemed unnecessary and added a layer of difficulty that felt unnecessary.

Runtime performance

Even though marketing called Gatsby blazing fast, the runtime performance of the finished site fell short of my expectations. To improve it, I added numerous plugins, many of which were third-party:

  • Use Preact instead of React (to reduce bundle size)
  • Create optimized, responsive images
  • Use Linaria for styling (compiles to raw CSS, has no runtime overhead)

Additionally, I used plugins to enable offline support using service workers, generate a robots.txt, manage SEO meta in <head>, create a sitemap, create an RSS feed, and more.

A performance problem I couldn’t easily fix with Gatsby was full hydration: To “connect” the HTML on a static page with React and make parts of the page interactive, Gatsby effectively sent all content over the wire twice: First as HTML, then a second time contained in JavaScript.

Challenges updating to a new major version

The process was quite challenging when I attempted to update Gatsby to 3.x. Many plugins I relied on were incompatible with the new major version or not yet available.

This lack of readiness among crucial plugins caused me to spend two weeks trying to upgrade, to no avail. This process was frustrating enough that I decided to call it quits and look for an alternative to Gatsby.

Second iteration: wilson

I started Wilson as a side project in March 2021. I aimed to build an opinionated, performant static site generator specifically built for blogs and documentation websites.

The main problem I wanted to tackle was changing hydration, the way static HTML is made interactive with JavaScript. This meant optimizing both what parts need interactivity (partial hydration) and when they need to become interactive (progressive hydration).

Islands architecture

“Islands architecture” is a term that Katie Sylor-Miller and Jason Miller popularized. It describes a paradigm that reduces the amount of JavaScript shipped by introducing “islands” of interactivity on otherwise static HTML. In simpler terms, it means that only the parts of the page that need to be interactive with JavaScript are made so, reducing the overall amount of JavaScript required for the page.

I implemented a simple version of the islands architecture in Wilson using Preact option hooks. The implemented version allowed hydrating islands of interactive Preact components on top of an otherwise static page - right away, when the client was idle, when a component became visible, or when a media query was matched.

Main features

Wilson was based on Vite using Preact, Sass styling, and the unified ecosystem to work with Markdown content. With islands architecture as the primary driver of runtime performance, I managed to build some other features that Wilson supported out of the box:

  • Dynamic routing (generating multiple pages from one source page)
  • Multi-language support
  • User-defined taxonomies to group content, similar to Hugo
  • Meta tag and <head> management
  • Generation of opengraph images using @codepunkt/wasm-layout-text
  • Syntax highlighting based on Visual Studio Code

Deciding to sunset my side project

A year in, I had created a GitHub org, made 1000+ commits on multiple repositories, bought a domain name and started work on the website, and asked Colin for ownership of the package named wilson on NPM, which he gladly provided me with. Wilson was reaching a maturity level that allowed me to rebuild this site with it.

I was adding finishing touches on multi-language support and wanted to tackle responsive image optimization next. However, my motivation to continue working on Wilson alone diminished, so I decided to pause development and focus on other projects.

Third iteration: astro

When I was interested in working on this blog again, a few SSG alternatives with island architecture gained traction. The most promising one was Astro, which seemed to support everything I either supported or planned to support with Wilson. On top of that, they support framework-agnostic island architecture that works with many frameworks besides just React (e.g., Vue, Svelte, Solid).

Instead of spending much time refining Wilson’s current state and publishing another static site generator, I decided to give Astro a shot!

For the first time in years, I no longer feel like I’m building my website with subpar technology. The Astro team built what I wanted to achieve with Wilson—and a much more!

My Conclusion

Abandoning a side project is okay; doing that doesn’t indicate failure. A side project’s primary value is in its learning opportunities. Whether mastering a new programming language, experimenting with a new framework, or trying to implement a new pattern, you always learn something. No matter how small, every step taken contributes to your growth as an engineer.

I’m thrilled that this site has now been migrated to Astro, and I’m looking forward to getting back into regular writing habits. The future with Astro looks promising!

Related topics

About the author

Photo of me

Software engineer building for the web since 1996. User group organiser, open source maintainer and Director UI Engineering at smartclip.

  1. LinkedIn
  2. GitHub
  3. X
  4. Threads