$ mix dialup.new my_app
→ Get Started!
WebSocket-first
Elixir Web Framework
Dialup はサーバー上の GenServer がブラウザの状態を持ち続ける、
WebSocket ファーストな Elixir フレームワークです。
新しい形のSingle Page Application を実現します。
Get Started
Live Demo →
defmodule Dialup.App.Counter do
use Dialup.Page
def mount(_params, assigns) do
{:ok, Map.put(assigns, :count, 0)}
end
def handle_event("inc", _, assigns) do
{:update, Map.update!(assigns, :count, &(&1 + 1))}
end
def render(assigns) do
~H"""
<p>Count: {@count}</p>
<button ws-event="inc">+1</button>
"""
end
end
なぜ Dialup なのか
1 tab = 1 process で、全てのページにまたがってセッションが継続。
状態はサーバー上に存在し、WebSocket で同期される。
ファイルベースルーティング
app/users/[id]/page.ex を置くだけで /users/:id になる。router.ex への手書き登録は不要。
1 tab = 1 process
各セッションが独立した GenServer を持つ。状態はサーバー上に存在し、WebSocket で同期される。
session / assigns の分離
session はナビゲーションをまたいで持続。assigns はページ遷移でリセット。ログイン状態が自然に保たれる。
クライアント側 DOM モーフィング
サーバーは HTML を送るだけ。差分適用は idiomorph が担う。プロトコルが単純でデバッグしやすい。
軽量な依存関係
Phoenix 本体は不使用。Bandit + HEEx + idiomorph のみ。クライアント JS は自作 ~100 行 + idiomorph 5KB。
自動再接続
切断を検知したら指数バックオフで再接続。プロセスが生きていれば状態はそのまま復元される。
フレームワーク比較
Dialup は Phoenix LiveView と Next.js に大きく影響を受けています
| 機能 | Dialup | Next.js | Phoenix LiveView |
|---|---|---|---|
| 言語 | Elixir | TypeScript / JS | Elixir |
| ルーティング | ファイルベース | ファイルベース | router.ex に定義 |
| 状態の管理 | サーバー | クライアント (React) | サーバー |
| リアルタイム通信 | WebSocket 組み込み | 別途実装が必要 | WebSocket 組み込み |
| DOM 更新 | idiomorph | Virtual DOM (React) | サーバサイドで差分計算 + morphdom等 |
実際に動かしてみる
カウンター・フォーム・リアルタイム入力を体験できる Live Demo を用意しています。