Linearが私をローカルファーストの rabbit hole に誘った
(bytemash.net)- Linear を使い始めてから、ウェブアプリケーション開発の視点が大きく変わった
- Linear はローカルファースト方式で動作し、即時の反応とネットワーク遅延のないインタラクションを提供する
- この方式では、クライアントが独立したデータベースを持ち、変更は非同期でサーバーと同期される
- ただし、分散環境での同期、衝突解決、オフライン処理などの実装難易度が高い
- Jazz、Electric SQL、Zero などのローカルファーストエコシステムのさまざまなソリューションが登場しており、開発者体験も徐々に改善している
概要
Linear というプロジェクト管理ツールを使い、ローカルファースト方式の卓越した速度とユーザー体験から大きな影響を受けた。既存のウェブアプリでよく体験するネットワーク遅延、ローディング状態、ページリフレッシュといった事象が全く感じられない点が印象的だった。この体験を通じて、ローカルファースト(local-first) パラダイムの技術的な原理と実際の適用事例を深く掘り下げることになった。
Down the Rabbit Hole
Linear の技術的な仕組みを探るうちに、彼らはブラウザの IndexedDB を実際のデータベースとして活用していることを知った。すべての変更はローカルで先に即時処理され、その後GraphQL と WebSocketsを使ってバックグラウンドで同期が行われる。
- local-first という用語は、UX戦略(即時応答)またはデータ自体をローカルに保存して同期する哲学としてさまざまに解釈できる
- 伝統的なウェブアプリではサーバーが単一の真実の源だったが、ローカルファースト構造では各クライアントが独自のデータベースを持つ
- データベースの位置がユーザーに近づくことで、ユーザーインタラクションにおけるネットワーク遅延が完全になくなる
The Challenge: This Is Not Trivial
Linear の方式を実際に実装しようとしてみると、かなりの複雑さがあることに気づいた。
- オフライン/オンライン切り替え処理
- 分散したクライアント間の衝突解決
- 部分同期(全データをダウンロードしないための設計)
- キャッシュデータのスキーマ移行
- 分散環境でのセキュリティおよびアクセス制御
- こうした機能は、膨大なエンジニアリング時間と労力を要する領域である
The Local-First Ecosystem in 2025
2025 年時点で、ローカルファーストエコシステムには複数の強力なソリューションが登場している。
- Electric SQL: Postgres ベースの同期エンジン
- PowerSync: エンタープライズ向けソリューション
- Jazz: ローカルファーストアプリを簡単に構築できるようにするツール
- Replicache: 主要な既存ソリューション(開発終了)
- Zero: Replicache チームの新しい方向性
- Triplit: TripleStore ベースの同期
- Instant: 開発者体験に焦点を当てる
- LiveStore: リアルタイム同期レイヤーを提供
Deep Dive: Jazz
Jazz は、"ローカルファーストアプリをステート更新と同じくらい簡単にする"という独自の約束で注目される。
The Mental Model
Jazz は Collaborative Values(CoValues) というリアルタイム共同作業構造を導入している。
- Jazz と Zod でスキーマを定義する。これは単なる型ではなく、自動同期されるライブオブジェクトとして動作する
- 別途の API ルート、リクエスト/レスポンスロジック、DTO は不要で、単にオブジェクトの状態を変更するだけで自動で同期される
How Jazz Achieves This
Jazz の内部構造は次の通り。
- 一意性保証: 各データにユニーク ID を自動割り当て
- イベントソーシング: 変更履歴をイベントとして保存し、リアルタイム同期の効率を高める
- エンドツーエンド暗号化: 同期前にクライアント側でデータを暗号化。サーバーは暗号化された BLOB だけを見ることができる
- グループベースの権限設計: 従来の ACL の代わりにグループ単位で権限を定義し、所有権を明確に分離
The Trade-offs
この構造は、プロトタイピングと迅速な UI 開発において非常に生産的だ。ただしいくつか考慮すべき特性がある。
Your Server Is Blind
エンドツーエンド暗号化のため、サーバーはユーザーのデータを読み取れない。事前にサーバーがアクセスする必要があるデータを明確に定義しておかないと、監視や悪意ある保存防止など管理上の制限が生じる。
Time Travel Is Mandatory
イベントソーシングにより、すべての変更履歴が永続保存される。これにより Undo/Redo は非常に便利だが、GDPR などの法的要件を考えると削除が難しいという欠点がある。
Storage Goes Brrr
削除が行われないため、ストレージ使用量がどんどん増加する。小規模プロジェクトでは問題ないが、大規模な SaaS ではストレージコストが大きく増加する可能性がある。
Local Dev Still Has Quirks
Passkeys を中心とした認証方式が基本だが、独自開発やローカル環境では HTTPS、証明書管理、鍵の移行などで開発初期の手間が発生する。とはいえ、Better Auth 統合などの改善が予定されている。
But Honestly? Still Worth It
これらの制約があるにもかかわらず、Jazz の開発体験と生産性は非常に印象的だ。まだ初期バージョンだが、今後はさまざまな問題が徐々に解決される見込みだ。
Exploring: Electric SQL and Zero
Jazz と異なり、Electric SQL と Zero は段階的なアプローチを取る。
- 既存の Postgres テーブルをそのまま利用可能
- Electric SQL はテーブルの一部を reactive query(Shape)として購読し、UI と同期できる
- 変更(ミューテーション)処理は Jazz とは異なり、LiveStore 統合など複数の選択肢がある
- Zero は Electric と似ているが、変更の同期サポートが組み込まれている
When Does Local-First Make Sense?
ローカルファーストパラダイムが適する場面と難しい場面を次のように整理した。
適している:
- 創作ツール(デザイン、執筆、音楽など)
- コラボレーション支援アプリケーション
- オフライン対応が必要なモバイルアプリ
- 開発者向けツール
- 個人向け生産性アプリ
難しい:
- 大規模なサーバー側ビジネスロジック
- 厳格な監査要件
- 大規模分析システム
- 深く統合された既存システム
- サーバー側でリクエストを頻繁に拒否するシステム
Looking Forward
ローカルファーストはウェブ開発のパラダイムシフトを意味する。Linear はすでにユーザー体験で大きな効果を実証している。開発者はこれらの構造的なトレードオフが自分のプロジェクトに適しているかを判断する必要がある。
Jazz でパーソナルアプリを実際に作る過程で、実際の長所と短所、抽象化の限界を体験している。エコシステムはまだ初期段階で、今後はツールとパターンが成熟し改善されるだろう。しかし、データをローカルに置く方法の利点は明確であり、これはなくならない見通しだ。
新しいプロジェクトでこれらの制約を受け入れられるなら、ローカルファーストを試してみる価値は十分にある。最悪でも新しいアーキテクチャパターンを学べるだけで、最良なら不可能と思えるほど高速なユーザー体験を実装できる。300ms 応答競争の中でこれは重要な優位性になる。
1件のコメント
Hacker News の意見
Zero も Electric と同様の機能を提供し、ミューテーション処理を直接サポートする Zero の主な差別化はクエリ中心の同期にある アプリをクエリ単位で設計でき、事前に何を同期するか決めたり設定したりする必要がなく、クエリを実行するだけで必要な分か最小限だけを同期できる クライアントに必要なデータがなければクエリは自動的にサーバーに送られ、同期された後すぐ次のクエリで使用可能になる この方式はかなり実用的
私は SSR を好む クライアントはセッショントークン、現在の URL、そして DOM のみ状態として持つべきだと思う ネットワークとサーバーは引き続き高速化している 光速は固定だが、まだ十分に活用できていない段階だ Hollow core fiber などでインターネット全体のレイテンシを 30% 低下させる技術も出てくる予定 既に RTT が 500ms だとしても、SSR で 16ms 以内にレンダリングされたページは、今日のほとんどのウェブサイトよりずっと即時に感じられる サーバー側で 60Hz フレームより長く HTML レスポンスをレンダリングするのはおかしいと思う Zen5 コアならその時間内に 30〜40MB の JSON シリアライズを行える サーバー側では単に fancy な UTF-8 文字列にすぎない こうした部分は ms 単位ではなく μs 単位で測るべきだ 転送遅延が高いことは CPU 時間を使わないでいい理由にはならない 私は SQLite を使ってミリ秒地獄から脱した ホスティング SQL サービスは 1ms 未満レイテンシを狙う際の足かせになる ブラウザ標準でも一部のナビゲーション遅延問題は解消できる Speculation Rules API 参照
ネットワークとサーバーが速くなるという点は、SSR の普遍的な根拠にはならない 一部のサーバーに計算資源が多い場合や、ロジック分離が難しいケースで SSR が必要だという例外的状況を示しているに過ぎない 実際にはクライアントレンダリングの方が速いケースは多い レンダリングロジックはデータ量に比べてはるかに複雑なことが多く、全クライアントリソースを合計するとサーバーより大きくなることもある SSR しか選択肢がなかったなら、いま話題の Web Assembly 熱狂を説明できない local computation に関する投稿 も参考になる 結局どちらが良いかは事前には分からず、リクエスト時点で選べる必要がある
Right Tool For The Right Job! たとえば Google Docs や Sheets のような協業ドキュメントを、単純にサーバーサイドレンダリングだけで扱えるだろうか SSR に固執すると、編集中に別のユーザーがコンテンツを上書きしてしまう事態が必然的に起きる こうしたツールは変更影響が小さく、ユーザーが共同作業中であることを即座に認識してリアルタイム更新を受けられるためうまく機能する 一方、ホテル予約のようなサービスではリアルタイム同期は不要 さらに、途中で揺れる同期や、前提設計が不足したエンタープライズアプリは、後からドメイン・システムの複雑さで整合性を合わせるのがかなり難しくなる
既存 SSR アプリに以下のライブラリを簡単に追加できるなら使うだろう:
これは本当にハッピーパス・エンジニアリングだ 現実にはハッピーパスにいない人にとってかなり挫折しやすい
SSR の現在と将来の主な用途は、最初のページロード、特にモバイル その後はクライアント側でステータス更新だけ必要なので、すべてがさらに速くなるべき エンジニアリングの力量が足りないと、SSR があっても意味がない
私は CRDT ベースの local-first アーキテクチャの OSS タスク管理ソフトを開発している 開発動機は、共同編集機能が不要だったことと、Linear のようなツールが私の用途には過度に複雑だったため このアーキテクチャの利点は次のとおり:
Jazz に非常に強い印象を受けた DX がすごく良く、ほぼ同期的で命令型のようにコードが書けて開発が楽しい 何でも即座に感じられ、オフラインでも作業できるので UX も優れている 最大の問題は展開と長期保守で、データが増え続けること(大半のクライアントがそれを全部見る必要がないので大きな懸念ではない) 最大の課題は、頻繁に変化する public index に対して良いソリューションがないこと 理論上は public readable list of ids は可能だが、最近 Anselm と話したところ、解決中とのこと 全体として local-first にもコストは小さくないが、Jazz が従来の中央サーバー型の主要な欠点を解消できれば、Firestore をほぼ全ての面で代替できるだろう
ElectricSQL と TanStack DB のどちらも素晴らしいが、なぜウェブで local first にそこまで注力するのか疑問 モバイルではオフライン環境のため local first がはるかに必要だと思う ブラウザを使う場合は、実際にはインターネットがほぼ常時接続 さらに、こうした local-first 技術は理論上は見栄えがよいが、コンフリクト解決が追いつかないと実運用で簡単に壊れる モバイルアプリを local-first 化する過程で得た教訓で、だから私は CRDT を使うことにした
ウェブ技術で local-first アプリを作るのは、ネイティブに比べると桁違いに難しい ネイティブアプリはインストールするだけでオフライン利用がデフォルト ウェブは AppManifest や ServiceWorker などの小細工で辛うじてオフライン対応を付ける必要がある ネイティブでは 30 年前の C コードでディスクへファイルを自由に読み書きできるだけで十分 ウェブでは IndexedDB が本当の悪夢で、localStorage は規模が大きくなると使えず、OriginPrivateFileSystem も制限がある ユーザーが月に 1 回でもサイトに訪れなければ、Safari はローカルブラウザ状態を削除してしまう JavaScript や Emscripten で wasm ビルドなど別の工夫をしても、async web API をいかに回避してなんとか処理するかが必要 Apple は 2015 年から CoreData + CloudKit の組み合わせで local + sync の完成版を提供してきた Google 側は Firebase がその点かなり近いと思う
私は Replicache と Zero の開発者として、なぜウェブに集中するのかよく考えてきた 正解はまだ分からないが、意見としては:
モバイルはウェブよりオフラインの基礎機能がはるかに強い しかし実際の多くの生産性/協業はウェブ上で行われ、ウェブはより敵対的な環境 タブ間の状態同期、保存削除などが複雑な問題となる そのため local first は主にウェブ中心で発展する
同期エンジンがウェブを先にターゲットにするのは、これらの技術がまだ若くアップデートが多いためだと思う モバイルアプリのアップデートは本当に面倒だが、ウェブアプリのアップデートはずっと簡単 PWA の能力もかなり良くなっていると思う iOS の PWA でもプッシュ通知ができ、私はモバイルアプリのようなウェブアプリだけでも十分満足
ここでのポイントは「何の機能が使えるか」ではなく、信じられないほど速く反応するプロダクトから生まれる「楽しさ」 それで local-first を志向する
Local-first/sync エンジンの協働面はあまり扱われていない感じがする 私は Zero を使って、友人向けのビジネス用 Google Sheets 代替プロジェクトを作っている Google Meet でリアルタイムに一緒にシートを開きデータを扱う状況で使っている この経験は以前ならウェブアプリで実装するなど想像もできなかった WebSocket でライブ UI をたくさん作ってきたが、入ってくるデータを正しい場所に正しく反映・管理するのは非常に複雑 データセルが数百、数千個になるとその混乱は想像を超える Zero ではクエリでデータを選び、mutator でデータを変更すると、全員が同じ状態で即座に同期される そのおかげで開発そのものが本当に楽しい
私は Google Docs が最初に公開された時(12 歳の時)リアルタイム同期と協業カーソルが入ったのを見て、『これからのウェブ体験はすべて協業型になる』と思った 当時クラウドコンピューティングが流行語で、私は誤りだったとわかったが、リアルタイム協業をクラウドコンピューティングの定義だと信じていた でも結局、そのような未来は現実にならなかった 20 年が経っても、ほとんどのウェブ製品はまだ CRUD 体験だ(このサイトもそうだ) 何度も「今度こそ革命」が来ると思った。Meteor.js、React などに期待したが、まだデフォルトにはなっていない これが本当にメインストリームになることをずっと期待している。いつか必ず現実になる気がする ただ予想以上に難しく、すべての状況で使えるだけのツーリングが整っていないだけだ
リアルタイム協業の例としては Discord(本質的には 1990 年代の IRC とそう変わらない)、Zoom(あらゆるビデオ会議)がある HN のようなサイトが CRUD アプリであるのは長所 リアルタイム更新はむしろノイズになるため望ましくない
光速が実際には限界である 地球を半周するのに光は 56ms かかる。実際の信号はさらに迂回し、変換や追加ボトルネック(ロードバランサ、DDoS 防御など)でさらに遅くなる レイテンシはむしろ昔より悪化している場合もある
私もそのリアルタイム性の最初の魔法を体感したが、その未来はどこかにまだ残っているような気がする それでも実際に、本当の Google Docs スタイル(入力欄/送信ボタンなし)のリアルタイムメッセージングツールを作っている: kraa.io/hackernews
Local-First、Sync-Engines の未来を信じる local-first フレームワークランドスケープの様々なテーブル整理 は本当に有益 個人的には Triplit.dev が最も良く、TanStack DB とも組み合わせられる PowerSync、NextGraph も検討したい選択肢 最近の LocalFirst Conf の動画の中で NextGraph 関連の発表も楽しく見ている: YouTube 動画
これらのツールのデータベース移行対応はどうか気になる 長期的にサーバー接続のないクライアントをサポートする場合、かなり古いスキーマ状態からロールフォワード移行することが大きな障害ではないか 実際、単一ユーザーのフロントエンドバグ対応でも大変なのに、スキーマ状態まで考慮すると複雑さは想像を超える
Meteor を思い起こさせる
こうしたアプローチも過去の方式だ
Triplit は必ず試したい。InstantDB を使ったことがあるか気になる 私も興味はあったがまだ使えない
Electric のアプローチがずっと気に入っており、長く注視してきた Electric は記述の難しさを開発者と API に任せることでむしろクリーン 双方向同期ソリューションは、通常シンプルな ToDo アプリレベルでしかうまく機能しない 権限、ビジネスロジックの進化、マイグレーション、製品成長が加わると、耐久性に疑問が生じる Electric は読み取り同期のみをビューでサポートし、書き込みは既存の API/REST/RPC でそのまま処理するため、既存プロジェクトへの導入が簡単
なぜ couchdb / pouchdb が一覧にないのか不思議だ いまでもかなりちゃんと動作するツールだ