The SwiftData for Flutter. Zero-boilerplate, offline-first data persistence and sync for Dart.
Apple gave iOS developers SwiftData — a declarative, model-driven persistence layer that Just Works. Flutter deserved the same. dart_data is that answer.
Annotate your models. Get local SQLite persistence, cloud sync, conflict resolution, encryption, and reactive streams — with near-zero configuration.
@SyncModel(tableName: 'todos')
class Todo {
@SyncId()
final String id;
@SyncField(index: true)
final String title;
@SyncField()
final bool completed;
Todo({required this.id, required this.title, this.completed = false});
}final dd = await DartData.initialize(
databasePath: 'app.db',
schemas: [TodoSchema()],
);
final repo = dd.repository<Todo>(TodoSchema());
await repo.save(Todo(id: '', title: 'Buy milk'));
repo.watchAll().listen((todos) => updateUI(todos));
await syncEngine.sync();That's it. No boilerplate. No manual SQL. No sync plumbing.
| What you get | SwiftData | dart_data |
|---|---|---|
| Declarative models | @Model |
@SyncModel |
| Auto-persistence | Core Data + SQLite | SQLite with auto-schema |
| Cloud sync | CloudKit | REST, Firebase, Supabase |
| Conflict resolution | Last-write-wins | 6 strategies (LWW, field-merge, 3-way merge, ...) |
| Reactive queries | @Query |
watchAll() / watch() streams |
| Encryption | Data Protection | SQLCipher with key rotation |
| Code generation | Swift macros | build_runner + annotations |
| Platform | Apple only | Everywhere Dart runs |
- Offline-first — Writes hit local SQLite instantly. Sync happens in the background. Your app never blocks on the network.
- Zero-boilerplate — Annotate with
@SyncModel, runbuild_runner, get typed schemas, repositories, and migrations. - Full CRUD + reactive streams —
save,findAll,delete,watch,watchAll, batch operations, soft deletes. - Sync engine — Persistent operation queue, push/pull orchestration, connectivity awareness, exponential backoff.
- 6 conflict strategies — Last-write-wins, server-wins, client-wins, field-level merge, three-way merge, manual.
- Hybrid Logical Clock — Causal ordering that works even when device clocks disagree.
- Pluggable backends — REST, Firebase, Supabase out of the box. Implement
BackendAdapterfor anything else. - SQLCipher encryption — AES-256 at rest with key rotation.
- Auto schema migration — Column adds, type changes, index changes, full table rebuilds.
- Pure Dart — No Flutter dependency. Works in CLI, backend, and Flutter apps.
| Package | Description | pub.dev |
|---|---|---|
dart_data |
Core framework — storage, repository, sync, conflict resolution, encryption, migration | |
dart_data_generator |
Code generation for @SyncModel annotations via build_runner |
|
dart_data_rest |
REST backend adapter | |
dart_data_firebase |
Firebase Firestore backend adapter | |
dart_data_supabase |
Supabase backend adapter |
See the dart_data package README for full documentation, API reference, and examples.
dependencies:
dart_data: ^0.1.0
dev_dependencies:
dart_data_generator: ^0.1.0
build_runner: ^2.4.0dart_data (core)
├── Storage Engine ......... SQLite with auto-schema, metadata tracking
├── Repository ............. Type-safe CRUD, queries, reactive streams, batch ops
├── Sync Engine ............ Push/pull orchestration, operation queue, connectivity
├── Conflict Resolution .... 6 strategies, Hybrid Logical Clock ordering
├── Migration Engine ....... Auto-diff, custom steps, table rebuild
└── Encryption ............. SQLCipher AES-256, key rotation
dart_data_generator (codegen)
└── @SyncModel → ModelSchema, toJson/fromJson, typed repositories
dart_data_rest ─┐
dart_data_firebase ├── Backend adapters (implement BackendAdapter)
dart_data_supabase ─┘
Contributions are welcome! Please file issues and pull requests on GitHub.
See CONTRIBUTING.md for guidelines.
BSD 3-Clause. See LICENSE.