A fully-functional Todo application demonstrating the power of SyncVault for offline-first data synchronization.
| Feature | Description |
|---|---|
| 🔄 Automatic Queueing | Requests made while offline are automatically queued |
| ☁️ Auto-Sync | Queued requests sync automatically when connectivity returns |
| 🎯 Idempotency Keys | Prevents duplicate operations during retries |
| 📊 Status Stream | Real-time sync status updates for UI feedback |
| ⚡ Optimistic UI | Immediate UI updates with pending sync indicators |
| 🔢 Pending Count | Track how many requests are waiting to sync |
- Flutter SDK (3.10+)
- A device or emulator
cd example
flutter pub get
flutter runThe app features a beautiful dark theme with:
- Header — App title with animated sync button
- Status Bar — Online/offline indicator + pending count badge
- Input Field — Add new todos
- Todo List — Swipe-to-delete with completion toggle
| Indicator | Meaning |
|---|---|
| 🟢 Green dot | Device is online |
| 🟡 Amber dot | Device is offline |
| ☁️ Cloud icon on todo | Item pending sync |
| ⏳ "X pending" badge | Number of queued requests |
| ✓ "Synced" badge | All requests synchronized |
| Color | Status |
|---|---|
| 🟢 Green | SyncStatus.synced — All caught up |
| 🟣 Purple | SyncStatus.syncing — Currently processing queue |
| 🟡 Amber | SyncStatus.pending — Items waiting to sync |
| 🔴 Red | SyncStatus.error — Sync error occurred |
example/
├── lib/
│ ├── main.dart # Main app with SyncVault integration
│ ├── todo_model.dart # Todo data model
│ └── sqflite_example.dart # Alternative: SQLite storage example
└── pubspec.yaml
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final dir = await getApplicationDocumentsDirectory();
await SyncVault.init(
config: SyncVaultConfig(
baseUrl: 'https://jsonplaceholder.typicode.com',
storagePath: dir.path,
maxRetries: 3,
),
);
runApp(const SyncVaultExampleApp());
}// POST — Create todo
final response = await SyncVault.instance.post(
'/todos',
data: todo.toJson(),
idempotencyKey: 'create_todo_${todo.id}',
);
// Track the action ID for event listening
if (response.actionId != null) {
_todoToActionId[todo.id] = response.actionId!;
}
if (response.isQueued) {
// Show offline indicator
} else if (response.isSent) {
// Update UI with success
}// Wrap your screen with SyncVaultListener
SyncVaultListener(
onSuccess: (event) {
// Called when any action completes successfully
_markTodoSynced(event.id);
showSnackBar('Synced!');
},
onDeadLetter: (event) {
// Called when an action permanently fails
showSnackBar('Failed: ${event.error}');
},
child: YourScreen(),
)// Automatically rebuilds when sync status changes
SyncStatusBuilder(
builder: (context, status) {
return Icon(
status == SyncStatus.syncing ? Icons.sync : Icons.cloud_done,
color: _getSyncColor(status),
);
},
)// Show sync progress for a specific action
SyncEventBuilder(
actionId: actionId,
builder: (context, lastEvent) {
if (lastEvent?.status == SyncEventStatus.started) {
return CircularProgressIndicator();
}
return Icon(Icons.cloud_upload);
},
)final pendingCount = await SyncVault.instance.pendingCount;final syncedCount = await SyncVault.instance.processQueue();- Open the app
- Add a few todos
- Enable Airplane Mode in the emulator
- Add more todos — notice the "pending" badge
- Disable Airplane Mode
- Watch the automatic sync happen!
- Turn off WiFi and mobile data
- Use the app normally
- Re-enable connectivity
- Observe auto-sync
See sqflite_example.dart for using SQLite instead of Hive:
final sqliteAdapter = SqfliteStorageAdapter();
await SyncVault.init(
config: SyncVaultConfig(
baseUrl: 'https://api.example.com',
storage: sqliteAdapter,
),
);- Color Palette: Indigo/Purple gradients with emerald/amber accents
- Typography: SF Pro Display (system font)
- Theme: Material 3 Dark
- Animations: Pulse effect on sync button, smooth transitions
This example uses JSONPlaceholder as a demo API:
POST /todos— Create todoPATCH /todos/:id— Update todoDELETE /todos/:id— Delete todo
Note: JSONPlaceholder is a fake API that returns success responses but doesn't persist data. Perfect for demonstrating SyncVault's behavior!
- SyncVault Package — Main package documentation
- SyncVault on pub.dev — Package page
Built with 💜 to demonstrate offline-first architecture in Flutter.