Skip to content
Published on

リアルタイム協業 & CRDT 2026 ディープダイブ — Liveblocks・PartyKit・Yjs・Automerge・Loro・ShareDB・Replicache・Fluid・Tldraw sync

Authors

プロローグ — 2026年、「一緒に編集する」とはどういうことか

2010年にGoogle Docsが一般ユーザーに「同じ文書を同時に編集する」を届けたとき、その技術はOT(Operational Transform)だった。ある人の編集操作を別の人の編集操作に合わせて「変換」する方式である。動作はしたが、サーバ中心であり、オフラインは難しく、誤った変換関数は永遠にデバッグを強いた。

2026年5月、風景は完全に逆転した。CRDT(Conflict-free Replicated Data Type) がウェブ協業の基本単位になった。Figmaのマルチプレイヤー基盤、Linearのローカルファースト同期、Notionのライブカーソル、tldrawのリアルタイムキャンバス、Excalidrawのルーム同期 — これらすべてがCRDTまたはその変種の上に成り立っている。

そしてさらに大きな変化が二つある。

  • 2025年11月、VercelがLiveblocksとPartyKitを相次いで密接なパートナーとして取り込み、「Vercel for Realtime」というポジショニングを固めた。
  • Ink & Switch研究所が発表した「Local-first software」のマニフェストはもはや学術的好奇心ではない。Automerge 2.x・Loro・Yrs(YjsのRustポート)が実サービスに乗った。

本稿は2026年のリアルタイム協業スタックを一気通貫で整理する。理論(CRDT vs OT、ベクタークロック、Lamport)からライブラリ比較(Yjs vs Automerge vs Loro)、SaaS比較(Liveblocks vs PartyKit vs Hocuspocus)、運用パターン(WebSocket vs WebRTC、awareness、永続化)まで。


第1章 · 同時編集の本質 — 同じ文書、別の時間線

まず問題を定義しよう。二人の人が同じ文書を同時に編集するというのは、計算機科学的には「同じ状態に二つの独立した操作が加わる」ことを意味する。

時刻 t0:    "Hello"           (サーバ = クライアントA = クライアントB)

時刻 t1:    クライアントAが位置5に ", world" を挿入
時刻 t1:    クライアントBが位置0に "Say: " を挿入
            (互いに知らない)

時刻 t2:    二つの操作がサーバで出会う
            -> 結果はどうあるべきか?

答えは二つある。OTは「二つの操作を互いの座標系に合うように変換する」。CRDTは「座標を最初から絶対的・一意のIDで打ち、操作をそのまま適用する」。

OTはサーバという単一の真実の源を仮定するが、CRDTはサーバ無しでもすべてのクライアントが最終的に同じ状態に収束する(これをeventual consistencyと呼ぶ)。ローカルファーストソフトウェアの前提条件は、まさにこれだ。


第2章 · CmRDT vs CvRDT — 操作か状態か

CRDTは大きく二種類に分かれる。

  • CmRDT(Operation-based): 操作(operation)を伝播する。「位置5に 'x' を挿入」というメッセージを送る。メッセージサイズは小さいが、正確に一回配送(exactly-once) または因果順序(causal order)の保証が必要。
  • CvRDT(State-based): 状態(state)全体または一部を伝播する。同期時にマージ関数が二つの状態を結合する。マージ関数は可換・結合・冪等(commutative, associative, idempotent) でなければならない。

YjsとAutomergeはどちらもop-basedで始まったが、2026年のLoro・Y-CRDT・Automerge 2.xはdelta-stateまたはハイブリッドモデルへ進化した。差分のみを送るが、冪等に適用できる形で。

種類メッセージサイズネットワーク保証代表的ライブラリ
CmRDT因果順序 + at-least-once初期 Treedoc, RGA
CvRDTbest-effort, 冪等初期 Riak DT
Delta-state冪等 + 因果メタYjs, Automerge 2.x, Loro

第3章 · OT vs CRDT — なぜCRDTが勝ったのか

基準OTCRDT
中央サーバ要否実質必要不要(P2P可能)
オフライン編集難しい自然
変換関数の検証非常に困難(TP2問題)不要
メモリ使用量大(メタデータ蓄積)
テキストCRDTの成熟度2000年代に検証済2020年代に検証済
代表的な採用Google Docs(歴史的)Figma, Linear, Notion ライブカーソル

Google Docsは今もOTを使う(レガシー + 検証済みインフラ)。しかし2020年代以降の新規協業アプリはほぼすべてCRDTを選んだ。最大の理由はオフライン対応P2P可能性である。


