Skip to content

2. use drift (SQLite) for the local database

status

accepted

context

the app needs to store relational data (meditations, timer segments, bells, tags, prompt lists, session history, notification profiles) with queries like "sessions per week per tag" and "streaks" that are much more natural in sql than in a nosql/key-value store. it also needs a mature migration story since the schema will grow across many phases.

superseded terminology: "timer segments" are now segments, "prompt lists" are now lists, and "notification profiles" are now reminders (the SQL table names are unchanged) — see docs/dev-guide/terminology.md.

decision

use drift on top of package:sqlite3 (via drift/native.dart, no sqlite3_flutter_libs needed - see the "Implementation log" appendix in docs/dev-guide/PROJECT_PLAN.md) as the local database for all native platforms (Android, iOS, Linux, Windows, macOS, and Wear OS).

alternatives considered

  • isar: fast, Dart-native, but a smaller ecosystem and weaker migration tooling than drift's.
  • hive: simplest option, but a key-value store is a poor fit for the relational queries history/graphs and tag filtering need.

consequences

  • schema changes go through drift's migration system (AppDatabase.schemaVersion + MigrationStrategy); every phase that adds tables must bump the schema version and write a migration.
  • the backup/sync bundle format (phase 8) serializes drift rows to JSON rather than shipping the raw sqlite file, keeping the bundle human-inspectable and diffable (useful for the git sync backend).