Kotlin Multiplatform Newsletter #42
We explore real-time low-latency audio processing in Kotlin with Phil Burk, analyze browser threading constraints in Compose Multiplatform Web apps, and detail CI/CD pipeline strategies for KMP using GitHub Actions. We also dive into hardening Turbine Flow tests, avoiding subtle Kotlin Flow bugs, implementing recomposition-free AGSL holographic shaders, and utilizing Haze 2.1 glass merging effects. Plus, embedding Kotlin in Godot games via Godot-JVM, dithered UI components with Stipple, streaming Ogg Opus audio with koggopus, and an in-browser horror game powered by Gemma 4 and KMP.
The Main Thread
Community's most insightful threads, curated from social media platforms and websites.
Experimental music software developer Phil Burk joins us to discuss the complexities of building low-latency, real-time audio applications across platforms. We dive into the architecture of modern audio pipelines, the challenges of cross-platform sound processing, and how Kotlin fits into the audio development ecosystem.
Expect Actual
Technical deep dives, or solving the "how-the-hell-do-I-test-this" problems.
affiliate link
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
kotlinx.coroutines library is multiplatform. It works on Android, on the JVM in desktop apps, on iOS, and in the browser. But unlike the other platforms, the browser does not have an equivalent threading model where code can run in parallel with access to shared memory. This is why, if your project has a web target, you will find two important differences.This isn’t a story about a heroic rewrite. The real story is less dramatic and, I think, more useful: the migration was easier than it could have been because of choices made long before it started. How much a platform shift hurts is decided largely by architectural decisions made years earlier, often for entirely different reasons.
KMP gives you one codebase and two (or more) build targets. That’s the pitch. What the pitch leaves out is that Android and iOS builds have completely separate toolchains, separate runners, and separate failure modes. The shared module compiles fine for JVM and then refuses to link for the iOS simulator because you used a dependency that doesn’t support
iosArm64. The Android unit tests pass and the commonTest suite throws a NullPointerException that only surfaces on the JVM. Both builds succeed locally because you only ran one of them.Testing Flows in your app can be confusing, especially when they’re interconnected with multiple data sources and emissions coming from multiple places. In this second part of our Coroutine testing series we’ll look deeper into how Turbine works with different types of Flows. Then in the next part we’ll cover how testing coroutines changes in KMP and finally I’ll cover how this can be made into a skill for AIs to use when testing your code. This post assumes you have basic knowledge of Turbine.
Flow bugs are surprisingly easy to introduce. The code compiles, the operators look good, everything works during dev testing but then an extra collector appears, and/or request gets cancelled, or a test never receives an update.LazyColumn
Compose Multiplatform tips, tricks, and code snippets.
In this article I’ll walk you through how the effect works: why the scratch surface had to change, the AGSL shader layer by layer, and how the tilt of the phone reaches the shader without a single recomposition. The full code is in the gists along the way.
Haze 2.1 is out, and Glass is now stable. Haze brings background blur and glass effects to Jetpack Compose and Compose Multiplatform. In this release, Glass surfaces can also merge and separate.
The Dependency Graph
Curated libraries, tools and plugins that won't break your Gradle build.
- Stipple
A small dither engine, modifiers that dither any element, and eleven ready-made components: buttons, charts, gauges, text, text effects, avatars, images and backgrounds. Android, iOS, desktop and the browser, from onecommonMain. - Orrery
Compose Multiplatform calendars and date pickers for Android, iOS, Desktop and Web. - Compose System Bars
Set status bar and navigation bar icon colors from Compose Multiplatform. Each screen declares the icons it needs. The library applies them on Android and iOS, and brings back the previous ones when the screen leaves. - Styled QR KMP
Kotlin Multiplatform QR generator for Android, iOS and Web. Styled QR codes without Google Play services or ZXing. - koggopus
Streaming Ogg Opus encoder and decoder for Kotlin Multiplatform (Android, iOS, macOS, Linux and desktop JVM), built on libopus, libogg and libopusenc. - Godot-JVM
Brings Kotlin, Java, and Scala to the Godot engine. It is a GDExtension addon that embeds a JVM in the editor and in your exported games, so you write gameplay code in the language and tooling you already trust while keeping the official editor, scenes, and asset pipeline exactly as they are.
Target: Production
Showcase of real-world apps proving KMP is ready for prime time.
SPONSORED
wellfound • Where great companies meet great people.
The next company that changes the world, and the role that changes yours. Wellfound is where 27,000+ startups hire. Apply directly to the founders and hiring managers building what's next.
🚀 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
commonMain.dev is not affiliated with JetBrains or the Kotlin Foundation.
Kodee by JetBrains s.r.o. is licensed under CC BY 4.0.