Sync Engine

Offline-first synchronization without the complexity.
Annotate your domain classes, connect user storage, done.

The Vision

What if building offline-first, cloud-synced apps was as simple as annotating your domain classes?

1

Annotate Your Classes

Use RDF mapper and CRDT annotations on your domain models. Define conflict resolution strategies right in your code.

@LcrdRootResource(PersonalNotesVocab.NotesCategory)
class Category {
  @RdfIriPart()
  final String id;

  /// Last writer wins on conflicts
  @RdfProperty(SchemaCreativeWork.name)
  @CrdtLwwRegister()
  final String name;

  /// Immutable - can't be changed after creation
  @RdfProperty(SchemaCreativeWork.dateCreated)
  @CrdtImmutable()
  final DateTime createdAt;

  /// Preserve unmapped triples for interoperability
  @RdfUnmappedTriples(globalUnmapped: true)
  final RdfGraph other;

  Category({
    required this.id,
    required this.name,
    DateTime? createdAt,
    RdfGraph? other,
  }) : createdAt = createdAt ?? DateTime.now(),
       other = other ?? RdfGraph();
}
2

Connect User Storage

Use our pre-built UI widgets. Users connect their Google Drive, Solid Pod, or other storage with simple clicks.

Connect Your Storage
πŸ“ Google Drive
πŸ”’ Solid Pod
☁️ Dropbox
3

Sync Automatically

That's it. Your app is now fully synchronized across all devices, using the user's own storage as the cloud backend.

πŸ“±
↔️
☁️
↔️
πŸ’»

Key Features

πŸ”„ Conflict-Free Synchronization

State-based CRDT algorithms ensure safe collaboration without coordination. Multiple devices can edit simultaneously without data loss.

🌐 Semantic Interoperability

All data stored as clean, standard RDF for maximum compatibility. Your data remains accessible and interoperable.

πŸ“± Offline-First

Full offline functionality with automatic sync when connectivity is available. Your app works everywhere.

πŸ”’ Privacy-Preserving

User data stays in their own storage. No vendor lock-in, no centralized database, complete data ownership.

⚑ Performance at Scale

Flexible indexing and fetch strategies keep sync fast as your dataset grows. Tested with ~15k resources; smart sharding is designed to scale further.

🎯 Not a Database

Store your domain instances however you like. The sync engine only handles synchronization, not storage architecture.

Early Access

The core idea works. Try it out, build something real, and tell us what you need.

βœ…

Works Today

  • Google Drive backend β€” fully implemented and tested
  • Offline-first sync with CRDT conflict resolution
  • File-per-resource layout (Solid Pods, linked-data interop)
  • Packed layouts: single-file and sharded (Google Drive)
  • Tested with ~15 000 resources
  • Core application API is stable
🚧

Known Gaps

  • Solid backend: each sync requires many HTTP requests β€” Solid Protocol currently has no batch-write operation. This is a protocol-level limitation, not something we can fix on our side. It is on the Solid roadmap, but progress there is slow.
  • ensure and delete operations not yet implemented
  • Delta layout not yet available β€” the full packed file is uploaded/downloaded each cycle, even for small changes
  • Limited set of CRDT types (LWW register, immutable, OR-Set; more planned)
  • Non-initial sync performance has room for optimization
πŸ”¬

Stability

  • Core application API (annotations, mapper): stable
  • Backend implementation API and exchanged data format (index shards, wire protocol): may have breaking changes
  • Not production-ready yet β€” but definitely worth exploring

Other backends beyond Google Drive are planned. Contributions are very welcome.

Configure Your Storage Layout

Two independent axes give you full control: the layout determines how many cloud files hold your data, while the serialization format determines how each file is encoded.

🌐

File-per-Resource Layout

Required for Solid Pods Β· works everywhere

Each managed resource lives in its own file. Fully linked-data compliant: any Solid-compatible tool or SPARQL client can read and write the data directly.

  • Maximum interoperability with other apps
  • Resources discoverable and addressable by IRI
  • More HTTP round-trips per sync cycle
  • Natural fit for Turtle encoding
Best for: open data, Solid ecosystem
⚑

Packed Layouts

Google Drive, Dropbox & any file-based backend

Multiple resources are grouped into fewer files β€” from a handful of shards down to a single file for the entire dataset. Bulk transfers dramatically reduce round-trips and speed up sync cycles.

  • Far fewer network requests per sync
  • Great fit for Jelly, TriG, or JSON-LD encoding
  • Single-file layout available; single-file-with-delta planned
  • Data not directly accessible by external RDF tools
Best for: private data, performance-critical apps

The serialization format β€” Turtle, Jelly, TriG, JSON-LD β€” is configured independently of the layout. For Solid interoperability Turtle is the natural choice; for packed layouts Jelly gives the best size and decode performance.

Architecture Overview

A 4-layer architecture designed for both simplicity and power

1

Data Resource Layer

Clean RDF resources using standard vocabularies

2

