Offline-first synchronization for Flutter apps that need durable writes, deterministic conflict resolution, and generated adapters.
SyncForge is a backend-agnostic offline synchronization framework for Flutter applications. It combines CRDT-based conflict resolution, vector clocks, optimistic local updates, code generation, and pluggable storage and transport adapters to simplify building resilient offline-first products.
The synchronization engine is implemented in pure Dart, making it portable, testable, and independent of Flutter.
- Core package
- Drift adapter
- Generator package
- Architecture
- Sync protocol
- Contributing
- Support policy
- Security
flowchart TD
Model["@Syncable model"] --> Generator["Generated adapter + serializer"]
Generator --> Engine["SyncEngine"]
Engine --> Storage["SyncStorage / Drift"]
Engine --> Transport["SyncTransport"]
Transport --> Backend["Backend API"]
Backend --> Engine
SyncForge is designed for teams that want the control of a custom sync stack without the maintenance burden of building one from scratch.
- Durable local writes that survive restarts
- Deterministic merge behavior for concurrent edits
- A generated adapter layer instead of handwritten serialization glue
- A Drift-backed storage path for real offline persistence
- A transport abstraction that works with REST-style backends and custom APIs
- Clear protocol docs so sync behavior is explainable, testable, and supportable
@Syncable models
│
▼
Generated adapters and serializers
│
▼
SyncEngine
├── SyncStorage → Drift-backed persistence
└── SyncTransport → REST, GraphQL, custom backend
SyncForge separates synchronization logic from storage and networking, allowing applications to integrate with existing backends without changing the synchronization engine.
- Solo Flutter developers who need offline writes without inventing a sync protocol.
- Product teams building note, task, field service, or collaboration apps.
- Enterprise apps that need deterministic recovery, auditability, and restart-safe persistence.
- Define a synchronizable model:
@Syncable()
class Todo {
const Todo({
required this.id,
required this.title,
});
@Id()
final String id;
@ConflictStrategy(ConflictType.lastWriteWins)
final String title;
}- Generate the synchronization code:
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs- Create a
SyncEngineinstance:
final sync = SyncEngine(
storage: storage,
transport: transport,
nodeId: "device-a",
adapters: {
Todo: const TodoSyncAdapter(),
},
);- Offline-first architecture
- Pure Dart CRDT engine
- Vector clock–based causal ordering
- Per-field conflict resolution
- Optimistic writes with automatic rollback
- Durable outbox with retry and dead-letter handling via the Drift adapter
- Tombstone-based deletion support
- Annotation-driven code generation
- Generator-time rejection of unsupported custom merge strategies
- Drift storage adapter
- Backend-agnostic transport abstraction
- Comprehensive property-based and convergence testing
The core synchronization library implemented in pure Dart.
Includes:
- Vector clocks
- CRDT implementations
- Synchronization protocol
- Optimistic write pipeline
- Conflict resolution
- Serialized sync execution and cursor validation
- Public synchronization API
Code generation using build_runner.
Generates:
- Sync adapters
- Serializers
- Merge logic
- Adapter registry
Unsupported ConflictType.custom fields fail generation instead of crashing at runtime.
A production-ready Drift storage implementation featuring:
- Durable persistence
- Tombstones
- Acknowledgements
- Frontier pruning
- Schema versioning
- Durable outbox persistence with retry metadata and dead letters
The repository includes several example applications, each optimized for a different stage of adoption.
| Example | Description |
|---|---|
minimal_app |
Smallest possible integration path |
notes_app |
External consumer example with persisted local state |
task_manager |
Full-featured production-style synchronization example |
conflict_playground |
Interactive visualization of concurrent conflict resolution |
Start with:
- minimal_app for a five-minute integration.
- notes_app for a consumer-owned app structure.
- task_manager for transport and retry behavior.
- conflict_playground for a live merge demo.
SyncForge combines multiple conflict-resolution strategies.
- Vector clocks provide causal ordering.
- Per-field Last-Write-Wins (LWW) resolves concurrent edits independently for each field.
- GCounter provides monotonic distributed counters.
- GSet provides grow-only replicated sets.
- Tombstones ensure deletes converge correctly across replicas.
This design allows unrelated concurrent edits to be preserved while maintaining deterministic convergence.
Further details are available in:
docs/SYNC_PROTOCOL.mdpackages/sync_engine_drift/DESIGN.md
SyncForge is designed to scale from a handful of offline writes to large queues and repeated reconnect cycles. The repository validates the sync path, generator output, durable outbox behavior, and example-app workflows in CI.
For production evaluation, review:
packages/sync_engine/test/packages/sync_engine_drift/test/packages/sync_engine_generator/test/example/task_manager/test/example/notes_app/test/
| Capability | SyncForge | Hand-rolled sync | Backend SDK only | Local cache only |
|---|---|---|---|---|
| Offline writes | Yes | Usually partial | Usually no | Yes |
| Durable outbox | Yes | Rarely | No | No |
| Deterministic conflict handling | Yes | Varies | Varies | No |
| Generated adapters | Yes | No | No | No |
| Drift-backed persistence | Yes | Possible | No | Yes |
| Protocol documentation | Yes | Usually no | Usually no | No |
The project includes extensive automated verification:
- Unit tests
- Integration tests
- Property-based CRDT verification
- Replica convergence testing
- Generator fixture validation
- Widget tests
- External consumer integration tests
Randomized property tests verify CRDT correctness across thousands of merge scenarios.
dart pub global activate melos 2.9.0
melos bootstrap
melos run generate
melos run analyze
melos run testDoes SyncForge replace my backend? No. It coordinates local synchronization and transport, but your backend still owns authentication, authorization, and server-side data rules.
Can I use a custom backend?
Yes. Implement SyncTransport for your API shape.
Do I have to use Drift? No. Drift is the production storage adapter included in this repository, but the core engine is storage-agnostic.
Can I customize conflict resolution? Yes for supported strategies. Unsupported custom merge behavior is rejected at generation time rather than failing at runtime.
docs/SYNC_PROTOCOL.md— Synchronization protocol specificationARCHITECTURE.md— System architecturedocs/CONTRIBUTING.md— Contribution guidelinesdocs/RELEASE_CHECKLIST.md— Release processpackages/sync_engine_drift/DESIGN.md— Drift implementation detailsSUPPORTED_VERSIONS.md— Supported runtime and maintenance policySECURITY.md— Security reporting guidanceCODE_OF_CONDUCT.md— Community standards
If you are evaluating SyncForge for a production app:
- Start with the minimal example.
- Read the sync protocol.
- Review the task manager example for HTTP transport behavior.
- See BACKEND_INTEGRATION.md for adapter boundaries.
The current codebase is production-ready for the supported core workflow. Codex and GPT 5.6 accelerated development by helping generate:
- CRDT implementation scaffolding
- test infrastructure
- generated adapter patterns
- documentation
Future work centers on additional storage adapters, transport integrations, observability hooks, and richer enterprise deployment guidance.
Released under the MIT License.