- Published on
CRDT 로컬-퍼스트 엔진 2026 — Yjs / Automerge 3 / Loro / Replicache / Liveblocks / Zero 비교 심층 가이드
- Authors

- Name
- Youngju Kim
- @fjvbn20031
프롤로그 — Ink and Switch의 7가지 이상, 7년 뒤
2019년 4월, Ink and Switch 연구소가 "Local-first software: You own your data, in spite of the cloud"라는 에세이를 냈다. 마틴 클레프만, 피터 반 하덴버그, 마크 맥그래너핸이 공저자. 그들은 클라우드 SaaS가 만들어낸 "내 데이터인데 내가 못 만지는" 상황을 지적하면서 7가지 이상을 제시했다.
- No spinners — 빠른 동작 (UI는 로컬에서 즉시 응답)
- Your work is not trapped — 여러 기기에서 접근 가능
- The network is optional — 오프라인에서 동작
- Seamless collaboration — 협업 가능
- The Long Now — 장기 보존 가능
- Security and privacy by default — 종단간 암호화
- You retain ultimate ownership — 데이터 소유권
2019년에는 야심찬 비전이었다. 2026년에는 이 7가지 중 4~5가지를 동시에 만족하는 프로덕션 스택이 실재한다. CRDT(Conflict-free Replicated Data Type) 엔진이 무르익었고, 모바일·웹 양쪽에서 오프라인 우선 패턴이 표준이 됐다.
이 글은 그 진영의 8개 주요 엔진을 정확히 비교한다.
- Yjs — 협업 에디터(TipTap, BlockNote, Lexical, ProseMirror)의 사실상 표준
- Automerge 3 — column-oriented 스토리지, 10배 압축
- Loro 1.0 — Rust 기반 신예. movable tree, rich text, 빠른 성능
- Replicache → Reflect → Zero — Rocicorp(Aaron Boodman)의 진화
- Liveblocks — 매니지드 Yjs 백엔드. 2024 Series A
- ElectricSQL — Postgres와 SQLite 양방향 동기화
- PowerSync — 같은 아이디어, 오프라인 우선 강조
- Tinybase — 작은 인메모리 DB + 선택적 CRDT
각각이 무엇이 되고 안 되는지, 어떤 트레이드오프가 있는지, 그리고 한국과 일본 시장에서 무엇이 일어나고 있는지를 짚는다.
1장 · 왜 2026년에 다시 로컬-퍼스트인가?
2019년 에세이 이후 6~7년이 흘렀다. 변화의 동력은 셋이다.
1. WASM과 TypeScript의 성숙 — Loro·Automerge·Yjs가 모두 WASM 또는 순수 JS 빌드를 제공한다. 5년 전에는 브라우저에서 CRDT를 굴리는 게 실험이었다. 지금은 1MB 짜리 WASM 한 덩어리에 들어간다.
2. SQLite의 부활 — Cloudflare D1, Turso, libSQL, SQLite-on-WASM(@sqlite.org/sqlite-wasm)이 동시에 떴다. 모든 클라이언트가 로컬 SQLite를 갖는다는 전제가 다시 현실이 됐다.
3. AI 코파일럿의 등장 — Cursor, Linear, Notion AI 같은 도구들이 "오프라인에서도 동작하고, 빨라야 하고, 협업도 돼야 함"이라는 요구를 SaaS의 기본값으로 만들었다. SaaS의 RTT 200ms는 더 이상 허용되지 않는다.
4. 모바일 우선 시장 — 인도네시아, 인도, 베트남 등 네트워크가 불안한 시장에서 오프라인 동작이 협상 불가능한 요구가 됐다. PowerSync가 이 시장에서 자라났다.
7가지 이상 중 2026년 시점에서 정말 어려운 두 개는 여전히 살아 있다.
- The Long Now (장기 보존) — CRDT는 메타데이터가 끝없이 쌓인다. tombstone garbage collection이 여전히 미해결.
- 종단간 암호화 — CRDT의 머지 로직과 E2EE가 호환되기 어렵다. Automerge 진영이 시도 중.
2장 · CRDT 기초 — state-based vs operation-based
CRDT는 두 갈래로 나뉜다.
State-based CRDT (CvRDT — Convergent)
전체 상태를 통째로 머지한다. 머지 함수는 commutative, associative, idempotent여야 한다. 즉 어떤 순서로 합쳐도, 어떤 횟수로 합쳐도 같은 결과가 나와야 한다.
대표 자료구조:
- G-Counter (grow-only counter)
- PN-Counter (positive-negative counter)
- LWW-Register (last-write-wins)
- OR-Set (observed-remove set)
장점: 단순. 메시지가 한 번이라도 도착하면 수렴. 단점: 페이로드가 크다. 전체 상태를 보내야 함.
Operation-based CRDT (CmRDT — Commutative)
각 변경을 operation으로 보낸다. operation 자체가 commutative해야 한다. 메시지는 exactly-once delivery가 필요.
대표 자료구조:
- RGA (Replicated Growable Array) — 텍스트의 기반
- Treedoc
- LSEQ
- Logoot
장점: 페이로드가 작다. delta만 보냄. 단점: 인프라가 더 까다롭다. 메시지 손실/중복을 다뤄야 함.
실전 엔진들의 가족 관계
| 엔진 | 알고리즘 가족 | 텍스트 | 트리 |
|---|---|---|---|
| Yjs | YATA (op-based RGA 변형) | 강력 | 보통 (Y.Map 중첩) |
| Automerge | RGA-like + Hash-linked ops | 좋음 | 좋음 (JSON 트리) |
| Loro | Fugue + Movable Tree | 강력 | 강력 (movable) |
| Replicache/Zero | LWW + per-row reorder | 단순 텍스트만 | row-based |
| Liveblocks | Yjs 위에 빌드 | Yjs 그대로 | Yjs 그대로 |
| Tinybase | LWW-Register | 약함 | 약함 |
여기서 핵심 한 줄. CRDT는 "어떤 데이터 모델"이냐에 따라 가족이 갈린다. 텍스트 협업 에디터를 원하면 Yjs·Automerge·Loro가 후보. JSON 트리 동기화면 Automerge·Loro. 단순 LWW가 충분하면 Replicache·Tinybase로 가벼워진다.
3장 · Yjs — 사실상 표준이 된 협업 에디터의 엔진
Yjs는 2017년 Kevin Jahns가 박사 논문에서 시작한 프로젝트다. 2026년 현재, 협업 에디터 진영에서 사실상 표준이 됐다.
왜 Yjs가 표준이 됐는가
- YATA 알고리즘 — Yet Another Transformation Approach. RGA의 변종으로, 메모리·성능 양쪽에서 우수.
- 공유 자료형의 풀 —
Y.Doc,Y.Text,Y.Array,Y.Map,Y.XmlFragment. 모든 협업 에디터가 필요한 자료형이 다 있다. - 에디터 어댑터의 풀 —
y-prosemirror,y-tiptap,y-codemirror.next,y-quill,y-lexical,y-blocknote. 새 에디터가 나오면 거의 바로 어댑터가 붙는다. - 트랜스포트 자유 — WebSocket, WebRTC, libp2p, IndexedDB. 동기화 채널을 사용자가 고른다.
TipTap + Yjs 한 조각
가장 흔한 패턴. TipTap 에디터 두 인스턴스가 실시간으로 동기화된다.
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'
const ydoc = new Y.Doc()
const provider = new WebsocketProvider('wss://demos.yjs.dev', 'my-room', ydoc)
const editor = new Editor({
extensions: [
StarterKit.configure({ history: false }), // Yjs가 자체 undo 제공
Collaboration.configure({ document: ydoc }),
CollaborationCursor.configure({
provider,
user: { name: 'Alice', color: '#f783ac' },
}),
],
element: document.querySelector('#editor')!,
})
이 30줄로 협업 에디터 한 개가 굴러간다. 두 브라우저를 열고 같은 룸에 들어가면 즉시 동기화된다.
Yjs의 한계
- 트리 이동(move) 지원이 약하다 — Y.Map 중첩으로는 진짜 movable tree를 표현하기 어렵다. Notion 같은 블록 에디터에서 블록을 다른 부모로 옮기면 동시 충돌이 잘 안 풀린다.
- 메타데이터 누적 — 오래된 도큐먼트일수록 메타데이터가 커진다.
Y.encodeStateAsUpdate로 압축할 수 있지만 비싸다. - 숫자형 약함 — counter나 set 같은 자료형이 1차 시민이 아니다. 직접 구현해야 함.
이 두 한계가 Loro가 등장한 이유다.
4장 · Automerge 3 — column-oriented 스토리지로 10배 압축
Automerge는 마틴 클레프만 본인이 주도하는 프로젝트다. Yjs와 동시기에 시작했지만, Automerge는 "JSON 트리 전체를 머지하는 일반 목적 CRDT"를 노렸다. 더 일반적이라는 뜻은 더 무겁다는 뜻이기도 했다.
2025년 Automerge 3의 격변
Automerge 2까지는 메모리 사용량과 도큐먼트 크기가 큰 약점이었다. 2025년 가을 출시된 Automerge 3가 이걸 한 방에 뒤집었다.
- Column-oriented storage — Apache Parquet에서 영감을 받았다. 같은 종류의 op들이 컬럼별로 모이면 압축률이 폭발한다.
- 평균 10배 작은 도큐먼트 — 같은 편집 히스토리에 대해 Automerge 2 대비 약 10배 줄어든다.
- 빠른 머지·로딩 — 메모리 사용량이 50~70% 감소.
Automerge 3 스켈레톤
import * as A from '@automerge/automerge'
// Doc 생성
let doc1 = A.from({ tasks: [] as Array<{ title: string; done: boolean }> })
// 변경 — 트랜잭션 안에서 plain JS처럼 변경한다
doc1 = A.change(doc1, (d) => {
d.tasks.push({ title: '논문 읽기', done: false })
d.tasks.push({ title: 'CRDT 글 쓰기', done: false })
})
// 다른 곳의 복제본
let doc2 = A.clone(doc1)
doc2 = A.change(doc2, (d) => {
d.tasks[0].done = true
})
doc1 = A.change(doc1, (d) => {
d.tasks.push({ title: '코드 리뷰', done: false })
})
// 머지 — 어느 쪽에서든
const merged = A.merge(doc1, doc2)
console.log(merged.tasks) // 3개 task, 첫 task는 done: true
Automerge Repo
Automerge 3 시점에서 더 중요한 변화는 @automerge/automerge-repo다. 단순 라이브러리가 아니라 도큐먼트 저장소 + 동기화 프로토콜을 같이 제공한다.
- IndexedDB 어댑터 — 브라우저 영구 저장
- BroadcastChannel 어댑터 — 같은 브라우저의 탭 간 동기화
- WebSocket 어댑터 — 서버 동기화
- 향후 libp2p, WebRTC 어댑터
Yjs vs Automerge — 솔직한 비교
| 항목 | Yjs | Automerge 3 |
|---|---|---|
| 에디터 통합 | 풍부 | 약함 (직접 짜야 함) |
| 데이터 모델 | 자료형 한정 | 임의 JSON |
| 도큐먼트 크기 | 작음 | 작음 (3이 와서) |
| 머지 성능 | 매우 빠름 | 빠름 |
| TypeScript 타입 | 약함 | 강함 (T로 파라미터화) |
| 트리 이동 | 약함 | 보통 |
| 학습 곡선 | 가파름 | 완만 |
협업 에디터를 짠다면 Yjs. 일반적 JSON 도큐먼트 동기화면 Automerge.
5장 · Loro 1.0 — Rust 기반 새 표준 후보
Loro는 2023년 말 등장한 Rust 기반 CRDT 라이브러리다. 2025년 1.0이 정식 출시되면서 진영의 새 표준 후보로 올라왔다. 만드는 사람은 Zixuan Chen·Loro 팀.
왜 Loro가 주목받는가
- Movable Tree가 1차 시민 — 트리 노드를 다른 부모로 옮기는 동작을 동시성 안전하게 처리. Notion·Linear 같은 블록 에디터의 가장 어려운 문제.
- Fugue 텍스트 알고리즘 — RGA의 변종으로, "split-line" 같은 어려운 패턴에서 사용자 의도를 더 잘 보존.
- Rust → WASM — 핵심이 Rust고, WASM·NAPI·UniFFI로 모든 진영에 뿌린다. JS, Swift, Kotlin, Python, Rust.
- Rich text 1차 지원 — Y.Text 같은 자료형이 처음부터 rich text를 노렸다. Yjs는 Y.XmlFragment로 우회.
- Time Travel — 도큐먼트의 임의 시점으로 되감기·재생.
Loro 스켈레톤
import { LoroDoc, LoroList, LoroMap, LoroText } from 'loro-crdt'
const doc = new LoroDoc()
doc.setPeerId(BigInt('0x1234567890abcdef'))
const tasks: LoroList = doc.getList('tasks')
const task1: LoroMap = tasks.insertContainer(0, new LoroMap())
task1.set('title', '논문 읽기')
task1.set('done', false)
const note: LoroText = task1.setContainer('note', new LoroText())
note.insert(0, '읽는 중...')
// 직렬화·역직렬화
const snapshot = doc.exportSnapshot()
const docCopy = new LoroDoc()
docCopy.import(snapshot)
Loro Movable Tree
const tree = doc.getTree('blocks')
const root = tree.createNode()
const block1 = tree.createNode(root.id)
const block2 = tree.createNode(root.id)
// block2를 block1의 자식으로 이동 — 동시성 안전
tree.move(block2.id, block1.id)
Yjs에서 이걸 직접 구현하면 충돌 시 사이클이 만들어지거나 사라지는 노드가 생긴다. Loro는 알고리즘 레벨에서 보장.
Loro의 한계
- 에디터 어댑터가 적다 — 2026년 5월 기준 prosemirror·tiptap·codemirror 어댑터가 베타 단계. Yjs만큼 무르익지 않았다.
- 공식 서버 컴포넌트 부재 — y-websocket 같은 표준 서버가 없다. 직접 짜야 함.
- 커뮤니티 크기 — Yjs만큼 큰 생태계가 아니다. 모서리 케이스에 부딪히면 GitHub issue를 직접 열어야 함.
그래도 2026년에 새 협업 도구를 짠다면 Loro부터 평가하는 게 합리적이다. 알고리즘이 더 옳고, 데이터 모델이 더 풍부하고, 미래 지향적이다.
6장 · Replicache → Reflect → Zero — Rocicorp의 진화
Aaron Boodman은 Gmail Offline·Google Gears를 만든 사람이다. 그가 Rocicorp을 차려 만든 라이브러리들은 협업 에디터가 아니라 "B2B SaaS의 sync engine"을 노렸다. 즉 Linear·Notion·Figma 스타일의 백엔드.
진화 순서.
- Replicache (2020~) — 클라이언트가 SQLite-like 로컬 DB를 갖고, 서버에 mutation을 보내고, pull로 서버 상태를 받는다. CRDT 아님. LWW와 명시적 충돌 해결.
- Reflect (2022~) — Replicache 위에 Cloudflare Workers + Durable Objects로 실시간 멀티플레이를 얹었다.
- Zero (2024 말~) — 완전히 새 아키텍처. ZQL이라는 클라이언트-측 쿼리 언어, Postgres를 1등 시민으로, IVM(Incremental View Maintenance).
Replicache의 아이디어
import { Replicache } from 'replicache'
const rep = new Replicache({
name: 'user-123',
licenseKey: 'YOUR_LICENSE_KEY',
pushURL: '/api/replicache/push',
pullURL: '/api/replicache/pull',
mutators: {
async createTask(tx, args: { id: string; title: string }) {
await tx.set(`task/${args.id}`, { title: args.title, done: false })
},
async toggleTask(tx, id: string) {
const task = await tx.get(`task/${id}`)
if (task) await tx.set(`task/${id}`, { ...task, done: !task.done })
},
},
})
// 사용
await rep.mutate.createTask({ id: 'a1', title: 'Replicache 글 쓰기' })
mutators는 클라이언트와 서버에서 둘 다 돈다. 서버가 정답을 알게 되면 client의 optimistic mutation을 rebase한다.
Zero의 새로움
Zero는 2024년 말부터 베타로 공개됐고, 2026년 5월 기준 1.0 직전이다.
- ZQL — 클라이언트에서 쓰는 쿼리 언어. SQL과 비슷하지만 reactive.
useQuery로 결과를 구독한다. - Postgres를 직접 본다 — 서버는 Postgres 그대로. Zero는 그 위에 IVM 레이어를 얹는다.
- 재진입 없이 실시간 — 서버에서 데이터가 바뀌면 클라이언트의 모든 ZQL 결과가 자동 업데이트.
import { Zero } from '@rocicorp/zero'
const z = new Zero({
userID: 'user-123',
server: 'wss://my.zero.dev',
schema,
})
// 리액티브 쿼리
const tasks = z.query.task
.where('userId', '=', 'user-123')
.where('done', '=', false)
.orderBy('createdAt', 'desc')
const view = tasks.materialize()
view.addListener((data) => {
console.log('업데이트된 task 리스트:', data)
})
Replicache 진영의 트레이드오프
- CRDT가 아니다 — 충돌은 명시적으로 해결한다. 동시 텍스트 편집 같은 건 직접 풀어야 함.
- 서버가 진실의 원천 — 오프라인 동작은 가능하지만, 결국 서버가 결정자.
- 데이터 모델이 row 기반 — JSON 트리나 텍스트 같은 도메인 자료형은 사용자가 정의.
Linear가 이 패턴의 가장 유명한 사용자다. 대규모 B2B SaaS에서 서버-측 권한·일관성을 포기하고 싶지 않은데, 빠른 UI는 원할 때 후보.
7장 · Liveblocks vs Partykit vs y-redis — 매니지드 협업 백엔드
CRDT 라이브러리는 절반의 그림이다. 나머지 절반은 도큐먼트를 어디에 저장하고, 누가 누구에게 동기화 메시지를 라우팅하느냐다.
Liveblocks
프랑스 스타트업. 2024년 Boldstart에서 Series A. 매니지드 협업 백엔드의 1등 후보.
- Yjs 그대로 — 사용자가 짠 Yjs 코드를 Liveblocks 위에서 그대로 굴린다.
- 고유 자료형 —
LiveObject,LiveList,LiveMap— Yjs 없이도 단순 협업이 필요하면 쓰는 자료형. - 댓글·알림 — Notion 댓글 같은 기능이 SDK에 내장.
@liveblocks/react— 리액트 훅 풀.Threads,Inbox— 사전 빌트 댓글 UI 컴포넌트.
가격은 MAU 기반. 1만 MAU까지 무료, 그 이상부터 유료.
Partykit
Sunil Pai(전 Cloudflare·React 코어 멤버)가 시작. 2024년 Cloudflare에 인수됨.
- Cloudflare Durable Objects 위에 빌드 — 룸 단위로 영구 상태 + 글로벌 라우팅.
- Yjs 통합 —
y-partykit어댑터. - 임의 코드 가능 — Liveblocks가 닫힌 API라면, Partykit은 사용자가 서버 로직을 직접 짠다.
- 저렴함 — Cloudflare 가격 모델 그대로. CRDT의 매니지드 진영에서 가장 싸다.
y-redis / y-mongodb-provider
자가 호스트 진영. Yjs 도큐먼트를 Redis나 MongoDB에 영속화한다.
- 가장 싸고 가장 시간이 든다.
- 클라우드 사용량이 적거나, 보안·법규로 매니지드를 못 쓸 때.
의사결정 매트릭스
| 시나리오 | 후보 |
|---|---|
| Notion 클론 — 댓글까지 | Liveblocks |
| 작은 사이드 프로젝트 — Cloudflare 우선 | Partykit |
| 엔터프라이즈 자가 호스트 | y-websocket + y-redis |
| 글로벌 엣지 — 가격 최우선 | Partykit |
| Slack 풍 메시지 + 협업 도큐먼트 | Liveblocks |
8장 · ElectricSQL vs PowerSync — Postgres와 SQLite 양방향 동기화
조금 다른 진영. 텍스트나 JSON 트리 CRDT가 아니라 "관계형 DB 자체를 클라이언트에 복제"하는 접근.
ElectricSQL
벨기에·EU 기반 팀. Postgres 위에 logical replication을 얹어, 클라이언트의 SQLite로 데이터를 흘려보낸다. 클라이언트의 변경은 위로 올라가 머지된다.
- 서버: Postgres + Electric service — Electric은 Elixir로 짜인 동기화 게이트웨이.
- 클라이언트: SQLite —
@electric-sql/client라이브러리. - Shape — 동기화 단위. SQL where절로 부분 데이터만 가져옴.
- 2024 피벗 — Local-first 풀스택 프레임워크에서 "Postgres → SQLite 동기화 엔진"으로 단순화됐다.
import { ShapeStream } from '@electric-sql/client'
const stream = new ShapeStream({
url: 'https://api.example.com/v1/shape',
params: {
table: 'tasks',
where: 'user_id = $1',
params: ['user-123'],
},
})
stream.subscribe((messages) => {
for (const m of messages) {
console.log(m.headers.operation, m.value)
}
})
PowerSync
호주 기반 팀. 모바일 우선. ElectricSQL과 비슷한 아이디어지만 다른 강조점.
- 클라이언트 우선 — React Native·Flutter·iOS·Android SDK가 1차.
- 백엔드 DB 자유 — Postgres뿐 아니라 MongoDB·MySQL도 지원 시도 중.
- PowerSync rules — SQL-like 룰로 어떤 행이 어떤 사용자에게 동기화되는지 정의.
어떤 진영이 어떤 경우에 쓰이나
| 시나리오 | ElectricSQL | PowerSync |
|---|---|---|
| 웹 우선, Postgres만 | 1등 | 가능 |
| 모바일 우선 (Flutter·RN) | 가능 | 1등 |
| 오프라인 며칠 후 머지 | 가능 | 1등 |
| Notion 풍 트리 편집 | 부적합 | 부적합 |
| 단순 row-based SaaS | 1등 | 1등 |
이 진영의 한계: 동시 텍스트 편집·트리 이동 같은 CRDT 고유 문제는 해결하지 않는다. 그건 Yjs·Loro의 일이다.
9장 · Tinybase — 작은 인메모리 DB + 선택적 CRDT
Tinybase는 James Pollack이 단독으로 만든 라이브러리. "10KB 짜리 인메모리 데이터베이스 + 옵션으로 CRDT". 2023~2025년 사이 빠르게 성장.
왜 Tinybase가 흥미로운가
- 단순함 —
setRow,getRow,delRow. Redux의 store 같은 추상화에 reactive 쿼리를 얹었다. - 작음 — minified 50KB 미만.
- CRDT는 선택 — 기본은 LWW. 필요하면 Yjs 어댑터를 붙인다.
- 인덱서·메트릭·체크포인트 — 기본 기능이 풍부.
- 2025 —
MergeableStore— Tinybase 자체에 가벼운 CRDT 머지가 들어갔다. Yjs를 안 끼고 단순 LWW로 동기화 가능.
Tinybase 스켈레톤
import { createStore, createMergeableStore } from 'tinybase'
const store = createMergeableStore('store-1')
store.setTable('tasks', {
t1: { title: '논문 읽기', done: false },
t2: { title: 'CRDT 글 쓰기', done: false },
})
store.setCell('tasks', 't1', 'done', true)
// 다른 클라이언트와 머지
const otherStore = createMergeableStore('store-2')
otherStore.setTable('tasks', {
t3: { title: '코드 리뷰', done: false },
})
const merged = store.merge(otherStore)
console.log(merged.getTable('tasks')) // t1, t2, t3 모두 보임
Tinybase는 Yjs·Loro 같은 일반 CRDT 엔진의 대체재가 아니다. 더 작고 더 단순한, 다른 진영이다.
10장 · 어떤 엔진을 선택해야 하나? 결정 프레임워크
다음 결정 트리는 2026년 5월 기준 내가 추천하는 우선순위다.
협업 텍스트 에디터 (Notion·Linear·Slab 풍)
- Yjs + TipTap/BlockNote/Lexical — 가장 빠른 시작. 어댑터 풍부.
- Loro + ProseMirror — 2026년 새 프로젝트면 평가 가치. 알고리즘 더 옳음.
- Automerge 3 — JSON 도큐먼트 동기화가 핵심이면.
호스팅: Liveblocks(빠른 출시) → Partykit(저렴) → y-redis 자가 호스트(가장 비싸지만 자유).
모바일 오프라인 우선 앱 (의료·물류·현장)
- PowerSync — Flutter/RN SDK가 1등.
- ElectricSQL — Postgres 진영이면 후보.
- WatermelonDB — Nozbe 팀의 RN-우선 대안. 의외로 안정.
호스팅: Supabase + ElectricSQL, 또는 자체 Postgres + PowerSync.
B2B SaaS의 인스턴트 UI (Linear 풍)
- Zero — 2026년 새 프로젝트의 가장 흥미로운 선택. ZQL이 만족스러우면.
- Replicache — 1.x 안정. 큰 회사들의 채택 이력.
- Liveblocks + RDBMS — UI 협업만 필요하면.
단순 멀티플레이 사이드 프로젝트
- Liveblocks — 30분 안에 띄움.
- Partykit — Cloudflare Workers 진영이면.
- Tinybase MergeableStore — 가벼운 진영.
데이터 모델별 가이드
| 데이터 모델 | 1순위 | 2순위 |
|---|---|---|
| 리치 텍스트 한 덩어리 | Yjs | Loro |
| 블록 트리 (Notion 풍) | Loro | Yjs (어색) |
| JSON 도큐먼트 | Automerge 3 | Loro |
| 관계형 row | Zero | Replicache |
| 단순 LWW key-value | Tinybase | Replicache |
| 모바일 SQLite 미러 | PowerSync | ElectricSQL |
11장 · 한국과 일본 시장의 로컬-퍼스트
한국·일본의 SaaS 시장은 2025~2026 들어 로컬-퍼스트 패턴을 적극 받기 시작했다.
한국
- 노션 클론들 — 슬리드·노션라이크 도구들이 Yjs를 기반으로 짜졌다. 슬리드는 Liveblocks 후보였지만 자가 호스트로 갔다는 후문.
- 카카오 워크의 협업 도큐먼트 — 2025년 베타로 나온 도큐먼트 기능이 Yjs 기반. ProseMirror + y-prosemirror.
- 네이버 메모 — 2026년 봄 리뉴얼에서 멀티 기기 동기화를 강화. Replicache류 아키텍처로 추정.
- 토스 페이먼츠의 가맹점 도구 — 오프라인 가능한 매출 입력 도구가 PowerSync 후보. 직접 채택은 미공개.
일본
- LINE Notes — 2026년 초 멀티-기기 협업 메모. 내부적으로 Yjs 진영의 어댑터를 만들었다는 소문.
- Sansan/Eight — 명함 동기화에 SQLite-on-the-edge + 자체 CRDT를 쓴다는 발표(JJUG 2025).
- Mercari Mini — 2025년 진출 시도. 일본의 오프라인 모바일 결제 환경에서 PowerSync 도입 검토.
- Hatena/Cybozu — 사내 협업 도구에 Yjs 진영을 일부 채택.
두 시장의 공통점
- 보안·법규 때문에 매니지드 SaaS(Liveblocks·Partykit)보다 자가 호스트 선호.
- 통신사 모바일 환경이 양호해 ElectricSQL/PowerSync의 절박함이 동남아시아만큼 크진 않다.
- 협업 에디터 진영은 Yjs가 압도적. Loro는 2026년 들어서야 진지하게 검토되기 시작.
12장 · 참고 / References
- Ink and Switch, "Local-first software: You own your data, in spite of the cloud" (2019) — https://www.inkandswitch.com/local-first/
- Martin Kleppmann, Adam Wiggins, Peter van Hardenberg, Mark McGranaghan, original local-first essay
- Yjs documentation — https://docs.yjs.dev/
- Kevin Jahns, "Near Real-Time Optimistic Replication" (YATA paper)
- Automerge 3 announcement — https://automerge.org/
- Loro documentation — https://loro.dev/
- Loro 1.0 release notes (2025)
- Fugue: A Generic Text Replication Algorithm — https://arxiv.org/abs/2305.00583
- Replicache documentation — https://doc.replicache.dev/
- Zero by Rocicorp — https://zero.rocicorp.dev/
- Liveblocks documentation — https://liveblocks.io/docs
- Partykit documentation — https://docs.partykit.io/
- ElectricSQL documentation — https://electric-sql.com/docs
- PowerSync documentation — https://docs.powersync.com/
- Tinybase documentation — https://tinybase.org/
- TipTap collaboration docs — https://tiptap.dev/docs/collaboration
- BlockNote documentation — https://www.blocknotejs.org/
- WatermelonDB — https://watermelondb.dev/
- "A move operation for replicated trees" — Kleppmann, Mulligan, Gomes, Beresford
- "CRDTs: The Hard Parts" — Martin Kleppmann talk
- JJUG CCC 2025 — Sansan/Eight CRDT talk (Japanese)
다음 글에서는 이 중 두세 엔진을 골라 같은 협업 도구를 직접 구현해 보는 hands-on을 다룬다. 알고리즘이 아니라 실전 코드의 모서리에서 무슨 일이 일어나는지를.