Kotlin Multiplatform Newsletter #30
We debate using native SwiftUI over Compose UI on iOS to shrink app binary sizes from ~100 MB down to 8 MB, evaluate why choosing KMP over React Native is an architecture bet rather than a framework preference, and track down a memory leak in JetBrains Jewel’s LazyTree. We also look at pairing Gemini Nano with Apple Intelligence in Compose, OCR scanning using ML Kit and Vision, parameter instability pitfalls under Strong Skipping Mode, and cross-platform home screen widgets using WARP. Plus, a foundational Senior KMP role at Yonder Media Mobile.
The Main Thread
Community's most insightful threads, curated from social media platforms and websites.
I'm still using Kotlin Multiplatform for business logic, networking, database, etc., but I no longer share the UI. Android uses Compose. iOS is built entirely in SwiftUI while calling shared Kotlin through a shared module. The difference has been huge. The new iOS app is around 8–10 MB instead of ~100 MB, and the experience finally feels like a proper iOS app.
Expect Actual
Technical deep dives, or solving the "how-the-hell-do-I-test-this" problems.
Stop treating Kotlin like a black box! 🧠
To build truly performant multiplatform apps, writing code that just "works" isn't enough. We need to understand what the compiler is actually doing under the hood.
That’s why I highly recommend Practical Kotlin Deep Dive by skydoves. This isn't a basic syntax guide, it breaks down Kotlin internals, bytecode, and coroutines. It’s been a total game-changer for me when writing and optimizing shared code.
If you want to level up your Kotlin and KMP skills to a senior standard, you need this on your desk.
The last article ended on a claim: isolate the platform API behind a small interface in
commonMain, and everything above it can be written once. That result came from porting a 2012 Objective-C iOS app into shared Kotlin and standing up Android alongside it. Good outcome — but a single data point, and one where I controlled the scope. So I did it again, deliberately choosing a project that would stress the parts the first one didn’t.For a long time, React Native was the go-to answer. On paper, it sounds great: write JavaScript once, leverage a huge web ecosystem, and ship features fast. But once your app grows, the reality hits. React Native forces you to wrap your entire mobile application inside a JavaScript runtime engine. When we re-evaluated our long-term mobile strategy, we realized we didn’t want a framework that forces us to compromise on native quality just to save time. We wanted an architecture that actually scales.
The JetBrains Jewel project recently got a report of a supposed memory leak in the
LazyTree Composable. Thankfully, the issue had a minimal reproducer that we could use to investigate this weird behavior. But the reproducer by itself is not enough, to effectively check if there are any memory leaks going on, we need specific tooling.Jibify’s rule has always been the same: AI runs on the phone by default, and the cloud is only a fallback. That rule didn’t change when I moved to Compose Multiplatform. What changed is that “the phone” now means two very different phones.
In this article we’ll look at how that’s put together: the
expect/actual camera scanner, the per-platform OCR implementations, and how we match the recognised text to a stop.A Compose Multiplatform app can share 93% of its code and still meet the platform in two places nothing abstracts away — native vendor SDKs, and the physical device. The finale is about engineering that edge so it fails loudly instead of rotting in silence.
It took a while for all the dependencies to be in place, but once support was available (especially SQLDelight support) we were finally able to add support for browsers. In this post we wanted to go over the difficulties and intricacies of adding web support to our project.
Feature modules are a spec series. I want every one of mine built to the same jig, so that when a module behaves oddly I know it’s the code I wrote and not the scaffold it arrived in. It took me a while, and one AI-generated codebase, to work out that I’d been running Formula 1.
LazyColumn
Compose Multiplatform tips, tricks, and code snippets.
In this post, we’ll look at how Strong Skipping Mode actually compares parameters under the hood 🔬 and demonstrate with a live demo (using
List<T> as a primary example) why unstable parameters can still cause unnecessary recompositions 🔄.A Compose Multiplatform port of yaru.dart, Ubuntu's design system. It brings the GNOME/Yaru design language — widgets, accent variants, the Ubuntu font — to Android, iOS, Desktop and Web through Compose Multiplatform.
When building a Compose UI, passing a ViewModel deep into the UI makes components less reusable because they become tied to one ViewModel type, and therefore to one screen. It also makes them harder to test in isolation and can break previews because previews are not meant to recreate the real runtime environment of the app.
The Dependency Graph
Curated libraries, tools and plugins that won't break your Gradle build.
- WARP
Widget Abstraction & Rendering Pipeline for Kotlin Multiplatform. Write home screen widgets once in Kotlin — render natively on Android (Glance) and iOS (WidgetKit + SwiftUI). - Grafima
Charts for Compose Multiplatform. Android, iOS and desktop, one codebase. Five chart types (bar, line, pie, radar, gauge) drawn onCanvas, animated, and accessible by default. - audio-stream-player
Low-latency raw PCM streaming audio player for Kotlin Multiplatform (Android, iOS, macOS) - Kmemo
Kotlin Multiplatform semantic cache for LLM calls: eleven guards against false cache hits, measured on blind corpora, coroutine-first. - Kamera
A modern camera library for Compose Multiplatform supporting Android, iOS, and Desktop with a unified API. - Kim - Kotlin Image Metadata
Kim is a Kotlin Multiplatform library for reading and writing image metadata. - Pikto
A Compose Multiplatform photo gallery library. Read the device photo library, show thumbnails, play videos and delete assets, all fromcommonMain. One Kotlin Multiplatform API over MediaStore on Android and PhotoKit on iOS. - KitFlow
KitFlow helps you create responsive layouts across Android, iOS, Desktop and Web with a simple adaptive API.
Target: Production
Showcase of real-world apps proving KMP is ready for prime time.
Carrd • Simple, free, fully responsive one-page sites for pretty much anything.
Whether it's a personal profile, a landing page for your KMP project, or something a bit more elaborate, Carrd has you covered. Simple, responsive, and yup — totally free!

Careers
Kotlin Multiplatform job postings and opportunities.
hackajob • Meet Archer, your AI job matching agent
5x more interviews. Zero guesswork. Archer works 24/7 to match you with roles that fit your stack and seniority. You review the matches, not the job boards.
Yo is building an AI inference platform that runs directly on smartphones - turning the phone in your pocket into part of a global AI network. The mobile SDK that ships this to Android and iOS devices is moving to a shared core built in Kotlin Multiplatform, replacing what was previously two separate native codebases. This is a foundational hire on a KMP effort that is just getting started.
🚀 Get Featured!
Got something interesting to share with the Kotlin Multiplatform community? Submit your link for a chance to get featured in the next issue of commonMain.dev.
🤝 Support the Build
commonMain.dev is made possible by our partners. If you have a tool or service that helps KMP developers ship to production faster, we’d love to help you reach our community. Collaborate with us.
✍ Code Review
This newsletter is curated and written by a real human being. I’m always looking for ways to optimize the build. Was there something you liked or disliked in particular? Or did you find a bug in this issue? Simply reply to this email - I read every comment from the community and take your feedback into account for the next release.
Until next time,
Stay platform-independent!
Bogdan • Founder of commonMain.dev