Merge Contract Layer

Public CRDT rules for conflict resolution

3

Indexing Layer

Efficient change detection and performance optimization

4

Sync Strategy Layer

Application-specific performance trade-offs

Real-World Output

This is the actual output from the example application running on a Solid Pod (interoperability mode). Notice the generated IRIs and the metadata required for synchronization β€” all handled automatically.

@prefix category_1762183405043_136175: <https://experiments2.solidcommunity.net/data/aHR0cHM6Ly9sb2NvcmRhLmRldi9leGFtcGxlL3BlcnNvbmFsX25vdGVzX2FwcC92b2NhYnVsYXJ5L3BlcnNvbmFsLW5vdGVzI05vdGVzQ2F0ZWdvcnk=/category_1762183405043_136175#> .
@prefix cm: <https://w3id.org/solid-crdt-sync/vocab/crdt-mechanics#> .
@prefix data: <https://experiments2.solidcommunity.net/data/aHR0cHM6Ly9sb2NvcmRhLmRldi9leGFtcGxlL3BlcnNvbmFsX25vdGVzX2FwcC92b2NhYnVsYXJ5L3BlcnNvbmFsLW5vdGVzI05vdGVzQ2F0ZWdvcnk=/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix idx: <https://w3id.org/solid-crdt-sync/vocab/idx#> .
@prefix mappings: <https://locorda.dev/example/personal_notes_app/mappings/> .
@prefix pn: <https://locorda.dev/example/personal_notes_app/vocabulary/personal-notes#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix schema: <https://schema.org/> .
@prefix smm10v: <https://experiments2.solidcommunity.net/indices/aHR0cHM6Ly93M2lkLm9yZy9zb2xpZC1jcmR0LXN5bmMvdm9jYWIvaWR4I1NoYXJk/index-full-0d7e421f/shard-mod-md5-1-0-v1_0_0#> .
@prefix sync: <https://w3id.org/solid-crdt-sync/vocab/sync#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

data:category_1762183405043_136175 a sync:ManagedDocument;
    foaf:primaryTopic category_1762183405043_136175:it;
    cm:clockHash "d66831f16d25da5c5169b148c9fdeb65";
    cm:createdAt "2025-11-03T15:23:25.160620Z"^^xsd:dateTime;
    cm:hasClockEntry category_1762183405043_136175:lcrd-clk-md5-fe24422ab1fb1e0d69d127bd0c3fd78a;
    idx:belongsToIndexShard smm10v:shard;
    sync:hasBlankNodeMapping category_1762183405043_136175:lcrd-ibn-md5-3c7f9db5b14024d37f19f8dd09ec7c84;
    sync:isGovernedBy (mappings:category-v1.ttl);
    sync:managedResourceType pn:NotesCategory .

category_1762183405043_136175:it a pn:NotesCategory;
    pn:archived false;
    pn:displaySettings _:b1;
    schema:dateCreated "2025-11-03T15:23:25.043734Z"^^xsd:dateTime;
    schema:dateModified "2025-11-03T15:23:25.043738Z"^^xsd:dateTime;
    schema:name "Rot" .

category_1762183405043_136175:lcrd-clk-md5-fe24422ab1fb1e0d69d127bd0c3fd78a cm:logicalTime 1;
    cm:physicalTime 1762183405159 .

category_1762183405043_136175:lcrd-ibn-md5-3c7f9db5b14024d37f19f8dd09ec7c84 sync:blankNode _:b1 .

_:b1 pn:categoryColor "red" .

You can see the complexity typically hidden from the developer: clock vectors for conflict resolution, index shard references, and blank node mappings - all handled automatically by the sync engine.

What Can You Build?

πŸ“ Note-Taking Apps

Sync notes across devices using the user's Google Drive or Solid Pod. No backend infrastructure needed.

βœ… Task Managers

Collaborative task lists that sync conflict-free. Each user's data stays in their own storage.

πŸ“š Knowledge Bases

Personal wikis and knowledge graphs that sync seamlessly across devices while preserving semantic structure.

🎨 Creative Tools

Design apps, recipe managers, or any domain-specific tool with built-in sync and data ownership.

Project Scope

πŸ“‹ Specification

Complete architectural documentation for building CRDT-enabled applications with passive storage backends across any programming language.

  • Complete CRDT-RDF architecture with formal vocabulary
  • Language-agnostic design patterns
  • Performance analysis and optimization strategies
  • Interoperability contracts for cross-application compatibility
⚠️ Outdated

The currently published specification is severely outdated. It has significant deviations from the actual implementation, and performance optimization work may cause further changes.

Read Specification β†’

πŸ› οΈ Dart Implementation

A multipackage Dart library that aims to become production-ready for real-world Flutter applications.

  • Full-featured library for collaborative applications
  • Complete API coverage of specification capabilities
  • Performance-optimized for mobile and web
  • Reference example for other language implementations
Implementation Details β†’

Get Involved

This project is open source and welcomes contributions from the community.