KSafe — Universal Key/Value Persistence for Kotlin Multiplatform and Android
- Encrypted by default. Plain (unencrypted) when needed.
- Persist variables, Compose State, StateFlow, and serializable objects across Android, iOS, macOS, Desktop, and Web
- Easy to use by design


🤖 KSafe Skill for AI agents
KSafe ships an agentskills.io-compatible skill — skills/ksafe/SKILL.md — that teaches any AI agent (Claude Code, Codex, Gemini CLI, Copilot CLI, Junie) KSafe's patterns, anti-patterns, and gotchas. Restart your agent session after installing — skills load at session start.
Claude Code (recommended)
installs once, updates itself
Run both commands, in this order, inside any Claude Code session. It's a one-time setup:
/plugin marketplace add ioannisa/KSafe # 1. register this repo as a plugin source
/plugin install ksafe@ksafe # 2. install the ksafe skill from it
The first command only tells Claude Code where the plugin lives — it installs nothing by
itself. The second does the actual install (the format is <plugin>@<marketplace>; both
happen to be named ksafe here). Restart the session and the skill is active.
From then on you're done: Claude Code checks this repo for updates at the start of every
session, so skill improvements arrive on their own. /plugin update fetches the latest
immediately if you don't want to wait.
Other agents
(Codex, Gemini CLI, Copilot, Cursor, Junie, …)
pick ONE of the two options below
Option A — the skills.sh CLI (recommended): one command installs the
skill into whichever of your agents you select in its prompt (30+ supported):
npx skills add ioannisa/KSafe
There is no auto-update for these agents — re-run the same command whenever you want the
latest skill (e.g. after a KSafe release).
Option B — plain copy, no tooling: fetch the file straight into each agent's skills
directory. Edit the agent list to match what you actually use:
for agent in codex gemini copilot junie; do
mkdir -p "$HOME/.$agent/skills/ksafe" && \
curl -fsSL https://raw.githubusercontent.com/ioannisa/KSafe/main/skills/ksafe/SKILL.md \
> "$HOME/.$agent/skills/ksafe/SKILL.md"
done
Re-run it to refresh (again: no auto-update). If you've already cloned this repo,
cp -r skills/ksafe "$HOME/.<agent>/skills/" does the same thing offline. Add claude to
the list only if you prefer a plain skill over the plugin from the section above — don't
do both.
What is KSafe?
KSafe is a secure-by-default Kotlin Multiplatform key/value persistence library. Persist ordinary Kotlin variables, Compose MutableState, MutableStateFlow, and @Serializable objects across app restarts with one API on Android, iOS, macOS, JVM/Desktop, WASM, and Kotlin/JS. Encrypted (AES-256-GCM) by default; plain per-entry with mode = KSafeWriteMode.Plain.
var counter by ksafe(0)
counter++ // auto-encrypted (AES-256-GCM), auto-persisted, survives process death
Read and write it like any normal Kotlin variable — no suspend, no runBlocking, no DataStore boilerplate, no explicit encrypt/decrypt. Reads hit a hot in-memory cache (~0.002 ms); writes encrypt and flush in the background — synchronous, but never blocking. Reach for the suspend API (get / put) only when you want to await the disk flush.
- Easy? ✔ one-line setup, property-delegate API
- Encrypted by default? ✔ AES-256-GCM, hardware-backed where available
- Plain storage? ✔ opt out with one parameter
- Synchronous? ✔ non-blocking hot-cache reads
- Asynchronous? ✔ full suspend API for guaranteed disk flushes
Extras when you encrypt: biometrics (Face ID / Touch ID / Fingerprint — optional standalone ksafe-biometrics module) · root/jailbreak detection (WARN/BLOCK + analytics callback) · memory policy (RAM-exposure modes) · a one-line hardware-isolated DB passphrase for SQLCipher / SQLDelight / Room.
Demo & Videos
KSafe in action across many scenarios: KSafeDemo — Compose Multiplatform app.