第4章 · ベクタークロックとLamport timestamp — 分散時間の二つの顔

分散システムには絶対時間が無い。そこで二つの道具が使われる。

  • Lamport timestamp: すべてのイベントに単調増加する整数を付与する。二つのノードの時間を比較するにはmax + 1。全順序(total order)は作れるが、二つのイベントが同時(concurrent)かは分からない。
  • Vector clock: ノード別カウンターをすべて持ち歩く。[A:3, B:2, C:1]。二つのベクトルを比較すれば「先行/後行/同時」の三つから一つを確定できる。

Yjsは各クライアントが一意IDを持ち、ID + 単調シーケンスの組み合わせで操作を識別する(実質Lamport + client-id)。Automergeはアクター(actor) IDとシーケンス番号の組み合わせ(ベクタークロックの変種)を使う。Loroもactor + counterモデル。


第5章 · テキストCRDTの理論 — Yjs Y.Textの内部

テキストはCRDTの中で最も難しい。「位置5に 'x' を挿入」というインデックスベースの操作は同時編集で崩れる(他人が位置4に何か入れたら位置5は位置6になる)。だからCRDTは一意ID基盤の位置指定を使う。

YjsのY.Textはすべての文字に (clientID, clock) ペアを付与し、それを双方向連結リスト(double-linked list of Items) で繋ぐ。挿入は「このIDの次に入れろ」となり、削除はtombstone(削除マーク)として残る。同位置の同時挿入はclientIDで決定論的順序を作る。

// Yjs: 同じ文書を二人で編集する
import * as Y from 'yjs'

// クライアントA
const docA = new Y.Doc()
const textA = docA.getText('content')
textA.insert(0, 'Hello')

// クライアントB(オフラインで)
const docB = new Y.Doc()
const textB = docB.getText('content')
Y.applyUpdate(docB, Y.encodeStateAsUpdate(docA))
textB.insert(5, ', world')

// 同時に、クライアントAでも
textA.insert(0, 'Say: ')

// 両方の差分を相互に伝達
Y.applyUpdate(docA, Y.encodeStateAsUpdate(docB))
Y.applyUpdate(docB, Y.encodeStateAsUpdate(docA))

// 二つの文書が同じ状態へ収束する
console.log(textA.toString()) // "Say: Hello, world"
console.log(textB.toString()) // "Say: Hello, world"

このコードの核は encodeStateAsUpdateapplyUpdate である。どの順序で、何回、どの経路で適用しても結果は同じ。冪等で、可換で、結合的だ。


第6章 · Yjsの内部構造 — Itemリンクドリストと GC

Yjsの中心的データ構造は Item である。各Itemは:

  • id: { client: number, clock: number } — 一意識別子
  • origin: ID | null — 「このItemはどのItemの次に挿入されたか」
  • rightOrigin: ID | null — 同時挿入衝突解決用
  • content: ContentString | ContentEmbed | ... — 実際の値
  • deleted: boolean — tombstoneフラグ

メモリ爆発を防ぐためYjsはGCを行う。すべてのクライアントが見届けた削除は実際にtombstoneから消去される。また隣接する同一クライアントのItemをブロック単位で圧縮する(例: 一度に 'Hello' と打った5個のItemを一つに)。

ベンチマークではYjsは一貫して最速のテキストCRDTの一つだ。100万文字の文書でもメモリ・CPUが実用水準に収まる。


第7章 · Automerge — JSON CRDTの標準

AutomergeはYjsとほぼ同時期に始まったが、JSON文書全体をCRDTとして扱うことに焦点を当てる。テキストも対応するが(Automerge.Text → 最近はsplice ベースAPI)、強みは深くネストしたオブジェクトツリーのマージだ。

// Automerge: 同じJSON文書を二人で編集する
import { from, change, save, load, merge } from '@automerge/automerge'

// 初期文書
let doc1 = from({
  title: 'Realtime collab notes',
  todos: [{ done: false, text: 'Write CRDT post' }],
})

// シリアライズして他クライアントへ
const binary = save(doc1)
let doc2 = load(binary)

// 両側で同時編集
doc1 = change(doc1, (d) => {
  d.todos.push({ done: false, text: 'Add references' })
  d.title = 'Realtime collab notes (draft)'
})

doc2 = change(doc2, (d) => {
  d.todos[0].done = true
})

// 両方向にマージ
const merged1 = merge(doc1, doc2)
const merged2 = merge(doc2, doc1)

