8 min read

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 don't think shared Compose Multiplatform UI is the future for iOS (yet)

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.

Yet Another Way to KMP: One Pattern, Three Seams

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.
Why We Chose KMP Over React Native: It’s an Architecture Bet, Not a Framework Preference

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 One-Liner That Was Eating Our Memory

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.
One Codebase, Two On-Device Brains: Gemini Nano and Apple Intelligence in Compose Multiplatform

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.
Scanning bus stop codes with ML Kit and Vision in the GalwayBus Compose Multiplatform app

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.
The 7% You Can’t Share

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.
The challenge of adding a Web target to DroidconKotlin

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.
Same Car, Every Time: Deterministic Feature Module Generation in KMP

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.

Stop Ignoring Compose Stability (Yes, Even with Strong Skipping Mode)

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 🔄.
Yaru Compose UI

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.
From God ViewModel to Composed Screen Logic

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 on Canvas, 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 from commonMain. 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.

Hourly Journal - Hourly Mood Tracker & Micro Journaling App
Hourly Journal is a calm hourly check-in journal for mood, voice journaling, photos, energy and stress. Micro journaling on Android & iOS.
GitHub - ber4444/motoman-kmp: Kotlin Multiplatform 3D motorcycle racing game — shared engine and OpenGL ES renderer, Compose Multiplatform HUD.
Kotlin Multiplatform 3D motorcycle racing game — shared engine and OpenGL ES renderer, Compose Multiplatform HUD. - ber4444/motoman-kmp
GitHub - joreilly/GalwayBus: Galway Bus Kotlin Multiplatform project using Jetpack Compose and SwiftUI
Galway Bus Kotlin Multiplatform project using Jetpack Compose and SwiftUI - joreilly/GalwayBus

Careers

Kotlin Multiplatform job postings and opportunities.

Senior Kotlin Multiplatform Engineer - YOnC SDK at Yonder Media Mobile

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.

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