datastore
Use when persisting key-value preferences or small typed settings on Android or KMP with Jetpack DataStore — Preferences vs Typed (Proto/JSON) vs Room selection, the IOException and corruption-recovery error traps, serializers with corruption handlers, and the KMP factory with per-platform file paths. Triggers on DataStore, Preferences, PreferenceDataStoreFactory, DataStoreFactory, preferencesDataStore, Serializer, SharedPreferences-to-DataStore migration, or persistent settings work.
How do I install this agent skill?
npx skills add https://github.com/rcosteira79/android-skills --skill datastoreIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill provides technical guidance and code examples for implementing Jetpack DataStore in Android and Kotlin Multiplatform (KMP) projects. No security issues or malicious patterns were detected.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
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.
val settings: Flow<UserSettings> = dataStore.data
.catch { e -> if (e is IOException) emit(emptyPreferences()) else throw e }
.map { p -> UserSettings(p[Keys.DARK_MODE] ?: false, p[Keys.LOCALE] ?: "en") }
Typed-DataStore corruption recovery triggers on CorruptionException, NOT IOException. The serializer's readFrom must wrap parse failures in CorruptionException, and the store needs a ReplaceFileCorruptionHandler — without it, one corrupt file makes every read fail permanently.
object AppSettingsSerializer : Serializer<AppSettings> {
override val defaultValue = AppSettings()
override suspend fun readFrom(input: InputStream): AppSettings =
try { Json.decodeFromString(input.readBytes().decodeToString()) }
catch (e: SerializationException) { throw CorruptionException("Cannot read AppSettings", e) }
override suspend fun writeTo(t: AppSettings, output: OutputStream) =
output.write(Json.encodeToString(t).encodeToByteArray())
}
val store = DataStoreFactory.create(
serializer = AppSettingsSerializer,
corruptionHandler = ReplaceFileCorruptionHandler { AppSettings() },
produceFile = { File(context.filesDir, "app_settings.json") },
)
KMP factory — per-platform path (not the temp dir)
// commonMain
fun createPreferencesDataStore(producePath: () -> String): DataStore<Preferences> =
PreferenceDataStoreFactory.createWithPath(produceFile = { producePath().toPath() })
// android: context.filesDir.resolve(PREFS_FILE).absolutePath
// ios: NSDocumentDirectory via NSFileManager
// jvm: File(System.getProperty("user.home"), ".myapp") — NOT java.io.tmpdir (the OS may wipe it on reboot)
(In a composable, never runBlocking on DataStore — it parks the main thread on disk I/O, risking an ANR, and re-runs every recomposition. Expose a StateFlow and collect with collectAsStateWithLifecycle.)
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/rcosteira79/android-skills/datastore">View datastore on skillZs</a>