// 二つの結果は同一
console.log(JSON.stringify(merged1) === JSON.stringify(merged2)) // true

Automerge 2.xはRustで書き直され(automerge-rs)、WASMでブラウザ・Node・Electronすべてで走る。メモリ・速度が1.x比で一桁向上した。


第8章 · Loro — 2024-2026のダークホース

Loroは中国発の新興CRDTライブラリで、2024年に1.0を達成し、2026年にはYjs・Automergeと並んで「ビッグ3」に数えられる。特徴は:

  • 最初からRust + WASM
  • タイムトラベル(time travel) を一級機能に — 任意時点の文書状態へ巻き戻し
  • リッチテキストマークCRDT(スタイル範囲)を別データ構造で精密に処理
  • ツリーCRDT(親子関係の同時移動)を真剣に扱う

ベンチマークによればLoroは特定のワークロード(特にツリー・リッチテキスト)でYjsより速い。一方Yjsはテキスト単純編集・エコシステム・教材で依然優位。


第9章 · Liveblocks — CRDT-as-a-Serviceの第一人者

Liveblocks(パリ拠点)は「マルチプレイヤー基盤をSaaSで」という命題を最初に捉えた。2026年時点の主機能:

  • LiveObjectLiveListLiveMap — 独自CRDT(Yjsとは別)
  • useStorage / useMutation — Reactフックで状態同期
  • Awareness/Presence — カーソル・名前・選択範囲のリアルタイム共有
  • Comments・Threads — 文書上にコメントを付ける別モジュール
  • Yjsアダプタ — 既存Yjsアプリ(Tiptap・BlockNote・Lexical Yjs)もLiveblocksトランスポートで同期可能
// Liveblocks: useStorageフックで共有状態を読み書き
import { useMutation, useStorage } from '@liveblocks/react/suspense'

function Todos() {
  const todos = useStorage((root) => root.todos)

  const addTodo = useMutation(({ storage }, text: string) => {
    const list = storage.get('todos')
    list.push({ id: crypto.randomUUID(), text, done: false })
  }, [])

  const toggle = useMutation(({ storage }, id: string) => {
    const list = storage.get('todos')
    const idx = list.findIndex((t) => t.id === id)
    if (idx >= 0) {
      const item = list.get(idx)
      list.set(idx, { ...item, done: !item.done })
    }
  }, [])

  return (
    <ul>
      {todos.map((t) => (
        <li key={t.id} onClick={() => toggle(t.id)}>
          {t.done ? 'X' : 'O'} {t.text}
        </li>
      ))}
    </ul>
  )
}

Liveblocksの強みは運用の簡潔さReactに最適化されたDX。弱点は価格(席単位・MAU単位課金)と独自CRDTへのロックイン(完全な自己ホスティングは難しい)。


第10章 · PartyKit — Cloudflare Durable Objects上の協業

PartyKit(2023年Sunil Pai創業、2024年Cloudflare買収)は別の道を行く。各協業ルームが一つのDurable Objectで、その中に任意のコード(Yjs・Automerge・独自ロジック)を走らせる。

// PartyKit: サーバコード (server.ts)
import type * as Party from 'partykit/server'
import { onConnect } from 'y-partykit'

export default class YjsServer implements Party.Server {
  constructor(readonly room: Party.Room) {}

  async onConnect(conn: Party.Connection) {
    // y-partykitがYjs同期を自動処理
    return onConnect(conn, this.room, {
      persist: { mode: 'snapshot' },
    })
  }
}

PartyKitの強みはユーザコードをエッジで実行できる点。ルーム単位で認証・権限・永続化・ゲームロジックを自由に書ける。弱点はCloudflareロックイン(2026年現在ではむしろ強みでもある — グローバルエッジ分散が無料)。


第11章 · 自己ホスティング — Hocuspocus + Yjs

コスト・ロックインが負担ならHocuspocusが答え。Tiptapチームが作ったYjsバックエンドで、Node.jsで動き、Postgres・SQLite・Redisで永続化する。

// Hocuspocusサーバ
import { Server } from '@hocuspocus/server'
import { Database } from '@hocuspocus/extension-database'

