Flutter Supabase Offline First: The Sync Architecture That Actually Works
Make your Flutter + Supabase app work fully offline: the offline-first architecture (local-first database, outbox pattern, idempotency keys, watermark sync, conflict resolution), local database options (Drift, Isar, Brick, PowerSync), and a hands-on Brick + Supabase walkthrough.
TL;DR: Supabase has no built-in offline mode, so your Flutter app needs its own sync layer. The proven architecture: treat a local database (Drift, Isar, or Brick) as the single source of truth, queue every user change in an outbox table with an idempotency key , and let a background sync worker push changes up and pull changes down with watermark sync . Resolve edit conflicts with last-write-wins (enough for 95% of apps). This guide walks through the full architecture plus a hands-on Brick + Supabase implementation. What you'll learn What "offline-first" really means (it's messier than "no internet") The three ways offline apps corrupt data — and how to prevent each one The offline-first architecture: local-first database + background sync engine The outbox pattern, idempotency keys, and watermark sync, with Dart code How to resolve conflicts when two devices edit the same row When to trigger syncs (and why naive retries can take down your backend) Drift vs Isar vs Brick vs PowerSync: which local layer to pick Hands-on: building an offline-capable notes app with Brick + Supabase What most tutorials skip: RLS vs offline writes, testing, token expiry, and buy-vs-build Your app will go offline. Plan for it. Picture your user on a train between two stations. No signal. They create an order, edit a document, send a message. Ninety seconds later the train surfaces, and your app either syncs everything perfectly — or it just corrupted their data. Here's the uncomfortable truth most tutorials skip: offline is not a binary switch. It's a spectrum of mess. A flaky café network that drops halfway through a request. A user walking into a parking garage. Your app getting killed in the background mid-upload. A phone connected to Wi-Fi that has no actual internet…