Rustの非同期ランタイムTokioを支えるCarl LercheとJulien Scholzが、フルスタックWebフレームワーク「Topcoat」を発表した。すべてのHTMLをサーバーで描きながら、型検査したRust式の一部をJavaScriptへ変換し、WebAssembly(WASM)を読み込まずにブラウザ上の状態を更新する。これはRustでSPAを再現する試みというより、サーバー中心のWeb開発へRustの型とツールチェーンを持ち込む設計だ。ただし、公式ドキュメント自身が実験段階と明記しており、「Next.jsより優れている」と判定できる測定結果もまだない。
0.1から0.5へ11日、公開直後から変わり続けるAPI
Topcoat 0.1.0がcrates.ioへ公開されたのは2026年7月16日である。Tokio公式ブログでの発表は22日、0.5.0は27日に続いた。0.1.0から0.5.0まで11日しかなく、0.4.0と0.5.0の間には41件のコミットが入っている。WebSocketとServer-Sent Events(SSE)の対応が加わり、Datastar連携とメール送信の試作も入った。レイアウトやルーターでは破壊的変更が加えられた。
41件の変更量は、安定性の証拠にはならない。READMEは「early-stage and experimental」と明記し、破壊的変更を見込むよう求めている。現段階のTopcoatは、長期運用を約束する完成品ではなく、設計の方向と実装可能性を試せるリリースである。
開発の動機も、ページ描画の速さだけを追ったものではない。Lercheは、AI支援によって新しい言語を学ぶ負担と生産性差が小さくなったと説明する。すでにRustのライブラリ、ビルド基盤、社内手続きを持つ組織なら、高水準のWebアプリにも同じ言語を使う利点が生まれるという見立てだ。Topcoatは、Rustへ移行すべきだという一般論よりも、Rustを導入済みの組織が言語とツールを増やさずに済むか、という問いに答えようとしている。
Rust式を二度コンパイルする反応性
Topcoatの中心にある $(...) は、任意のRustコードをブラウザへ持ち込む仕組みではない。マクロが限定された式を二度コンパイルし、初回HTMLを作るRustコードと、ブラウザで再実行する等価なJavaScriptを生成する。初期値はサーバーで評価され、状態を表す signal が変わると、JavaScript側の式がテキストや属性を更新する。ボタンの開閉や入力欄との同期なら、サーバーとの往復は発生しない。
データベースへ触れる更新には、二つの経路が用意されている。#[procedure] はブラウザから非同期のサーバー関数をHTTPで呼び出す。#[shard] は状態の変化をサーバーへ送り、コンポーネントを再描画して返ってきたHTML断片を差し替える。画面全体をハイドレーションする代わりに、ローカル処理は小さなランタイムへ任せ、サーバーが必要な処理だけを明示的に戻す構成だ。
したがって「WASM不要」は「JavaScript不要」を意味しない。2026年7月29日時点でリポジトリに収録されたブラウザ用ランタイムは非圧縮で18,065バイトあり、ここへ各ページの反応式とメタデータが加わる。表現できない処理には生のJavaScriptを記述する逃げ道もある。Topcoatが減らすのは、別のフロントエンド一式とWASM用ビルドを維持する負担であり、ブラウザの実行環境そのものではない。
制約は明確だ。公式リファレンスは、式が扱える型とメソッドを「小さな語彙」と呼び、現行ランタイムを「非常に実験的で、かなり限定的」と説明している。型検査はRust構文の誤りを減らせても、JavaScriptへ変換できるRustの範囲を広げるものではない。複雑なクライアント処理を必要とするアプリでは、この境界へ早い段階で突き当たる可能性がある。
「全部入り」の範囲はWebの表面に集中する
0.5.0の機能は、初期状態で有効なもの、full で追加するもの、今後の実装に分かれる。
| 段階 | 主な機能 |
|---|---|
| デフォルト | ルーティング、SSR用ビュー、アセットと圧縮、Cookieとセッション、フォントとアイコン、クライアント反応性 |
full で追加 |
Tailwind CSSと編集可能なUI部品、HTMXとAlpine AJAX、Datastar、メールとSMTP、multipart、SSEとWebSocket、Tower連携 |
| ロードマップ | 認証と入力検証、バックグラウンドジョブ、ローカライゼーション、静的書き出し、Streaming SSR、クライアント側ナビゲーション、画像最適化、デプロイ手順 |
ページから通信路までを一つのRustワークスペースへ集める範囲はすでに広い。ただし、full を選んでも運用機能がすべて完成するわけではない。セッション管理が存在することと、ログインから権限設計までの認証機能が完成していることは別である。
データ層も同様だ。公式発表は、データベースが必要なら非同期ORMのToastyを追加するよう案内している。Topcoatの full 機能にORMは含まれず、フォームから安全にレコードを更新するための緊密なToasty連携は今後の課題である。「batteries-included」は、現状ではWebの表示と通信を広く覆う言葉として読むのが正確だ。
UI部品の配り方には、フレームワークの思想がよく出ている。Tailwindベースの部品は依存パッケージの奥に隠さず、topcoat ui でアプリのソースへコピーする。開発者は生成されたマークアップと振る舞いを直接変更できる。アセットも asset! の宣言から収集し、内容ハッシュ付きURLで配信する。抽象化で全面的に囲うより、必要なコードを手元へ置いて修正できる設計である。
Leptos、Dioxus、Axumとの分岐点
LeptosとDioxusも、フロントエンドとバックエンドをRustで記述できる。Leptosはきめ細かなリアクティブ更新とサーバー関数を備える。Dioxus FullstackはAxumと統合し、SSR後のハイドレーションとWebSocket、SSEを扱う。静的生成とWASM向け展開にも対応する。ブラウザ側でもRustのプログラムを大きく動かしたいなら、両者の守備範囲が広い。
Topcoatは別の負担を減らす。HTMLとデータ取得をサーバー側コンポーネントへ寄せ、ブラウザでは限定されたRust式を変換したJavaScriptを実行する。管理画面や社内ツール、コンテンツサイトとの相性がよい。サーバーから完成したHTMLを返しながら、検索や開閉、フォームには即時反応が欲しいアプリである。クライアント側に大きな状態機械やオフライン処理を持つ用途では、制約の方が先に目立つ。
Axumとの関係は競合より階層差に近い。AxumはHTTPのルーティングとリクエスト処理に集中し、Towerのミドルウェアを組み合わせる薄いライブラリである。Topcoatはその上で、開発者が毎回選んでいたテンプレートとアセット、セッションとブラウザ更新の流れに既定値を与える。公式発表も、低水準のAPIにはAxumを使い、同じプロジェクトで併用する場面を想定している。
Next.js比較より先に測るべき三つの条件
Topcoatのリポジトリには、Next.js 15 App Router、Leptos 0.8、Axum 0.8とMaudの組み合わせで同じ商品カタログを描画するベンチマーク環境がある。比較対象はHTTPで完成HTMLを返すまでのサーバー処理で、ブラウザの操作可能時間やCSS、JavaScript、画像の取得は測らない。測定結果の保存先はGit管理から除外されており、公式のスコア表も公開されていない。少なくとも現在、「Next.jsより速い」「優れている」と結論づける一次データはない。
実運用では性能の前に二つの境界も確かめたい。第一に、現行ブラウザランタイムはHTML属性に埋めたハンドラを new Function で関数化する。Content Security Policy(CSP)の仕様では、文字列からの関数生成は unsafe-eval を許可しないポリシーで遮断される。厳格なCSPを要求するサービスは、Topcoat側の実装変更や安全な代替策が整うまで、ポリシーを緩めずに動かせるかを検証する必要がある。これは脆弱性の認定ではなく、現在の実装と配備要件の相性の問題だ。
第二に、#[procedure] と #[shard] はサーバー上のHTTPエンドポイントになる。公式リファレンスは、ブラウザから送られる引数を偽装可能な値として扱い、信用しないよう明記している。コンポーネントからサーバー側の権限確認を呼べても、入力検証と認可が自動で保証されるわけではない。
Topcoatは、RustとSSRに局所的な反応性を組み合わせられることを実証した。採用判断を変えるのは、0.5.0の機能数ではない。まずAPIが安定し、認証とデプロイ手順が埋まる必要がある。さらに厳格なCSP下で動作し、同条件の測定で開発時間と配信性能を比較できたとき、既存のフルスタック基盤と同じ土俵に立つ。
