MJ Stories
Mobile craftsmanship stories
Offline-First KMP · Part 11
Witness, Not Judge
Your offline-first app is not a sync queue. The client witnesses; it never judges: it records what happened as immutable events, and one shared Kotlin engine, the same one the phone runs, derives state and rules on conflicts on a Node.js server. The whole architecture in one read, with the Droidcon Berlin talk and slides.

Series · 11 parts
Offline-First KMP
When your mobile app must work without internet as a standard, not an edge case, the sync layer is just the first decision. What comes after — preserving user intent offline, trusting a "success" your server never actually confirmed, resolving conflicts as a human decision — is where offline-first actually gets hard. Field notes from a production KMP winery app.
- 1Choosing an offline-first sync layer for KMP
- 2Two writes for every tap
- 3Minting IDs Before the Server
- 4The Write You Never Clean Up
- 5HTTP 200 Is Not Success
- 6Your Schema Is Not Your Payload
- 7You Cannot Fix a Generated File
- 8Every Synced Row Needs an ID
- 9Your Sync Stack Fits in Three Containers
- 10HTTP 500 Is Not a Retry
- 11Witness, Not Judge
More Stories
Your API key is not a secret
We have been hiding API keys in Android apps for a decade — with BuildConfig tricks, NDK, obfuscation libraries. None of it works. The fix is not better hiding; it is treating the key as a public identifier and proving the app is genuine instead.

Share iOs string resources with Android
There might be a requirement for mobile string resources to be defined or adjusted by management or copywriters. There also might be a requirement to add localization later by those roles. And on top of that strings should be synced across platforms.










