PT
Mobile

Minhas Listas

Offline-first shopping list built with Flutter + Drift: no account, no cloud, and all data on the device.

Period2026
RoleSolo project
Minhas Listas screen, shopping list app with items grouped by category

Context

It started as an exercise in local-first architecture: a shopping list app that worked without an account or a server. It became a single, multiplatform product (Android, iOS, Web and desktop) with product documentation, a design system, tests and CI. The app is complete but has not been published to any store yet.

The challenge

Keep the same data model and experience across four platforms, with the local database as the single source of truth — including migrations, faithful backups, automatic categorization without an external service and privacy by default. In the browser, that means running SQLite through WASM and persisting without a backend.

Role and responsibilities

  • Offline-first architecture with Drift/SQLite as the source of truth; writes always local and UUIDs generated on the client
  • Domain model with fractional quantities, a closed unit enum, categories and custom ordering
  • Layered local categorization (name memory → static dictionary → 'others'), with no network calls
  • Text import with a deterministic parser and editable preview; voice input through the system recognizer
  • Purchase history with a snapshot per trip, spending statistics and price comparison by store
  • The same database on Android, iOS, desktop and Web (WASM with OPFS/IndexedDB), plus JSON backup and restore

Stack and architecture

Flutter 3.44 + Dart 3.12 in the app; Drift 2.34 over SQLite for local storage (WASM in the browser); Material 3; speech_to_text, share_plus and qr_flutter for voice and sharing; GitHub Actions for CI.

FlutterDartDrift + SQLiteMaterial 3GitHub Actions

Highlights

  • Radical privacy: no account, analytics or ads, and no network calls — data never leaves the device
  • One data model running on mobile, desktop and browser, with the same Drift stack and persistence fallback
  • Categorization and import handled locally, without AI or an external service
  • Treated as a product: design system, onboarding tour, 48dp targets, AA contrast and normative documentation

Takeaways

Local-first simplifies infrastructure — there is no backend to operate — but moves the complexity into migrations, backups and recovery UX. I learned that privacy by default is an architecture decision, not a settings screen.