世界を動かす技術を、日本語で。

Zigにおける型安全なHTMLテンプレーティング

2026年10月12日原文(lalinsky.com)

概要

  • 2000年頃からWeb開発 を経験し、様々なテンプレートエンジンや言語を試行
  • Zig言語向けテンプレートライブラリzt を開発、型安全性と高速性を重視
  • HTMLエスケープやXSS対策 がデフォルトで組み込まれている
  • テンプレートエラーはZigのコンパイルエラー として検出可能
  • Dustyやhtmxとの連携 でSPA開発も可能

20年以上にわたるWeb開発経験とZigへの転機

  • 2000年頃からWeb開発 に従事、PHP 3.0リリース直後から活動開始
  • HTML生成手法 として、生PHP、Pythonの文字列連結、Smarty(PHP)、Template Toolkit(Perl)、Jinja/Django(Python)などを活用
  • SPAやJavaScriptフレームワークの台頭 以降、フロントエンドから一時的に離脱
  • 2年前にZigを習得 し、低レベル言語でもWeb開発が現実的であることを発見

ZigでのWeb開発とテンプレートエンジンへの要望

  • zioやDusty など独自エコシステムを構築、APIバックエンド向けにJSONやMessagePack出力を実装
  • アリーナアロケータの活用 により、文字列のメモリ管理が容易に
  • Zigのcomptime機能 で高レベルなインターフェースと高パフォーマンスを両立
  • htmxやDatastar により、JavaScript/TypeScriptを使わずにSPA構築が可能
  • テンプレートエンジンには以下の要件 を設定
    • 型安全性:全入力がコンパイル時に型チェック
    • 高速性:アロケーションなし、中間状態なし、std.Io.Writerへ直接出力
    • セキュアなデフォルト:XSS対策として全入力をデフォルトでエスケープ
    • HTMLライクな記述感:Zig独自DSLを強要しない

ZiexやTemplから着想を得たztの誕生

  • Ziex(Zig向けJSXライクテンプレート) の存在に驚愕
  • GoのTempl を参考に、Zig向けにアダプトした zt を開発
  • テンプレートはzig build時にパース・トランスパイル され、アプリコードから直接import可能
  • テンプレートとアプリの相互import が可能で、パラメータは完全に型安全
  • 生成コードはstd.Io.Writerへの出力のみ、バッファやソケットへの柔軟な書き込みが可能

ztテンプレートのサンプルと特徴

  • テンプレート例 (Userモデルを利用したLayoutとHomePage)
    • Zig構文とHTML記法を融合
    • @childrenによるレイアウトの継承実現
  • Zigコードからの呼び出し例
    • 型安全な引数渡し
    • 出力先の柔軟な選択(バッファ、stdoutなど)
  • Dustyとの連携 でHTMLページのレンダリングも容易

セキュリティと型安全性の徹底

  • 全動的値はデフォルトでHTMLエスケープ
    • テキスト・属性ともに自動処理
    • hrefやsrc属性は危険なスキームをチェック
    • 生HTML出力は{!value}で明示的に指定
  • 全要素の閉じタグ必須 で壊れたマークアップを防止
  • テンプレートエラーはZigのコンパイルエラー として発見可能
    • フィールド名のtypoや型不一致も即時検出

コンポーネント化と制御フローの柔軟性

  • 再利用可能なコンポーネント や @childrenによるレイアウト継承 が可能
  • if/for/switch等の制御フロー はZigそのままの構文で記述
  • すべての処理はstd.Io.Writerへの逐次書き出し、アロケーション不要

現状の課題と今後の展望

  • 制御フロー構文の曖昧さ (if, for, switchの行頭記述)については改善検討中
    • RazorやTwirlに倣い@if, @for, @switchの導入を検討
  • プロジェクトはまだ未成熟、フィードバックやバグ報告を歓迎
    • GitHub issueやZig Discordでの連絡を推奨

まとめ

  • Zigにおける型安全・高速・セキュアなテンプレートエンジンzt の紹介
  • Web開発の新しい可能性 として、低レベル言語でも快適なテンプレート記述体験を実現

Hackerたちの意見

そのアイデア、めっちゃいいね!他の言語でも似たようなものが作られるのを想像できるよ。例えば、Djangoで再利用できるテンプレートの形で書かれて、JSのReactフロントエンドと組み合わせる感じかな。tsxが提供する型安全性も活かせるし。

└

これはtsxとElixirのEExの中間みたいな感じだね。

└

Kotlinの型安全なDSLについて https://kotlinlang.org/docs/type-safe-builders.html

└

Ur/Webの型安全なXML/HTMLはエレガントだと思ってた。詳しくは、http://www.impredicative.com/ur/demo/を見てみて!

└

nimにもこれがあると思うよ。Djangoについては…まあ、Djangoはテキストフォーマットしかないから、適当なゴミや壊れたHTML、無効なテンプレートをたくさん書けちゃうんだよね。静かに失敗することも多いし、残念だよ。

└

みんながこぞってmustacheをテンプレートシステムとして使ってた時期があったけど、結局はクロスランゲージのテンプレーティングってあんまり役に立たないから、すぐに廃れちゃったよね。ホスト言語を切り替えることってあんまりないし、テンプレートはそのまま使うことがほとんどだから。

└

最近、長年の蓄積されたフラストレーションを解消するために、テンプレート言語(実際にはドキュメント用の中間言語)を作ったんだ。すでに4、5のプロジェクトに追加済み(HTML、メール、ダッシュボード、チャットボットのメッセージ、いくつかの設定用)。デザインポイントは「決定論的でホスト可能、テンプレートからフックを作るのに十分な機能」が特別なところだね。

W3C: なんでこれをやって終わりにできないの?

└

これに興味があるかもね https://github.com/WICG/declarative-partial-updates

└

いいアイデアだね! https://web.dev/articles/imports それやったことあるよ。2014年に導入(Chrome 36)、2018年に廃止(Chrome 70)、2019年に引退(Chrome 73)したんだ。

└

SGML(ISO 8879)は、HTMLの基盤となるマークアップメタ言語で、型チェックされたテンプレーティングなど、他にもいろいろな機能があるんだ。だから、SGMLの機能を使うだけのHTMLは独自のアドホックなメカニズムを定義する必要がなかったんだよね。ちなみに、その構文もSGMLから派生してる。SGMLの用語で言うと、これは「処理命令」であって「エンティティ参照」ではない。後者はコンテンツのインクルージョンの基本的な手段だからね。

└

iframeを紹介してもいい?ちょっと不格好だけど、君が求めてることをちゃんとやってくれるよ。

Hacker Newsで議論の続きを見る