const server = new Server({
  port: 1234,
  extensions: [
    new Database({
      fetch: async ({ documentName }) => {
        // DBからYjsバイナリをロード
        const row = await db.documents.findUnique({ where: { name: documentName } })
        return row?.state ?? null
      },
      store: async ({ documentName, state }) => {
        // DBへ保存
        await db.documents.upsert({
          where: { name: documentName },
          update: { state, updatedAt: new Date() },
          create: { name: documentName, state },
        })
      },
    }),
  ],
  async onAuthenticate({ token, documentName }) {
    // JWT検証など
    if (!verifyToken(token)) throw new Error('Unauthorized')
    return { userId: extractUserId(token) }
  },
})

server.listen()

運用を自前で握れデータ主権が確保される。代わりにスケーリング・HA・モニタリングは自前。Notion・Linear級になると結局自社インフラを書くことになる。


第12章 · ShareDB — OT陣営の生存者

ShareDB(旧derby-share)はOTベースの自己ホスティングライブラリだ。Yjs以前の時代(2015年前後)の協業アプリで広く使われ、今もOTに慣れたチームでは現役だ。

  • 文書をJSONで表現し、JSON OT操作を伝播
  • MongoDB・Postgresに永続化
  • テキストOT(json0json1 タイプ)は検証済
  • 弱点: P2P・オフラインがCRDTほど自然ではない

2026年の新規プロジェクトならCRDT(Yjs/Automerge/Loro)を選ぶのが一般的な推奨だが、既にShareDBで順調に動いているシステムを無理に置き換える理由は無い。


第13章 · Replicache・Zero — 「ローカルファースト同期エンジン」の別解

RocicorpのReplicache(2020-)と後継のZero(2025-)はCRDTではない。mutator方式の同期 + サーバ権威 + 楽観UIというモデルだ。

  • クライアントが「mutator」関数を定義する(例: addTodo(text))
  • mutatorをローカルで即実行しUIを更新
  • 同じmutatorリクエストをサーバへ送り、サーバで権威的に再実行
  • サーバ結果が届いたらローカル結果が上書きされる(ロールバック可能)

CRDTが「複数の真実が最終的に収束」なら、Replicacheは「サーバが最終真実、クライアントは楽観的推測」。Linearがこのモデルで有名になった。


第14章 · Fluid Framework — Microsoftのエンタープライズ解

Fluid FrameworkはMicrosoft 365(Office Online・Loop)のリアルタイム協業エンジン。CRDTではないがシーケンスベースの独自同期モデルだ。

  • SharedStringSharedMapSharedTreeなどの分散データ構造(DDS)
  • Azure Fluid Relay上で動くサービス
  • 外部開発者には扱いにくく(公式SDKはある)、実質Microsoft内部エンジン

2026年に外部新規アプリがFluidを採用する可能性は低いが、Office連携・Microsoft Graph上で協業を組むなら知っておく価値がある。


第15章 · ホワイトボード協業 — TldrawとExcalidraw

tldraw(@steveruizok・@orta)はホワイトボード・ダイアグラムライブラリで、マルチプレイヤーsyncエンジンを自社開発した。内部的にはYjsに似たop-basedモデルだが、キャンバスデータ構造(シェイプツリー)に最適化されている。@tldraw/sync パッケージでReact + WebSocketサーバでルーム同期し、Cloudflare Durable Objects上で動くリファレンス実装があり、シェイプ単位の最終書き込み者優先(LWW)で描画ツールの意味論に合わせている。

一方Excalidrawは手描きホワイトボードの代名詞で、協業ルーム機能は暗号化されたFirebase Realtime Database上で動く。CRDTを正式には使わず、単純なLWWとクライアント側変更マージで処理する。意外と合理的だ。ホワイトボードは短いセッションの間に少数のシェイプを同時編集する。CRDTのメタデータオーバーヘッドが不要なドメインだ。

tldrawの教訓: CRDTはデータ構造によって異なる設計が必要だ。 テキストCRDT(Yjs Y.Text)とキャンバスCRDT(tldraw)は同じ理論の上に立っていても実装ディテールは全く異なる。すべての協業アプリがフルCRDTを敷く必要はないということ。


第16章 · Figmaのマルチプレイヤーアーキテクチャ

Figmaは2016-2017年に独自マルチプレイヤーエンジンを作った。CRDTの一変種で、ノード・属性単位でLWWを適用する。核は:

  • ドキュメント = ノードツリー、各ノードは属性辞書(property bag)
  • 各属性に最新変更の (timestamp, clientID) を付与
  • 衝突 = より大きなtimestamp勝利(LWW)、同点はclientIDの大きい方
  • ツリー構造変更(親変更、順序変更)は別ツリーCRDTロジック

FigmaのエンジニアEvan Wallaceが2019年のブログでこのアーキテクチャを公開し、その後多くの協業アプリが類似パターンを採った。tldrawも一部影響を受けた。


