Pocketly — Expense Tracker
Personal finance tracking with offline-first sync
A Flutter app for tracking daily expenses with category breakdowns, recurring entries, CSV export, and a Riverpod + Hive offline-first architecture.
Overview
Pocketly started as a personal project after struggling to find an expense tracker that worked well offline. Most cloud-synced apps feel sluggish — every interaction waits on a network round-trip.
This app uses Hive as the local database with a sync queue that pushes to Firestore when the device comes online, giving every interaction immediate UI feedback.
Architecture
- State management: Riverpod 2 (providers + notifiers)
- Local persistence: Hive (typed boxes, no code-gen overhead)
- Charts: fl_chart with custom Flutter painters for the budget progress bars
- Sync: Background isolate polling with connectivity_plus

Key Technical Decisions
Offline-First Sync Queue
class SyncQueue {
final Box<SyncOperation> _box;
Future<void> enqueue(SyncOperation op) async {
await _box.add(op);
_tryFlush();
}
Future<void> _tryFlush() async {
if (!await _connectivity.isOnline) return;
for (final op in _box.values) {
await _remote.apply(op);
await op.delete();
}
}
}The queue survives app restarts and processes in FIFO order, preventing double-entries.
What I Learned
- Hive adapters need manual type registration — easy to miss in tests if you bootstrap lazily
fl_chartanimation conflicts withherotransitions; disabling chart animations on route entry solves the jank- Riverpod's
keepAliveis critical for expensive providers that parse large Hive boxes
Screenshots