All Projects

Pocketly — Expense Tracker

Platforms:
androidios
Stack:
FlutterDartRiverpodHivefl_chart
Pocketly app screenshot showing expense dashboard

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_chart animation conflicts with hero transitions; disabling chart animations on route entry solves the jank
  • Riverpod's keepAlive is critical for expensive providers that parse large Hive boxes

Screenshots

Home screen with monthly summary
Monthly overview with category donut chart
Add expense bottom sheet
Quick-add with smart category suggestions