第17章 · Google DocsとOTの歴史

Google Docsは2010年のWritely買収から始まり、同年に同時編集を正式リリースした。エンジンはJupiter(Google内部名)OT。核となるアイディア:

  • すべての編集は (revision, operation) ペア
  • クライアントはサーバにopを送り、サーバは他のopと変換して返す
  • TP1(Transformation Property 1): op1 \* (op2 transformed against op1) == op2 \* (op1 transformed against op2) が成立しなければならない

OTの変換関数を正確に書くのは悪名高く難しい。Googleが十数年かけて磨いたこのコードは2020年代の新規アプリには追従コストが高すぎて、業界はCRDTへ移動した。


第18章 · Presence / Awareness — 「誰がどこで何を見ているか」

協業のもう半分はpresenceだ。誰がオンラインで、どこにカーソルがあって、何を選択していて、何色で表示されるか。

Yjsは y-protocols/awareness で標準化した。CRDT本体とは別の短命状態(ephemeral state)だ。メタデータ:

  • clientID(Y.Docと共有)
  • namecolorcursorselection等の自由JSON
  • ハートビートで生存表示、切断時は自動クリーンアップ

LiveblocksはawarenessをファーストクラスシチズンとしてもたらしUseOthers()・useUpdateMyPresence()で公開する。PartyKitも独自broadcastで実装可能。どちらにせよpresenceは永続化しないのが原則 — ルームが閉じれば消える。


第19章 · WebSocket vs WebRTC — トランスポートの選択

CRDT同期のトランスポートは二つに分かれる。

基準WebSocketWebRTC (DataChannel)
サーバ要否必要NAT越え用のSTUN/TURNのみ
レイテンシサーバラウンドトリップ直通P2P(より速い場合あり)
拡張性サーバがファンアウトメッシュトポロジならN^2
永続化自然サーバミラー必要
ファイアウォール通常通るTURN無しだとブロック可能性
標準ライブラリy-websocket, y-partykity-webrtc

2026年の一般推奨: WebSocketを基本にしつつ、真のP2Pが必要なドメイン(セキュリティ、オフラインメッシュ)、またはサーバ負荷を分散したい時にWebRTCを補助で使う。


第20章 · CRDTライブラリ比較

ライブラリ言語強み弱み代表的採用
YjsJS/TS(+Yrs Rustポート)成熟・エコシステム・テキスト性能本体メモリやや大Tiptap, BlockNote, Lexical Yjs
AutomergeRust/WASMJSONツリーマージ強いテキスト性能はYjsより弱いPushPin, Trail Runner
LoroRust/WASMリッチテキスト・ツリー・タイムトラベルエコシステム新興新規アプリ
Yjs + YrsRustポートRustネイティブバックエンドYjsとのワイヤ互換は部分的サーバサイドYjs
Diamond TypesRust単一テキストCRDT性能チャンピオンJSON非対応ベンチマーク用
sjs (Synchronized JS)実験的TypeScript親和新興研究用

第21章 · SaaS vs 自己ホスティング比較

基準LiveblocksPartyKitHocuspocus(自己)ReplicacheFluid (MS)
CRDT種類独自 + YjsアダプタYjs/Automerge自由Yjs非CRDT(楽観的)DDS(非CRDT)
ホスティングSaaSCloudflareエッジセルフセルフまたはRocicorpAzure
価格MAUベース使用量ベースインフラ費のみ使用量 + SaaSAzure単価
自己ホスト可能部分(Edge Storageオプション)困難(CF依存)完全Replicacheは可能困難
データ主権米・EUオプショングローバルエッジ自由自由Azureリージョン
Awarenessファーストはい自作はい該当なし部分
Comments/Threadsモジュールはい無し無し無しLoopが別途

第22章 · 韓国・日本の事例 — Notion、カカオ、サイボウズ、Sansan

韓国の協業市場は興味深い。Notion韓国進出(2020) 以降、Notion APIと自社ビルド協業の比率が急速に増えた(Notionは独自CRDTライクなモデルを使うが公開資料は少ない)。カカオワーク / カカオトークのメッセージはCRDTではないが、カカオワークの掲示板・メモ協業はOTベース(公開発表)で、カカオエンタープライズが「リモート協業」を伸ばした時期に自社エンジンを作った。ネイバー Line Worksは文書・表・カレンダー協業を提供し、Lineの日本市場と統合され、日本のエンタープライズで大きなシェアを持つ。トス / トスペイメンツは内部協業ツール(アーカイブ・文書)でYjs + Tiptap組み合わせを採用した事例をカンファレンスで共有した。

