// Writing
Notes from the journey
Thoughts on building calm, private software as a team of one.
RSS feed
Android App Links in 2026: why your https:// links still open in the browser
Digital Asset Links verification, the assetlinks.json gotchas, and the adb commands that tell you why Android won't hand a link to your app.
Room TypeConverters in 2026: storing enums, dates, and lists without corrupting your schema
A practical guide to Room TypeConverters on Android — enums, Instant/LocalDate, and lists — plus the mistakes that turn a converter into a silent data-corruption bug.
R8 and ProGuard for Kotlin, Room, and Compose: the crash that only happens in release
Why a Room + Compose Android app can work perfectly in debug and crash in production, and the specific R8/ProGuard keep rules that catch it before a user does.
The Android In-App Review API: asking for a rating without being annoying
A practical guide to Google's In-App Review API — how it actually works, where to trigger it, and why the usual 'rate us' popup is quietly hurting your Play Store rating.
Android app shortcuts and Quick Settings Tiles: logging water without opening the app
A practical guide to Android's dynamic ShortcutManager API and TileService — how to let a one-tap action skip the app entirely, with the pitfalls that trip most implementations.
Foreground service types on Android in 2026: picking the one your feature actually qualifies for
A practical guide to Android's foreground service type restrictions — dataSync, mediaPlayback, specialUse, shortService — and how to pick the right one without getting killed or rejected.
One App, One Job: Why I Don't Build a Super-App
Every growing app feels pressure to add features and merge into one big platform. Here's why MFKAPPS stays a set of small, single-purpose apps instead.
StateFlow vs SharedFlow in Jetpack Compose: modeling UI state without the replay bug
When to use StateFlow and when to use SharedFlow in a Compose ViewModel — and the one-time-event bug that shows up when you mix them up.
Room database indices in 2026: finding the query that's actually slow and fixing it
A practical guide to indexing a Room/SQLite database on Android — reading EXPLAIN QUERY PLAN, adding @Index without guessing, and the mistakes that silently defeat one.
Room's @Relation: querying one-to-many data on Android without N+1 queries
A practical guide to Room's @Relation annotation — modeling one-to-many data like categories and entries without N+1 queries or manual joins.
Type-Safe Navigation in Jetpack Compose: Routes as Data, Not Strings
How to replace string-based Compose Navigation routes with serializable Kotlin objects — type-safe arguments, nested graphs, and deep links that survive a refactor.
Budgeting with irregular income: a system that doesn't assume a steady paycheck
Most budgeting advice assumes the same amount lands every month. Here's a system built for freelance, commission, or seasonal income that actually holds up.
Android 16 Live Updates: putting Mintly's focus timer on the lock screen
A practical guide to Android 16's progress-centric notifications — ProgressStyle segments, promoted ongoing notifications, and what they add to a running Pomodoro timer.
Setting Up Medication Reminders for a Family Member: A Caregiver's Guide
A practical guide to helping a parent or partner stay on top of their medications — what to set up, what to avoid, and how to check in without hovering.
Android notification channels in 2026: designing importance levels users won't mute
A practical guide to Android notification channels — importance levels, channel groups, why settings freeze after creation, and how to migrate them without losing user trust.
How Long Should a Focus Session Be? A Framework Beyond the 25-Minute Default
The 25-minute Pomodoro is a starting point, not a rule. A practical framework for finding your real focus session length, by task type and energy.
Paging 3 with Room: keeping a growing transaction list smooth on Android in 2026
How to page a Room-backed transaction list with Jetpack Paging 3 so years of data stay smooth in Compose — no RemoteMediator, no network, just a local database done right.
The Android 16 KB page size migration: what actually breaks and how to check your APK
Google now requires Android apps to support 16 KB memory pages. Here's what that means in practice, why native libraries are the ones that break, and how to verify yours are safe.
Structured concurrency on Android in 2026: scopes, cancellation, and the leaks they prevent
A practical guide to Kotlin structured concurrency on Android — viewModelScope vs lifecycleScope, why cancellation propagates, and the coroutine leaks it quietly rules out.
Recomposition in Jetpack Compose: what actually triggers it and how I stopped guessing
A practical guide to Jetpack Compose recomposition in 2026 — type stability, unstable lambdas, LazyColumn keys, and reading the compiler's own metrics report.
Full-text search in Room: adding instant search to a local-first Android app in 2026
A practical guide to Room's FTS4 support on Android — building a virtual search table, keeping it in sync with triggers, and why FTS5 needs a manual migration.
No Accounts, No Passwords: Why My Apps Don't Have a Login Screen
Six apps, zero sign-up forms. Here's the actual reasoning behind skipping accounts entirely — what it costs, what it removes, and where the line is.
Encrypting a Room database in 2026: SQLCipher, the Keystore, and migrating without losing data
A practical guide to encrypting a Room/SQLite database at rest on Android with SQLCipher — key management via the Keystore, the one-time migration, and the real performance cost.
Backing up local-first data on Android in 2026: SAF export, Auto Backup, and a restore flow you can trust
How local-first Android apps back up user data without a server: SAF export/import, Auto Backup for App Data, and a restore that verifies before overwriting.
Testing a local-first Android app in 2026: Room, Flow, and Compose UI tests that catch real bugs
A practical testing strategy for local-first Android apps in 2026 — in-memory Room DAO tests, Turbine for Flow, and the few Compose UI tests actually worth writing.
Biometric authentication on Android in 2026: BiometricPrompt, the Keystore, and locking a local-first app
A practical guide to androidx.biometric on Android — BiometricPrompt, CryptoObject-backed keys, device credential fallback, and the mistakes that let a fingerprint check protect nothing.
Accessibility on Android in 2026: a TalkBack and Compose semantics checklist that ships
A practical Android accessibility checklist for 2026 — TalkBack, Compose semantics, touch targets, and the testing pass I run on every screen before release.
Health Connect on Android in 2026: reading and writing data without giving up local-first
A practical guide to Android's Health Connect API in 2026 — permissions, background reads, and why local-first apps should treat it as optional, not truth.
Edge-to-edge and predictive back on Android in 2026: what's mandatory now, and how not to break your UI
Edge-to-edge is now enforced on API 35+ and predictive back is the default gesture. A practical guide to Compose insets, WindowInsets, and PredictiveBackHandler.
How much water should you actually drink? A formula that beats '8 glasses a day'
The 8-glasses rule ignores your body weight, activity, and climate. Here's the body-weight formula clinicians actually use, with a worked example.
A calm phone setup: a beginner's roadmap
A practical, step-by-step roadmap to a calmer phone — notification triage, a smaller home screen, and batched check-ins that actually stick long-term.
Jetpack DataStore in 2026: migrating off SharedPreferences without losing a setting
A practical guide to moving from SharedPreferences to Jetpack DataStore on Android — the async pitfalls, the migration path that preserves existing values, and how to test it.
How to audit your subscriptions in 20 minutes (and actually cancel the ones you don't use)
A step-by-step subscription audit you can finish in one sitting — find every recurring charge, decide keep-or-cancel with one rule, and set a habit that keeps the list honest.
ML Kit barcode scanning on Android in 2026: how Stocky adds a pantry item in under a second
A practical 2026 guide to on-device barcode scanning with ML Kit and CameraX: format tuning, offline product lookup, and the partial-use math behind a pantry app.
Room database migrations in 2026: shipping schema changes without losing a row
A practical guide to Room database migrations on Android — AutoMigration, hand-written Migration objects, and how to test a migration before your users find the bug.
Baseline Profiles on Android: what actually moves your cold-start time in 2026
A practical guide to Android Baseline Profiles — generating one with Macrobenchmark, wiring it into Gradle, measuring the real gain, and the three other things that move cold start more.
Jetpack Glance in 2026: building a home-screen widget that never lies about your data
A practical guide to Jetpack Glance widgets on Android — state, click actions, and the update-quota trap that makes home-screen widgets show stale data.
A pantry inventory system that actually stops food from going to waste
Most food waste isn't bad planning — it's forgetting what's already there. A simple inventory and expiration-triage system that catches it before the bin does.
Building OldSchool's adherence calendar: turning dose taps into a day you can trust
A monthly adherence calendar looks like a single colored dot per day. Here's the event model, the day-status rules, and the on-time math behind it, on-device.
Building Subly: the calendar math behind subscription renewal dates
Predicting a subscription's next charge date sounds trivial until you hit month-end billing, leap years, and trial conversions. Here's how Subly gets it right, on-device.
Building Mintly: keeping a focus timer accurate when Android kills the process
A running Pomodoro timer has a harder reliability problem than a one-shot reminder. Here's how Mintly survives Doze, process death, and screen-off drift with a foreground service and a wall-clock end time.
A hydration routine that doesn't rely on willpower
Most hydration advice boils down to 'drink more water' and hopes willpower fills the gap. Here's a routine built around cues and gentle nudges instead.
Building Granyn: a budget tracker with no bank login, in three tables
How Granyn tracks spending across currencies and catches recurring bills without linking a single bank account — the Room schema and the trade-offs behind it.
Android notification actions done right: marking a dose taken without opening the app
A practical guide to Android notification action buttons — PendingIntents, the trampoline restriction, goAsync(), and updating Room state safely.
The Pomodoro Technique that survives a bad day
The 25/5 timer is easy to start and easy to abandon. Here's a version of the Pomodoro Technique built around rituals, not streaks, so a rough day doesn't end the habit.
A budgeting system for people who've never stuck with one
Most budgets die in the first two weeks. A three-category system and a five-minute weekly check-in that survives a messy month, not just a perfect one.
Building Stocky: predicting what your kitchen runs out of — on the device
How Stocky turns a barcode scan and a bit of usage history into a shopping list that shows up before you run out — with all the math, and all the data, staying on your phone.
Building a medication routine you'll actually stick to
A practical guide to medication adherence — why people miss doses, how reminder timing actually works, and how to build a routine that survives a bad week.
The site now speaks seven languages
MFKAPPS is now available in English, Turkish, French, Spanish, Japanese, Hindi, and Russian. A short note on why a one-person studio bothered, and how it stays fast.
Privacy-first OCR on Android: how Subly reads bills without the cloud
A practical 2026 guide to on-device OCR on Android with ML Kit Text Recognition — the setup, the code, and the field extraction tricks that keep user data off your servers.
Building Hydrame: smart reminders without the nag
A reminder app lives or dies by its notifications. Here's how I designed Hydrame's to nudge you gently — and adapt to your day instead of fighting it.
Subscription overload: why I'm done linking my bank to apps
Subscription-tracker apps usually solve the problem by asking for your bank login. In 2026 there's a calmer way — on-device bill scanning, no Plaid, no aggregator.
Reliable Android reminders in 2026: WorkManager, exact alarms, and the new battery rules
How to ship reminders on Android in 2026 that actually fire — WorkManager vs AlarmManager, SCHEDULE_EXACT_ALARM, POST_NOTIFICATIONS, and the OEM quirks that still bite.
Local-first Android in 2026: SQLite, Room, and keeping user data on the device
A 2026 guide to building local-first Android apps with Room and SQLite — schema design, migrations, WAL, exports, and when (and when not) to add sync.
How I ship Android apps as a solo developer in 2026
An actual end-to-end launch playbook for shipping a Kotlin + Compose Android app alone in 2026 — scope, build, Play Store listing, and the boring bits that decide whether you ever launch.
The privacy advantage of local-first apps
The most private data is the data you never collect. Local-first isn't just an architecture choice — it's the simplest privacy policy there is.
Why I left to build calm tools
Most apps are designed to keep you hooked. I wanted to build the opposite — software that does its job and then gets out of your way.