Flutter for POS systems: offline-first done right
POS apps do not run in perfect conditions. The internet drops, power cycles, and the branch still must sell. This note captures the pattern we use on TtaKkaa Cashier to keep operations smooth regardless of connectivity.T…

POS apps do not run in perfect conditions. The internet drops, power cycles, and the branch still must sell. This note captures the pattern we use on TtaKkaa Cashier to keep operations smooth regardless of connectivity.
Three principles
- Local source of truth: SQLite is authoritative; the network is just a sync.
- Events-first: every sale/refund/discount is logged as an event, not a row mutation.
- Sync is never in the user path: background queue — we do not block receipts on network.
Stack
- Drift (SQLite) for local persistence.
- Riverpod for state management.
- WorkManager for smart sync the moment network returns.
- Laravel 11 on the far side, consuming event batches.
Conflict resolution
We use a minimal CRDT for stock line-items: additions / deductions are associative, so even multi-branch offline operations merge cleanly.
Common challenges
- Thermal printer: ESC/POS over Bluetooth works even offline.
- Barcode scanner: listen directly to USB-HID events.
- Product updates: applied on reconnect with resolvers so pending tickets are not broken.
Takeaway
A POS app is not "an online mobile app" — it is a tiny distributed system inside one branch. Plan for that and your system will stay up in the worst cases.


