Happy New 2026 everyone!

This site used to run on a very old WordPress instance. It worked, but it was not kept up to date; the Cloudflare proxy likely helped prevent it from being compromised. Updating WordPress in 2026 did not feel like a good use of time, so moving the blog to a static site made the most sense. Hugo was chosen because it is relatively common for static sites and integrates well with Cloudflare and GitHub Pages.

Instead of authoring posts in the WordPress WYSIWYG editor, you create a markdown file like content/posts/my_article.md and then run the hugo command. This generates a website in the public/ directory according to the settings in hugo.yaml. The public/ directory can then be rsync’ed to the root of a web server, an S3 bucket, or a CDN.

Cloudflare Pages offers seamless integration: you add a GitHub repository and select Hugo from a drop-down menu. Pushing to the repository’s main branch triggers a build process inside Cloudflare and a CDN update for the primary domain. Creating a PR or pushing to a non-main creates a preview URL, so you can see how the site will look before making changes final. Since DNS for my website was already hosted on Cloudflare, Cloudflare Pages was the obvious choice.

Next was asking ChatGPT to write a Python script to process the WordPress export.xml using a --selected list_of_good_posts.txt file and convert all entries into Hugo posts in markdown, preserving categories and URL slugs. The WordPress content needed cleanup, so posts from the selected list went into /posts, while everything else was written into /archives.

I chose the default Hugo theme to stay on the “beaten path”, but I wanted to adjust the styling to provide some continuity with the previous version of the site. I asked ChatGPT to help adjust CSS and templates to roughly match the old site’s look. Social links in the header and a year/month-aggregated archive view required layout template overrides. This step took most of the time, over multiple iterations, as front-end work is not my area of expertise.

The next day, I looked at HN and noticed that the #2 most popular blog on HN had made the same transition—from a dynamic CMS to Hugo. Reading the comments, people pointed out a few tradeoffs: you lose comments and search, and you introduce a dependency on a specific Hugo binary version. Losing search was fine—no one used it anyway—and comments were already disabled on my site because they only collected spam. As for the Hugo binary, yes, a newer version can theoretically generate a different site from the same config and content. Some commenters suggested committing the public/ directory to Git and reviewing diffs. I’m not sure how much of a real problem this is, but I’ll deal with it if and when it comes up.

The setup is much simpler and more maintainable when you compare:

  • AWS VPC
  • VM OS setup
  • Apache and Nginx configs (I added Nginx in front of Apache for caching, back before the site moved behind the Cloudflare proxy)
  • PHP configuration
  • MySQL server and database tuning
  • WordPress settings
  • Various WordPress plugins and their settings
  • WordPress theme overrides
  • Backups
  • Cloudflare proxy configuration

with:

  • Hugo config and theme overrides
  • A copy of the Hugo binary (Hugo is Go-based; it’s a single binary with no runtime dependencies)
  • A GitHub repository
  • Cloudflare Pages integration

Finally, checking Lighthouse scores - 100% everywere, except SEO score due to a missing meta description.

Lighthouse scores after migration

The end result, after roughly a day of work, is a static site with no moving parts beyond a Git push. The setup is much simpler and more maintainable when you compare: I’m pretty happy with how things turned out.