Offline-first is a promise: the app works in a tunnel exactly like it works on Wi-Fi. Drift (SQLite for Flutter) makes that promise keepable because the database is reactive: widgets rebuild when the query result changes, no manual cache invalidation.
Migrations are the whole game
Version every schema change and write the migration before the feature. Drift generates the step helpers, but you still need a test that opens a v1 database, migrates it, and asserts the data survived.
- Keep DAOs thin: one method per query the UI actually needs.
- Watch queries with .watch() for reactive lists; use .get() for one-shot reads.
- Test the data layer with an in-memory database: no widget harness required.
- Seed demo data behind a flag so reviewers see a full store on first launch.
If your app needs a backend to demo, you do not have an offline-first app. You have a loading spinner.