日本も興味深い。サイボウズ kintoneはビジネスアプリビルダーのフォーム・レコード協業で、同じレコードを複数ユーザが同時編集するときOTベースの変換を適用する。サイボウズは長いOTノウハウを持つ会社として有名だ。Sansanは名刺クラウドで、名刺データOCR結果を複数ユーザが同時に補正するワークフローでCRDT適用を発表したことがある。楽天 RMSは楽天モールの店長向け協業ツールで、内部的に独自同期エンジンを持つ。Notion日本チームは英語圏と同じエンジンだが、日本語IMEとの協業衝突(変換中の文字)を扱うパッチが日本チームPM発表で公開された。


第23章 · CRDT導入意思決定マトリクス

いつCRDTが正解で、いつそうでないか。

状況推奨
テキスト同時編集(エディタ)Yjs + Tiptap/BlockNote/Lexical-Yjs
ホワイトボード/キャンバスtldraw sync または Yjs Y.Map
フォーム・テーブル(セル単位)Yjs Y.Map + セル別キー、または ShareDB
ゲーム状態(時間決定的)CRDTよりlock-stepまたは権威サーバ
チャットメッセージCRDT不要、append-onlyログ
通知・リアルタイムカウンターCRDT G-Counter(学術的だが)または Redis
オフライン最優先(ローカルファースト)Automerge, Loro, Yjs IndexedDB persistence
サーバ権威が重要(決済・在庫)Replicacheまたは伝統的トランザクション

第24章 · 永続化戦略 — IndexedDB・Postgres・バイナリスナップショット

CRDTはどこかに保存される必要がある。

  • クライアント側: Yjsの y-indexeddb、AutomergeのIndexedDBアダプタ。オフライン編集後の再接続時に自動同期。
  • サーバ側(Yjsバイナリ): Yjsは encodeStateAsUpdate で全状態をバイナリとして保存する。Postgres bytea カラム、S3オブジェクト、Redisなどどこでも可能。
  • サーバ側(デルタログ): 各アップデートをログに蓄積し、定期的にスナップショットに圧縮。大容量文書に有利。
  • ハイブリッド: スナップショット + その後のデルタ。ロード時にスナップショット + デルタ累積。

永続化の落とし穴はGCだ。すべてのクライアントが見届けたtombstoneは消せるが、「すべてのクライアント」をどう判断するかが難しい。Yjsは保守的にGCを行い、運用者が定期的に明示的圧縮を呼ぶこともできる。


第25章 · セキュリティ・権限・エンドツーエンド暗号化

協業SaaSのセキュリティモデルは三つに分かれる。

  • サーバが平文を見る(最も一般的): Liveblocks・Hocuspocus標準モデル。権限チェック・検索・コメントモデレーションが楽。
  • エンドツーエンド暗号化(E2EE): クライアントがYjsアップデートを暗号化してサーバへ送る。サーバはバイナリブロブのみを知り、意味を知らない。Excalidrawルームが類似モデル。弱点: 検索・コメント分析・サーバ側マージが不可能。
  • 部分暗号化: コンテンツはE2EE、メタデータ(ルームメンバー、presence)は平文。折衷案。

権限は通常ルーム単位トークン + 操作単位検証の組み合わせ。誰がルームに入れるか(JWT)、入ってから何ができるか(Hocuspocusの onAuthenticate + beforeHandleMessage)。


第26章 · エピローグ — 2027年を見る

CRDTはもはや学術の領域を出て運用の領域にある。2027年に起こる変化を三つ。

  1. モバイル・ネイティブのファーストクラス市民化 — Yjs Swiftポート、Automerge Kotlin、Loro Flutterバインディングがすべて安定し、モバイル協業アプリが爆発する。ローカルファーストが本当に可能になる。
  2. AIエージェントが協業参加者になる — Cursor・Claude Codeが同じ文書を同時編集するもう一人の「ユーザ」になり、awarenessが人とAIを区別する。
  3. 標準化の始まり — IETF・W3CレベルでCRDTワイヤフォーマット標準化の議論に入る。Yjs・Automerge・Loroのワイヤ互換性はまだ無いが、「標準テキストCRDT」の輪郭が見え始める。

最大の教訓はシンプルだ。保存ボタンが消えた世界はすでに来ている。 残るは、その上に何を建てるかだ。


References