From Quartz to Zola, bypassing Hugo

I just transferred my knowledge base over to Zola. The starting point was Karpathy’s knowledge base post from April 2, 2026. Initially I built locally and viewed with Obsidian. Wanting a public view, I used Quartz which was very easy to set up. I started looking for alternatives when builds took over 4 minutes and 3 GB memory on 1000+ pages.

I chose Zola as a clean minimal alternative to Hugo. Zola and Hugo had equivalent build times in testing. Only Zola has native backlink tracking. And PR#3116 has wikilinks support. To extend Hugo, I considered writing a separate compatibility layer in Rust. Since Zola is written in Rust, I can extend it directly. Also the community feels like something I can contribute to, since the PR states they’re looking for testers.

I started on the next branch, merged PR#3116, and added a few things along the way, all of which went quite smoothly. What worked well, what did I change, and what did I add?

What went well

  • All of my existing tags, and a few obvious improvements, fit well under the taxonomy system
  • Customizing the theme to my liking was super easy
  • Cloudflare deployment was a snap

What I tweaked

  • Disambiguation suggestions when a duplicate is found (I have 3)
  • Let wikilinks point to aliases and allowlisted missing pages
  • Allow markdown to render hard breaks, for single-line transcripts (optional)

What I added

  • Self-fragment links such as [[#details]]
  • Ability to link to colocated assets and taxonomy terms
  • Relative paths like [[./sibling]] and [[../parent]]
  • Opt-in asset allowlisting and output-size limits

Non-static stuff

I also moved away from Quartz’s FlexSearch static search, to avoid a 6.3 MiB index (decoded to 18.21 MiB). I switched to D1 FTS5 search on the same Cloudflare worker that serves the site. It’s about twice as accurate and fast. I got Zola to build the JSONL search corpus in a second pass over its already-rendered article HTML. This could probably be folded into the rendering pipeline as a single pass.

Nice! I’ve replied on the wikilinks PR for the link related parts.

I didn’t know this was a pulldown-cmark option, I think we can expose it.

Any other issues with Zola or Tera?

1 Like

Other than the cachebust issue you already fixed, Tera has been smooth. The only real gap I found is around internal/alias.html. A site-level override works and I’m using one. But the source says it isn’t overridable and I couldn’t find that behavior documented. It might be worth making the override contract explicit and testing it.

:thinking: it’s probably years old if you go past the tera2 changes, not entirely sure.

It’s working now because of tera2 fallback prefixes, I don’t think anyone has wanted to override that one before? What are you changing?