David Fregoli
Projects Blog

Why I replaced Hugo with 300 lines of Go

March 15, 2026 · 1 min read

Hugo is a great static site generator. I used it for years. But when your content pipeline changes, your tools should change with it.

My content now lives in Obsidian and gets generated or translated before it hits HTML. That made Hugo a middleman in a pipeline that didn't need one:

Obsidian → generated markdown → Hugo → HTML

Two generation steps for a site with five pages. Hugo's opinions about front matter, section bundles, and taxonomy were constraints, not conveniences.

What I built instead

A Go program in the same repo as the site. It does exactly what Hugo did for me, nothing more:

  1. Walk a pages/ directory, parse YAML front matter, render markdown with goldmark
  2. Load project data from projects.yaml
  3. Build a nav tree with active states
  4. Wrap everything in HTML templates using Go's html/template
  5. Write static files to public/

The whole thing is about 300 lines across four files. It builds in under 100ms.

The template strategy

Go's html/template has a block/define system that works well for this. A base template defines the HTML shell with block placeholders. Layout templates override specific blocks:

  • page.html overrides main for generic pages
  • blog-post.html overrides wrapper for the full article chrome
  • blog-list.html and projects-list.html override main for their listings

For each page, the base templates are cloned and the layout-specific template is parsed into the clone. This prevents one layout's block definitions from leaking into another.

Multi-theme support

Since the templates are just files in a directory, supporting multiple themes is straightforward. Each theme gets its own directory under ssg/themes/, and site.yaml has a theme field. The build reads from whichever theme is configured.

A --preview flag builds the site with every available theme at once, outputting to public/_preview/<theme>/. Useful for comparing themes side by side.

Was it worth it?

For a site this small, absolutely. The build tool is simple enough to understand completely, flexible enough to add whatever I need, and has zero dependencies beyond the Go standard library plus goldmark for markdown.