Local-First / Offline / CRDT / Sync

    Local-First Software 2024

    Jazz.tools (CRDT), PowerSync (Postgres sync), ElectricSQL, Dexie.js, PGlite i offline-first patterns.

    Jazz.tools
    CRDT
    PowerSync
    Postgres sync
    Dexie.js
    IndexedDB
    PGlite
    Postgres WASM

    6 narzędzi Local-First — podejście i kiedy

    Jazz, PowerSync, ElectricSQL, Dexie, PGlite i Automerge/Yjs — podejście do sync i kiedy wybrać.

    Narzędzie Podejście Sync Kiedy
    Jazz.tools Co-values (CRDT) WebSocket + P2P Collaborative TypeScript apps, real-time
    PowerSync Postgres -> SQLite Postgres connector React + Postgres, offline-critical mobile
    ElectricSQL Postgres CRDT sync Electric protocol Nowe projekty Postgres, edge sync
    Dexie.js IndexedDB wrapper Dexie Cloud (opcja) Offline storage, reactive queries w przeglądarce
    PGlite Postgres WASM ElectricSQL opcja Full Postgres w przeglądarce, SQL-first
    Automerge / Yjs CRDT library Własny transport Collaborative editing, custom sync layer

    Często zadawane pytania

    Local-First Software — co to jest i dlaczego ważne?

    Local-First Software: Martin Kleppmann, Ink & Switch. Dane primarly na urządzeniu. Synchronizacja peer-to-peer lub z serwerem. Offline-first (nie tylko PWA offline). Aplikacja działa bez internetu. Sync gdy połączenie dostępne. Zalety: szybkość (brak network latency). Offline niezawodność. Privacy (dane lokalnie). Współpraca w czasie rzeczywistym. Brak vendor lock-in (dane twoje). Wady: sync jest trudny (konflikty). Migracje schematu skomplikowane. Security (dane na urządzeniu). Nie dla każdej aplikacji. CRDT (Conflict-free Replicated Data Types): matematycznie poprawne merge. Bez konfliktów przy edycji jednoczesnej. Typy: LWW (Last-Write-Wins Register). G-Counter, PN-Counter. OR-Set. RGA (Replicated Growable Array). G-Tree. Yjs: CRDT biblioteka. Collaborative editing. WebSocket lub WebRTC sync. SyncedStore — Yjs + MobX/Zustand. Automerge: CRDT z Jason Kester, Martin Kleppmann. JSON-like structure. History tracking. Merge od razu. Przykłady local-first apps: Figma — real-time collaborative. Linear — ultra-fast, offline-capable. Notion — local-first w web. Obsidian — pliki markdown lokalne. Loom — wideo lokalne. Ink & Switch Demos: Pixel pusher, Kanban, peritext.

    Jazz.tools — Local-First framework dla TypeScript?

    Jazz: Anselm Eickhoff. Local-first TypeScript framework. Co-values (collaborative values). WebSocket sync. Crypto auth. Instalacja: npm install jazz-tools @jazz-tools/react. Podstawy: import {co, coStream, CoList, CoMap} from 'jazz-tools'. import {useAccount, useCoState} from '@jazz-tools/react'. Schema: const TodoItem = co.map({title: co.string, done: co.boolean}). const TodoList = co.map({items: co.list(TodoItem)}). Account creation: const account = await createJazzBrowserContext({peer: 'wss://cloud.jazz.tools/?key=...'}). useAccount: const {me} = useAccount(TodoSchema, {resolve: {root: {todos: [{items: true}]}}}). useCoState: const todo = useCoState(TodoItem, id). Edit: todo.done = true — reaktywne! Sync automatyczny. Permissions: Account, Group, Everyone. Group: shareable. invite link. Jazz Cloud: bezpłatny sync server. Własny: jazz.tools/docs/jazz-self-hosting. Offline: działa bez internetu. Queue sync. Reactive: zmiany propagują do wszystkich subskrybentów. CoList: reaktywna lista. me.root.todos.push(newItem). Optymistyczne update. Kiedy Jazz: collaborative app. Real-time sync. Offline-first. TypeScript codebase. Nie dla: dużych zbiorów danych. Relacyjne zapytania. Public read-only content.

    PowerSync i ElectricSQL — Postgres sync dla local-first apps?

    PowerSync: JourneyApps. Postgres -> SQLite sync. Offline-first. React Native i Flutter. Instalacja: npm install @powersync/react. Konfiguracja: const db = new PowerSyncDatabase({schema, database: new WASQLiteOpenFactory('powersync.db')}). await db.connect(new MyConnector()). Connector: uploadData — sync do Postgres. fetchCredentials — JWT auth. Schema: const todoTable = new Table({list_id: column.text, description: column.text, completed: column.integer}). export const AppSchema = new Schema({todos: todoTable}). Zapytania: const {data: todos} = useQuery(db.watch('SELECT * FROM todos WHERE list_id = ?', [listId])). Real-time watch — jak reactive Supabase. Write: await db.execute('INSERT INTO todos (id, description) VALUES (?, ?)', [uuid(), description]). Upload queue: automatyczny. Sync rules: Postgres -> PowerSync. Filtry per user. ElectricSQL: James Arthur. Postgres sync. TypeScript client. CRDT-based. Instalacja: npm install electric-sql. Sync: await electric.connect(token). const db = electrify(rawDb, schema, config). Shapes: await electric.db.todos.sync({where: {user_id: userId}}). Zapytania: reaktywne. Podejście: ElectricSQL bardziej eksperymentalne. PowerSync bardziej produkcyjne. RxDB: Offline-first database. CouchDB sync. Rxjs reactive queries. Dexie.js: IndexedDB wrapper. Nie sync ale offline storage. Triplit: nowy, full-stack. TypeScript schema. Kiedy PowerSync: React + React Native. Postgres backend. Offline critical. Kiedy ElectricSQL: nowy projekt, Postgres, edge sync.

    IndexedDB, Dexie.js i PGlite — lokalne bazy danych w przeglądarce?

    IndexedDB: wbudowana baza przeglądarki. Transakcyjny. Asynchroniczny. Duże dane. Skomplikowane API. Dexie.js: wrapper nad IndexedDB. Prosty. Promise-based. Reactive. TypeScript. Instalacja: npm install dexie dexie-react-hooks. Schema: const db = new Dexie('MyDatabase'). db.version(1).stores({todos: '++id, title, done'}). CRUD: await db.todos.add({title, done: false}). const todos = await db.todos.where({done: false}).toArray(). useLiveQuery: import {useLiveQuery} from 'dexie-react-hooks'. const todos = useLiveQuery(() => db.todos.toArray()). Reaktywne! Aktualizuje gdy zmiany. Dexie Cloud: sync do chmury. Multi-device. Collaboration. Podobny do Jazz/PowerSync. PGlite (Electric SQL team): PostgreSQL w WebAssembly. Pełny Postgres w przeglądarce! Extensions: vector, pg_dump. Instalacja: npm install @electric-sql/pglite. import {PGlite} from '@electric-sql/pglite'. const db = new PGlite(). await db.exec('CREATE TABLE todos (id SERIAL, title TEXT, done BOOL DEFAULT false)'). const todos = await db.query('SELECT * FROM todos'). Użycie z ORM: drizzle-orm/pglite. Pełny SQL syntax. JOIN, transactions, etc. Sync z ElectricSQL: PGlite + electric sync. sql.js alternatywa: SQLite w WebAssembly. Starszy. Mniej feature-rich. wa-sqlite: SQLite WASM. Virtual File System. Persystencja przez OPFS (Origin Private File System). Origin Private File System: nowe API. Persystencja IndexedDB-like ale szybsza. Dostęp plikowy. Bun SQLite: tylko w Bun runtime.

    Offline-First architecture — wzorce i narzędzia 2024?

    Offline-First patterns: Offline as default: zakładaj brak internetu. UI działa zawsze. Sync gdy możliwe. Nie pokazuj 'brak połączenia' = błąd. Optimistic UI: aplikuj lokalnie natychmiast. Sync w tle. Rollback gdy sync fail. Zamiast czekać na server. Conflict resolution: Last-Write-Wins (prosto). CRDT (bez konfliktów). Operational Transform (Google Docs style). Custom merge logic (complex). Cache strategies: Cache-first: lokalny cache, potem sync. Network-first: próba sieci, fallback na cache. Stale-while-revalidate: cache natychmiast, background refresh. Service Worker + Cache API: const cache = await caches.open('v1'). await cache.put(request, response). const cached = await cache.match(request). Background Sync API: SyncManager.register('sync-tag'). Event: sync. Wykonaj gdy online. BullMQ lub własna queue: operacje do synchronizacji. Gdy offline -> queue. Gdy online -> execute. IndexedDB jako offline store. Conflict-free data structures: Immutable. Append-only log (event sourcing). CRDT types per use case. React Query offline: networkMode: 'offlineFirst'. Pauzuje queries gdy offline. Resume gdy online. TanStack Query + ServiceWorker. Zustand persist: persists: state -> localStorage/IndexedDB. Powraca przy reload. Bez serwera. Realtime sync po reconnect: WebSocket reconnection. EventSource (SSE) reconnection. Socket.io built-in. Supabase Realtime reconnect.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz