Static Site Generators (SSG)
Programs that turn source files (Markdown + assets + templates) into a static HTML site, deployable from any dumb file server — no runtime, no database, no attack surface beyond the web server itself. The enabling technology under blogs, docs sites, and Digital gardens alike; the reason Markdown won as the authoring format.
How the family slices
- Templating model — Go-template monoliths (Hugo, Zola) vs component-islands (Astro, Next) vs layout-inheritance (Jekyll, Eleventy). The trade: template-language power vs escaping into a real language when logic grows.
- Build performance — Hugo/Zola compile-time speed (Rust/Go, sub-second rebuilds) vs the JS bundlers’ dependency graph cost. For a garden of hundreds of notes rebuilt on every commit, build speed is the UX.
- Content model — file-tree-is-the-site (most) vs graph-native (Quartz: the backlink graph is the product, not a feature).
- Data sources — Markdown-first vs headless-CMS-first vs MDX-with-components. The garden stays Markdown-first: source of truth is plain files in git, renderers are replaceable.
The generators this homelab runs
- quartz (OSS) (13.2k★, MIT, TS) — this garden (
~/projects/garden-site): turns an Obsidian vault into a published site, translating OFM at build time (wikilinks → slugged links, callouts, graph view). Chosen because the vault is the source of truth, not a CMS. - hugo (OSS) (90.0k★, Go) + chirpy theme — the blog (hugo.h.krzysztofkaminski.dev,
~/projects/blog); the hugo-blog skill carries the workflow. - zola (OSS) (17.5k★, Rust) — the test blog (zola.h.*, per the zola-blog skill); single binary, everything built-in — the Rust niche-mate of Hugo.
The wider field (repos captured, linked)
- astro (OSS) (62.9k★, TS) — “the web framework for content-driven websites”; islands architecture — ship zero JS by default, hydrate interactive islands only. The static-site-plus-sprinkles middle path.
- buildawesome (OSS) (19.9k★, JS) — Eleventy, renamed: repo
11ty/eleventy→11ty/buildawesome(the API 301-redirects; the capture SKIPs as “exists”). The minimalist counter-position: no client framework, no data graph — directory of templates in any engine → HTML. - jekyll (OSS) (51.7k★, Ruby) — the original blog-aware SSG; GitHub Pages’ default, which made it the on-ramp for a decade of blogs. fzakaria.com (Personal websites inspiration) runs bare Jekyll v4.4.1 with hand-rolled CSS — the “no theme, all typography” pole.
- gatsby (OSS) (55.9k★, React) — the cautionary tale: GraphQL data layer + React island-everything; dominated 2018-2021, then Next took the JS mindshare and Astro took the static-first mindshare. Still maintained (not archived, pushed 2026-09) but decisively lost the future — the garden’s “Gatsby lost” post thesis.
Why static (the argument worth keeping)
- Deployment: any file server, object storage, or CDN edge — the site is files. No runtime to patch, no DB to back up, nothing to monitor beyond uptime.
- Ownership: plain files in git = the Golden repo pattern applied to a website; content survives every generator death (the Markdown source outlives the tool).
- Performance: pre-rendered HTML, cache-everything; the “is a framework needed?” question answers itself for read-mostly sites.
- The cost: anything dynamic (search, auth, comments) becomes a build-time or client-side problem — Quartz solves search by shipping the index to the client (Quartz search); forms/comments go to external services or get dropped.
Open
- (open: Astro hands-on — island architecture as the “static site + sprinkles of interactivity” middle path; candidate if a future project needs embedded widgets without a runtime)
- (open: does the viz artifacts lane (viz.h) want an SSG index page, or stay hand-rolled HTML?)
- (open: write the “Gatsby lost” blog post — Gatsby lost placeholder; thesis: GraphQL-everything + React-everything was the wrong bet twice, islands beat hydration, build-time beat runtime)
Related: Digital gardens · Markdown won · Quartz search · Personal websites inspiration
The MkDocs saga: maintenance death → hostile rewrite → Zensical (2026-10-12)
USER context at capture, verbatim: “I am long time fan of MkDocs material. There has been some dramas, then maintenance issues but it served me well for couple of projects and first versions of my digital garden - thanks to Mara-Li enveloppe.ovh. Zensical seems interesting but not yet at feature parity.” All three blog posts in the saga captured (squidfunk’s own series), plus obsidian-enveloppe (OSS) (Mara-Li’s Obsidian→GitHub publisher, 909★, Apache-2.0 — the vault-to-MkDocs bridge that powered the garden’s first versions).
The timeline from the captures:
- 2024-08 — MkDocs stalls. squidfunk’s “Transforming Material for MkDocs”: MkDocs effectively unmaintained since August 2024 (no releases in over a year, unresolved issues/PRs piling up), maintainership changed mid-2024, and a ground-up rewrite began that “does not require or support plugins.” squidfunk raised objections “to no avail” and immediately started building what became Zensical.
- 2025-11 — Zensical announced. Next-gen SSG by the Material team, “distilled from a decade of experience,” built to beat MkDocs’ architectural limits. Compatibility first: natively reads
mkdocs.yml, smooth migration path, subset of plugins supported with parity in progress. MIT, sponsorware dropped, commercial lane = Zensical Spark. - 2026-02 — MkDocs 2.0 fallout. The pre-release confirms: incompatible with Material for MkDocs, no plugin system (“removing plugin support to simplify the codebase” — squidfunk’s answer: the 300-plugin ecosystem “is one of the cornerstones of MkDocs’ success”), pre-rendered-HTML navigation that makes tabs/collapsible nav “technically impossible,” closed contribution model (“maintainer-driven issues,” no community PRs), initially unlicensed (later MIT, with license-change reserved), TOML config with no migration path from
mkdocs.yml. Material 9.7.2+ prints a build warning (NO_MKDOCS_2_WARNING=1to silence).
Why forking MkDocs was rejected (the keepable architecture lesson): every plugin depends on the mkdocs package name, so a real fork means forking all 300+ plugins — “like moving an entire city at once”; import-system interception “only preserves the ecosystem on the surface” (Python has no visibility boundary, so every internal is plugin surface); and the deep problem is no model of data dependencies — plugins share mutable state at fixed sync points, making parallel builds, differential builds, multi-project coordination, meaningful caching, and fast preview structurally impossible without a ground-up rewrite. Zensical’s module system (ZAP-007) is that rewrite: modules declare reads/writes so the build graph exists.
Field updates: zensical (OSS) now 5.9k★, MIT, written in Rust (not a Python fork — a new engine); mkdocs-material (OSS) 27.6k★, MIT, the biggest docs theme alive. The SSG family portrait gains its maintenance-mortality entry: MkDocs 1.x is the walking dead, 2.0 is a different tool with the same name, Zensical is the continuity play but “not yet at feature parity” (user verdict) — the garden-relevant trio stays Quartz/Hugo/Zola, with Zensical as the watch-item for docs-lane projects wanting the Material lineage.