datastore
Jetpack DataStore for Android and KMP
Reactive coroutine-based key-value / typed storage; the same androidx.datastore:datastore-preferences-core runs on Android, iOS, and JVM — only the file-path producer is platform-specific. (Web support is 1.3.0-alpha only, and it's sessionStorage/OPFS-backed there, not file-path-based.) This reference covers the storage-choice call plus the two error/path traps, not the basics of Preferences keys, edit { }, or Serializer<T>. Adapted from Meet-Miyani/compose-skill; MIT. Related: android-skills:android-data-layer, android-skills:kmp-boundaries, android-skills:kotlin-flows.
Preferences vs Typed vs Room
| Need | Storage |
|---|---|
| Key-value flags (theme, locale, onboarding done) | Preferences DataStore |
| One typed object, many related fields, schema evolution | Typed DataStore + Serializer<T> |
Relational data, indexes, WHERE / JOIN, >100 entries, paging |
Room |
| Payloads above ~50KB per write | Room / filesystem — DataStore rewrites the whole file on every edit |
Rule of thumb: if a WHERE clause would be useful, use Room.
The two traps
.catch must match IOException specifically — never a broad catch. A bare catch { emit(emptyPreferences()) } swallows CancellationException (breaking structured concurrency) and hides serializer/corruption errors behind a silent empty state.