Skip to content

Instantly share code, notes, and snippets.

@lark1115
Created April 16, 2026 03:37
Show Gist options
  • Select an option

  • Save lark1115/8ac6542fe6d3cba0730cfb733896a527 to your computer and use it in GitHub Desktop.

Select an option

Save lark1115/8ac6542fe6d3cba0730cfb733896a527 to your computer and use it in GitHub Desktop.

cmux-remote の xterm.js → wterm 置き換え調査

背景

cmux-remote は iPhone から cmux ワークスペースをリモート監視・制御するための PWA。現在 xterm.js をターミナル描画に使用している。

wterm は Vercel Labs が公開した DOM ベースのターミナルエミュレータ。Zig → 12KB WASM という軽量さが特徴。

本稿では xterm.js を wterm に置き換える実現性とメリット・リスクを整理する。


cmux-remote の現行アーキテクチャ

iPhone PWA (React 19 + xterm.js)
        ↕ WebSocket
   Bridge Server (Bun + Hono)
        ↕ Unix Domain Socket
    cmux (~/.../cmux.sock)

主要ファイル

ファイル サイズ 役割
client/src/components/Terminal.tsx ~2KB xterm.js によるターミナル描画
client/src/hooks/useWebSocket.ts ~2.5KB WebSocket 接続管理
client/src/hooks/useCmux.ts ~5.5KB cmux コア機能
server/src/ws.ts ~4.6KB WebSocket サーバー実装

技術スタック

  • クライアント: React 19, TypeScript, Vite, xterm.js, Hammer.js
  • サーバー: Bun, Hono
  • バンドルサイズ: gzip 時 約 144KB

wterm の概要

項目 内容
レンダリング DOM ベース(Canvas ではない)
コアサイズ ~12KB WASM(Zig 製)
パッケージ構成 @wterm/core, @wterm/dom, @wterm/react, @wterm/just-bash, @wterm/markdown
API write(data) で出力、onData(cb) でユーザー入力取得
WebSocket @wterm/core にトランスポート内蔵
テーマ Default, Solarized Dark, Monokai, Light 等ビルトイン
自動リサイズ ResizeObserver 対応

置き換え可能性の評価

結論: 置き換えは十分に可能。メリットも大きい。


API 互換性

両方とも基本的なインターフェースは同じ概念:

// xterm.js
const term = new Terminal();
term.write(data);
term.onData((input) => { /* send to server */ });

// wterm (@wterm/react)
<Terminal
  ref={ref}
  cols={80}
  rows={24}
  wasmUrl="/wterm.wasm"
  onData={(input) => { /* send to server */ }}
  onReady={(api) => { api.write(data); }}
/>

ドロップイン置換ではないが、概念マッピングは 1:1 で対応する。


cmux-remote にとってのメリット

項目 xterm.js wterm 影響
バンドルサイズ ~12KB PWA の初回ロードが大幅改善
テキスト選択 Canvas 上の独自実装 ネイティブ DOM iPhone Safari での UX 向上
コピー/ペースト 追加実装が必要 ネイティブ対応 モバイルの長押しメニューがそのまま動く
CSS カスタマイズ 制限的 通常の CSS テーマ・レスポンシブ対応が容易
アクセシビリティ 追加実装が必要 DOM 標準対応 スクリーンリーダー等が自然に動作
自動リサイズ FitAddon が必要 ResizeObserver 内蔵 依存が減る

特に cmux-remote は iPhone PWA であるため、DOM ベースのネイティブなテキスト選択・コピペは UX に直結する大きなメリット。


注意点・リスク

リスク 詳細 対策
プロジェクトの成熟度 wterm はまだ若い。エッジケースの対応が不十分な可能性 cmux の出力パターンで事前テスト
ANSI エスケープシーケンス網羅度 cmux が使う全シーケンスをサポートしているか未検証 VT100/VT220/xterm は対応。256色・24bit RGB 対応済み
Addon エコシステム xterm.js の FitAddon, WebLinksAddon 等に相当する機能がない FitAddon → ResizeObserver で代替可。リンクは DOM なので CSS/JS で対応可能
API 互換性 ドロップイン置換ではない 書き換え対象が小さい(Terminal.tsx ~2KB)
モバイルブラウザ対応 iPhone Safari での動作実績が不明 DOM ベースなので Canvas より Safari との相性は良いはず

書き換え対象と作業量

変更が必要なファイル

  1. client/src/components/Terminal.tsx (~2KB)

    • xterm.js の Terminal@wterm/react<Terminal> に差し替え
    • FitAddon の削除(ResizeObserver で代替)
  2. client/src/hooks/useWebSocket.ts (~2.5KB)

    • @wterm/core の WebSocket トランスポートで簡素化できる可能性
    • もしくは既存のロジックをそのまま活かし、write() / onData() の接続点だけ変更
  3. package.json

    • xterm@wterm/react, @wterm/core に依存を差し替え
    • xterm-addon-fit 等の Addon 依存を削除

作業量の見積もり

  • コード変更量: 100〜200行程度
  • 所要時間: 数時間〜1日
  • 難易度: 低〜中(API の概念が似ているため)

X での反響

wterm の発表は大きな注目を集めている:

  • Chris Tate(Vercel, 作者)の発表ツイートが 1,182 いいね / 13万ビュー
  • 「12KB WASM で DOM レンダリング」という軽量さとアクセシビリティが評価ポイント
  • xterm.js の Canvas ベースの制約を DOM で解決するアプローチに好意的な反応

まとめ

cmux-remote と wterm の組み合わせは相性が良い:

  • PWA + 12KB WASM → バンドルサイズ大幅削減
  • iPhone + DOM レンダリング → ネイティブなテキスト操作
  • React + @wterm/react → フレームワーク一致
  • WebSocket + @wterm/core → トランスポート層の簡素化

リスクは wterm の成熟度だが、cmux-remote の用途(ターミナル出力の表示と基本的な入力)であれば、wterm の現時点の機能で十分カバーできると考えられる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment