Source: Type-safe HTML templating in Zig, by Lukáš Lalinský
In Jinja, Django or Smarty templates, a misspelled field shows up only when the page renders. zt, Lukáš Lalinský’s adaptation of Go’s Templ to Zig, turns each template into Zig code during zig build. A typo becomes a compiler error.
Templates in dynamic languages check nothing until they run. Write {u.nmae} instead of {u.name} and you learn about it from a broken page, not from your build. The author wanted the opposite: “all inputs typed and checked at compile time.”
The template looks like HTML with Zig expressions in braces. It imports your app types, for example User from models.zig, so every parameter has a type.
zt parses the template and writes Zig code that only writes to a std.Io.Writer.
The compiler checks the generated code against your structs. If something cannot be rendered, the build stops.
Call pages.HomePage.render(.{ user }, w). Output goes straight to a socket or a buffer.
The template and your types meet in one compile step.
Misspell name as nmae and zig build prints:
src/templates/pages.zig:45:43: error: no field named 'nmae' in struct 'models.User'
try zt.writeEscaped(writer, u.nmae); // pages.zt:18:31
^~~~
src/models.zig:1:18: note: struct declared here
pub const User = struct {
^~~~~~The error points at the generated code, but each generated line carries a comment with the location in the original template: pages.zt:18:31. The calling side is checked too: pass a string where HomePage expects a ?User and it won’t compile.
{!value} outputs raw HTML, so it is easy to spot.href or src are checked for dangerous schemes.std.Io.Writer.| Limit | What it means |
|---|---|
| “It won’t protect you from everything” | It removes the most common sources of XSS, not all of them. |
| “Not very mature yet” | Several people use it; the author asks for feedback. |
Lines starting with if | A line starting with if, for or switch parses as code, so text like “if you forgot your password…” on its own line is a parse error. He is considering @if, @for, @switch, as in Razor or Twirl. |
Type-safe HTML templating in Zig, Lukáš Lalinský, 11 October 2026.
Sources: the error text, the 18:31 location and the no-allocation claim come from the post above.