Comparison
How astwerk differs from Hugo, Zola, Eleventy and Astro — and when one of those is the better choice.
This is a static-site generator among many. The honest comparison is against the ones people reach for first, on the axes that actually change a build: how content is described, what the template language is, and what client-side interactivity costs.
The short version
Choose astwerk when the team already writes Go, the templates should be type-checked at compile time, the site's structure should live in code rather than a directory convention, and interactivity shouldn't pull in a JavaScript toolchain. Choose Hugo, Zola, Eleventy or Astro when you want a theme ecosystem, a component framework for islands, or builds at a scale where incremental compilation matters.
At a glance
| astwerk | Hugo | Zola | Eleventy | Astro | |
|---|---|---|---|---|---|
| Language | Go | Go | Rust | JS/Node | JS/Node |
| Templates | templ (compiled Go) | Go html/template |
Tera | Nunjucks/Liquid/JS | .astro (JSX-like) |
| Site structure | a Node tree you write |
convention: content/ + layouts/ |
convention: content/ + templates/ |
convention + config | file-based routing in src/pages |
| Content discovery | explicit, via Generate |
directory scan | directory scan | directory scan | directory scan |
| Client JS | Go → WASM, opt-in | none built in | none built in | none built in | islands, any framework |
| Config format | none — Go struct literals | TOML/YAML/JSON | TOML | JS/JSON | JS/TS |
| Toolchain | go + templ CLI |
single binary | single binary | Node + npm | Node + npm |
Where astwerk is a good fit
You already write Go, and want the type checker on your templates. templ
components are Go functions — a typo in a variable name is a compile error, not
a blank spot in production. Hugo's html/template is Go too, but its templates
are strings interpreted at runtime; a bad field access there fails at build
time at best, in the browser at worst.
You want the site's structure to be code, not a directory convention the
generator infers. Hugo, Zola and Eleventy all work by scanning content/
and matching it against a layout by naming convention. That's fast to start
with and awkward to deviate from — an unusual routing need means fighting the
convention. A Node tree has no convention to fight; it's a Go value, so
anything expressible in Go is expressible in the tree, including a Generate
that computes children from an API response or a database query at build time.
You want interactivity without adopting a JS framework. Astro's islands
are the closest comparison — ship JS only where a component needs it — but the
island itself is still React, Vue, Svelte or similar, with that framework's own
build step. astwerk's interactive paths are x — compiled markup,
plain JavaScript at build time, no framework at all — and reactive, Go
compiled to WASM: one language, one toolchain, no npm install divergence
between the static and interactive halves of a page.
Where something else is the better choice
You want a plugin ecosystem and a theme marketplace. Hugo and Eleventy both
have large ecosystems of drop-in themes and shortcodes. astwerk's starter/ is
seventeen files you copy and edit — there is no marketplace, and there is not
meant to be one. If "install a theme, change the logo" is the whole
requirement, Hugo will get there faster.
You want Go on the client and nothing else will do it as cheaply. This one
needs a correction, not a caveat: astwerk does not require WASM. A page with no
CompileFrom node ships exactly as much client JS as a Hugo or Zola page — zero
— and CompileScripts hands .ts files to tsc in the same build step, so a
script written in plain JavaScript or TypeScript costs nothing beyond what it
would cost on any other generator. The ~2 MB WASM floor is real, but it's the
price of one specific choice — writing that script's logic in Go and running
reactive or wasmwrap — not a tax astwerk levies on every page. Reach for it
when the interactive logic is substantial enough that sharing a language with
the rest of the site pays for the runtime; reach for a <script> tag or a .ts
file, same as anywhere else, when it isn't.
The team is already fluent in JS/TS and wants component-level islands across
multiple UI frameworks in one project. That's Astro's specific strength —
mixing React, Svelte and Vue islands on one page — and it isn't something
astwerk is trying to do. reactive is one small, fine-grained state library,
not a place to plug in an existing component framework.
You need incremental/parallel builds for a very large site (10k+ pages). Hugo in particular is tuned hard for this. astwerk's walker is a straightforward depth-first recursion with no incremental cache — every build is a full build. For most project sites and docs sites that's unnoticeable; for a large content site it's a real gap (tracked as a possible improvement, not solved today).