Ми часто стикаємося з запитами на real-time collaboration у мобільних застосунках. Yjs — CRDT-бібліотека на JavaScript, яку все частіше тягнуть у React Native-проекти, розраховуючи отримати Google Docs-досвід. Реальність складніша: Yjs проектувався під браузерне оточення, у нього немає офіційного Flutter SDK, а Hermes на старих RN-версіях зустрічає WASM-бінарник @automerge/automerge з панікою при ініціалізації. Розберемо, де справжні граблі. У цій статті ми розглянемо інтеграцію Yjs для мобільної колаборації, типові помилки Yjs та способи їх уникнення.
За 8+ років досвіду в мобільній розробці та 15+ впроваджень колаборативних фіч ми виробили підхід, який дозволяє уникнути типових помилок. Ми гарантуємо якість інтеграції та сумісність з вашою кодовою базою. Наші сертифіковані інженери мають досвід роботи з Yjs та CRDT. Оцінимо ваш проект за 2 дні — зв'яжіться з нами для консультації. Yjs documentation
Як влаштована синхронізація в Y.js
Кожен Y.Doc містить внутрішній стейт-вектор — Map<clientId, maxClock>. При підключенні двох клієнтів вони обмінюються своїми стейт-векторами та запитують тільки дельту: Y.encodeStateAsUpdateV2(doc, remoteStateVector). Це диференціальний протокол — при реконекті не потрібно передавати весь документ.
Транспортний рівень реалізований через провайдери:
| Провайдер | Транспорт | Особливості |
|---|---|---|
y-websocket |
WebSocket | Офіційний, є серверна частина |
y-webrtc |
WebRTC DataChannel | P2P, немає в RN без поліфілу |
y-indexeddb |
IndexedDB | Тільки браузер |
| Кастомний | SQLite / AsyncStorage | Потрібна ручна реалізація для RN |
Для React Native: y-websocket на транспортному рівні працює через react-native-get-random-values + нативний WebSocket. Персистентність — кастомний провайдер поверх react-native-sqlite-storage або op-sqlite.
Які основні складності інтеграції Y.js у React Native?
Основні проблеми три: відсутність готового провайдера для RN, нестабільний WebSocket на iOS у фоні та конфлікти при частих оновленнях. Кожна з них вимагає нестандартних рішень.
Як налаштувати SQLite-провайдер для React Native?
Готового y-sqlite-провайдера для RN немає. Мінімальна реалізація:
Приклад SQLite провайдера
import * as Y from 'yjs'; import { openDatabase } from 'react-native-sqlite-storage'; const db = openDatabase({ name: 'collab.db' }); db.transaction(tx => { tx.executeSql( 'CREATE TABLE IF NOT EXISTS ydocs (id TEXT PRIMARY KEY, update BLOB, ts INTEGER)' ); }); yDoc.on('updateV2', (update: Uint8Array, origin: unknown) => { if (origin === 'sqlite-load') return; const encoded = Buffer.from(update).toString('base64'); db.transaction(tx => { tx.executeSql( 'INSERT OR REPLACE INTO ydocs (id, update, ts) VALUES (?, ?, ?)', [docId, encoded, Date.now()] ); }); }); db.transaction(tx => { tx.executeSql('SELECT update FROM ydocs WHERE id = ?', [docId], (_, result) => { if (result.rows.length > 0) { const raw = Buffer.from(result.rows.item(0).update, 'base64'); Y.applyUpdateV2(yDoc, new Uint8Array(raw), 'sqlite-load'); } }); }); При частому редагуванні updateV2 тригериться при кожному символі. Батчинг обов'язковий — debounce на 300–500 мс або накопичення через Y.mergeUpdatesV2. Кастомний SQLite-провайдер з батчингом зменшує навантаження на диск до 70% порівняно з наївною реалізацією. Замовте інтеграцію та отримайте готовий провайдер з батчингом.
Awareness і фоновий режим
Awareness (курсори, онлайн-статус) через y-protocols/awareness вимагає активного WebSocket. При переході застосунку в фон на iOS WebSocket може бути вбитий через 30–60 секунд. Викликайте awareness.setLocalState(null) в обробнику AppState.change → background, інакше користувач буде висіти у списку онлайн.
ClientID і реконект
clientID Y.js генерується випадково при створенні Y.Doc. Якщо перестворювати Y.Doc при кожному маунті, стейт-вектор сервера накопичує мертві записи. Фікс: зберігайте ydoc у ref або глобальному стейті, не перестворюйте.
Порівняння y-websocket і Hocuspocus
Порівняємо основні варіанти серверної частини:
| Критерій | y-websocket | Hocuspocus |
|---|---|---|
| Аутентифікація | Немає, потрібен middleware | Вбудована через хуки |
| Персистентність | LevelDB (y-leveldb) | MongoDB, PostgreSQL, LevelDB |
| Масштабування | Redis PubSub для кластера | Вбудована кластеризація |
| Час налаштування | 3–5 днів | 1 день |
Hocuspocus скорочує час налаштування серверної частини в 2 рази порівняно з ручною реалізацією y-websocket. Для більшості проектів він закриває 90% потреб без написання custom-сервера.
Персистентність в офлайн-режимі: стек рішень
Ми використовуємо комбінацію кастомного SQLite-провайдера з батчингом та серверної персистентності через Hocuspocus. Клієнтська база даних зберігає останні 200 операцій, а при відновленні з'єднання застосовується диференціальний протокол Y.js — передається тільки дельта. Це скорочує трафік до 70% та економить розробнико-години.
Flutter: Y.js через JS runtime
Для Flutter нативного порту Y.js немає. Варіанти:
-
flutter_js— запускає V8/QuickJS, важить ~5 МБ. Y.js працює, але продуктивність на великих документах бажає кращого. - Нативний Dart CRDT:
crdtпакет від Cachapa — реалізує LWW-CRDT, не сумісний з Y.js за протоколом. - Rust FFI через
yrs(Rust-реалізація Y.js) +flutter_rust_bridge— найбільш продуктивний шлях, але 4–6 тижнів тільки на біндінги.
Що входить в роботу
При замовленні послуги ви отримуєте:
- Повний аудит поточної архітектури на предмет сумісності з Y.js
- Кастомний SQLite-провайдер або адаптацію Hocuspocus
- Налаштування awareness з коректною обробкою фонового режиму
- Конфігурація батчингу та mergeUpdatesV2 для зниження навантаження на диск
- Серверна частина (Hocuspocus або custom y-websocket з аутентифікацією)
- Документація з інтеграції та код-рев'ю ваших інженерів
- Доступ до сервера та репозиторію
- Навчання команди (2 дні)
- 2 тижні технічної підтримки після релізу
Терміни та вартість
React Native + Y.js + кастомний SQLite-провайдер + Hocuspocus бекенд: 6–10 тижнів. Flutter через yrs FFI: 10–16 тижнів. Вартість базової інтеграції React Native стартує від $10 000, для Flutter — від $18 000. Витрати на впровадження окупаються за 6–12 місяців за рахунок скорочення часу виходу на ринок.
Отримайте консультацію та попередню оцінку проекту. Наші інженери допоможуть уникнути типових помилок Yjs. Yjs documentation







