TL;DR — Fitz LiveViewsFitz向けのリアルタイムUIフレームワークです。Fitzはコンパイル済みの段階的型付け言語で、HTTP、WebSocket、認証、ORMが構文に組み込まれています。単一ファイルコンポーネント(.fitzv)をstate / event / <template>で記述し、サーバーがHTMLをレンダリングし、差分を計算してWebSocket経由でブラウザにパッチを適用します — JavaScriptビルド不要、クライアントフレームワーク不要。同じ.fitzvはWebAssemblyにもコンパイルでき、オフラインでゼロラウンドトリップのウィジェットとしても動作します。ライブコンポーネントギャラリー、コース、完全なフラッグシップアプリ(認証+Postgres+Dockerを備えた管理パネル)がすでに構築されています。 リポジトリgithub.com/Thegreekman76/fitz-liveviews · ドキュメントthegreekman76.github.io/fitz-liveviews

これはFitzLiveViewsシリーズの最初の記事です。まずコンセプトとセットアップから始め、以降の記事で実際に構築していきます。

問題

現代的なWeb UIを構築するには通常、2つの言語、2つの型システム、ビルドパイプラインが必要です。バックエンド(Python / Node / Go)に加えてフロントエンドフレームワーク(React / Vue / Svelte)とそのツールチェーン(Vite / Webpack / Babel)が必要です。型をネットワーク越しに重複させ、2つのメンタルモデルを同期させ続け、node_modulesは独自の人格を持つようになります。

Phoenix LiveView(Elixir)は別の方法を示しました。サーバーでレンダリングし、WebSocket経由で差分をプッシュし、ブラウザはシンプルに保つというものです。クライアントフレームワーク不要、手書きのAPI不要、手動のJSONシリアライズ不要。Fitz LiveViewsはこのモデルをFitzにもたらし、さらに一捻りを加えます:同じコンポーネントを、純粋にクライアントサイドでオフラインのインタラクティブ性を求める場合にWebAssemblyにコンパイルできるのです。

Fitz LiveViewsの外観

コンポーネントは単一の.fitzvファイルで構成されます — 状態、イベントハンドラ、テンプレートはVueやSvelteのように記述します:

component Counter {
  state { count: Int = 0 }

  event increment() { count = count + 1 }
  event decrement() { count = count - 1 }
  event reset() { count = 0 }

  <template>
    <div id="counter-app">
      <p>Count: {count}</p>
      <button @click="increment">+1</button>
      <button @click="decrement">-1</button>
      <button @click="reset">Reset</button>
    </div>
  </template>
}

全画面表示 全画面表示を終了

サーバーレンダリングターゲットでは、フレームワークはこのコンポーネントを登録し、初期HTMLを送信します。そして、イベント発生ごとにHTMLを再計算し、差分を計算してWebSocket経由でパッチのみを送信します。ブラウザがこれを適用します。クライアントJavaScriptを書く必要はなく、APIを定義する必要もなく、ペイロードを手動でシリアライズする必要もありません。

クライアントWASMターゲット(fitz build --target wasm-client)では、同じファイルwasm-bindgen + web-sysバンドルにコンパイルされ、DOMを直接マウントして変更します — オフラインでサーバー不要です。単一コンポーネントは約12 KB(gzip)です。

違いを生むポイント

  • 1つの言語でフロントエンドからバックエンドまで。 コンポーネント、ハンドラ、サーバーはすべてFitzに存在します。type User { ... }は両側で同一 — 重複したDTOは不要です。
  • JavaScriptビルド完全不要。 npm install不要、バンドラー不要、node_modules不要。fitzバイナリがすべてをコンパイルします。
  • 型チェック付きテンプレート。 テンプレート専用のチェッカーが存在します:誤った型のプロパティ、存在しないハンドラに紐づけられた@event、対応する<slot name="x">のない<slot slot="x"> — これらはすべてコンパイル時に検出され、.fitzvファイルと行番号を指し示します。
  • デュアルターゲット:1つのソースからSSR または WASM。 共有・DB駆動・複数ユーザーの状態にはサーバーレンダリングを、ローカル・ゼロラウンドトリップ・オフラインウィジェットにはクライアントWASMを。どちらも同じコンポーネントモデルです。
  • パッケージ化されたUIライブラリ。 fitz_liveviews.ui.*は即時利用可能なコンポーネント(Badge、Card、DataGrid、Pager、Input、Select、Tabs、Stepper、TreeView、…)を提供し、--flv-*デザイン・トークンでテーマ設定可能です。

ライブコンポーネントギャラリーがあります — 実際のコンポーネントがWebAssemblyにコンパイルされ、ブラウザ内でサーバーなしで動作します。自由に操作してみてください。

数値で見る

以下はフラッグシップ管理アプリとギャラリーから測定したペイロード/ビルド数値です — 合成スループット値ではありません:

  • 完全なサーバーレンダリングダッシュボードページは約1.1 KBのJavaScript(テーマ事前描画+WebSocketライブクライアント用の3つの小さなインライン<script>ブロック)で、外部<script src>は一切なく、ビルド工程も不要です。ページHTMLは約38 KBで、これがすべて — まずダウンロードすべきフレームワークランタイムはありません。SPAと比較すると、フレームワークランタイムだけで約40 KB(Svelte系)から約140 KB(React + ReactDOM)がコードとハイドレーションペイロードの前に必要です。
  • クライアントWASMコンポーネントは約12 KB(gzip) — 「100 KBランタイム上のあなたのコード」ではなく、コンポーネント全体です。カウンターデモは11.4 KB(gzip)、12ウィジェットで構成された完全なギャラリーは約44 KBです。
  • node_modulesゼロ、バンドラー設定ゼロ。 fitzバイナリがツールチェーン全体です。git clonefitz run
  • ネイティブバイナリはインタープリターより1回の操作あたり約9倍高速fitz runfitz buildのレンダリング結果はビット単位で同一)なので、開発はインタープリターで行い、バイナリを出荷します。

(フレームワーク横断のリクエストスループットベンチマークは今後の正直な作業です — 負荷テストを大まかに述べるより、測定したペイロード数値を提示したいと考えています。)

比較

Fitz LiveViews Phoenix LiveView Hotwire (Turbo) React/Vue/Svelte (SPA) HTMX
WebSocket経由のリアルタイム差分 ✅ 組み込み ✅ 組み込み ~ (Turbo Streams) 手動 ~ (拡張)
JavaScriptビルド工程 なし なし なし 必須 なし
スタック内の言語数 1 (Fitz) 1 (Elixir) 2 (Ruby + JS) 2以上 (バックエンド + JS/TS) 1バックエンド + HTML
オフライン/クライアント専用ターゲット WASM、同じソース ✅ (JS)
型チェック付きテンプレート ✅ コンパイラ ~ (HEEx) ~ (TS/JSX)
ネイティブバイナリへのコンパイル ❌ (BEAM VM)
パッケージ化されたUIコンポーネントライブラリ fitz_liveviews.ui.* コミュニティ コミュニティ 巨大なエコシステム コミュニティ

Fitz LiveViewsが真に異なる点:スタック全体で1つの言語1つのソースからのデュアルSSR/WASMターゲットスタンドアロンネイティブバイナリへのコンパイル、そしてコンパイラによるテンプレートチェックです。率直に劣っている点:まだ新しく、エコシステムが小さい — React/Vue/Svelteには10年のライブラリと人材プールがあります。より小さなエコシステムと引き換えに根本的にシンプルなスタックというトレードオフが、あなたの構築するものに適していると思えば、読み進めてください。

はじめに

1. Fitzをインストール。 Fitz LiveViewsはFitz言語向けライブラリなので、まずFitzをインストールします:

curl -sSf https://thegreekman76.github.io/fitz/install.sh | sh
fitz --version

全画面表示 全画面表示を終了

Fitzコースではインストール/アンインストール/更新を詳しく解説しています — Fitzコース · C1 — インストールをご覧ください。

2. エディタ拡張機能をインストール。 2つのVSCode拡張機能で、シンタックスハイライト、診断、ホバー、定義への移動が利用できます:

  • Fitz.fitzファイル(言語本体)用。Fitz releasesから.vsixを取得し、code --install-extension fitz-language-*.vsixを実行します。
  • Fitz LiveViews.fitzv単一ファイルコンポーネント用。fitz-liveviews releasesから取得し、code --install-extension fitz-liveviews-*.vsixを実行します。

3. 依存関係を追加。 プロジェクトのfitz.tomlに:

[dependencies]
fitz_liveviews = { git = "https://github.com/Thegreekman76/fitz-liveviews" }

全画面表示 全画面表示を終了

これでセットアップは完了 — Nodeもバンドラーもpackage.jsonも不要です。

おもちゃではない — フラッグシップがある

このモデルを実際のものに証明するため、Fitz + Fitz LiveViewsだけで構築された完全なバックオフィス管理パネルがあります:ログイン(Argon2id+署名付きJWTセッションクッキー)、レスポンシブシェル(折りたたみ可能なサイドバー、320pxまで対応するモバイルドロワー、ES/EN切替、ライト/ダーク/自動テーマ)、Postgresからの実カウントを含むダッシュボード、検索・フィルタ・ソート・ページネーション・リッチなタブ付きフォーム・複数削除・グループ化・行ごとの展開・CSVエクスポートを備えた2つのライブCRUD画面(従業員+部門) — すべてWebSocket経由で差分更新され、すべて国際化され、すべて1つのdocker compose upで動作します。

再利用可能なすべての部分はfitz_liveviews.ui.*のパッケージ化されたコンポーネントです — このライブラリは本アプリから抽出されました。これが生きているリファレンスです。

参照先

本シリーズの次回

  • #2 — 初めてのコンポーネントを2回。 サーバーサイドでWebSocket経由でレンダリング、WebAssemblyにコンパイルされるカウンタ — 1つのソース、2つのターゲット。
  • #3 — フォーム、ペイロード、ライブ入力。 イベントがどのようにデータを運び、@input / @changeがフォーム値をどのようにバインドするかを解説。
  • #4+ — フラッグシップの構築。 管理パネルの深掘り:クッキー認証、Postgres上のライブDataGrid、パッケージ化されたUIライブラリ、i18n、Docker。

JavaScriptビルドなしのリアルタイムUIに魅力を感じたら、リポジトリにスターを付け、シリーズをフォローしてください。次回はカウンタを2回構築します。