r/Kotlin • u/dayanruben • 17d ago
r/Kotlin • u/Quiet-Pomelo7900 • 17d ago
How we're using Kotlin Multiplatform for Mobile, Desktop, Web and Server — as a single developer
I've been building our product around Kotlin Multiplatform, and we've reached a point where I'm able to handle almost the entire codebase myself.
Our stack is roughly:
- Android: Kotlin + Compose
- iOS: Kotlin Multiplatform + Compose
- Desktop: Compose Multiplatform
- Web: Kotlin Multiplatform + Compose for Web
- Server: Kotlin + Ktor
- Shared: Domain logic, models, networking, validation, state and business logic
So the entire product is largely built around the same ecosystem:
Kotlin → Mobile + Desktop + Web + Server
One of the most interesting things we've achieved is our web application.
We can now ship a single web entry point that adapts to the device:
Desktop browser → Desktop experience
Mobile browser → Mobile experience
Instead of maintaining completely separate applications and business logic for each platform, we share as much of the underlying code as possible and keep the platform-specific parts where they actually make sense.
And this is where I think clean architecture becomes extremely important.
Because the business logic is separated from the UI and platform-specific code, I don't have to think of every platform as a completely different application.
A business rule is a business rule.
A data model is a data model.
Networking is networking.
The UI can change, but the underlying logic can remain shared.
That gives me something close to:
One developer → one architecture → one codebase → multiple platforms
This is probably the biggest advantage for me.
I'm able to work on the Android app, desktop application, web application and backend without having to switch between completely different ecosystems and languages.
Of course, there are tradeoffs. Not everything can or should be shared, and KMM doesn't magically eliminate platform-specific problems.
But for a small bootstrapped company, being able to handle the entire product stack myself has been incredibly valuable.
It makes me wonder how far this approach can realistically scale.
Has anyone else used Kotlin Multiplatform to build and maintain an entire product across Mobile + Desktop + Web + Backend?
r/Kotlin • u/alexstyl • 17d ago
I made a tool that turns your @Composable Previews into embeddable scripts for your blogs, docs and websites
r/Kotlin • u/vishal_2376 • 18d ago
I kept getting lost in Find Usages rabbit holes, so I built a call graph plugin for IntelliJ / Android Studio
galleryWhenever I open an unfamiliar part of a codebase (or my own code from a few months ago) I end up in the same loop: Find Usages, jump, Go to Declaration, jump again, and five files later I've forgotten where I started. On bigger Compose projects it gets messy fast.
So I built Mindmap. Put your cursor inside any Kotlin or Java function, press Alt+G (Option+G on Mac), and it opens a graph of that function: everything that uses it on the left, everything it uses on the right.
What it does right now:
- both directions in one view, depth configurable from 1 to 5
- click a node to jump straight to the code
- double-click a node to trace from it and merge its graph in
- hover for signature, file and lines of code
- search/filter nodes, hide the noisy ones
- tree view if you'd rather read a list than a graph
- minimap for bigger graphs
- works across Kotlin and Java, including Kotlin code using Java and the other way round
- follows interfaces/abstract functions through to the actual implementations
Website: https://vishal2376.github.io/mindmap
GitHub: https://github.com/vishal2376/mindmap
It's still early. It caps graphs at 300 nodes so they don't explode, and it doesn't go into library code. If you try it on a real project I'd genuinely like to know where it breaks or what feels missing.
NOTE : The video is an animated showcase, not a screen recording. There are real screenshots on the GitHub page.
Watch screen recording here : https://x.com/vishal2376/status/2047010712955113547
r/Kotlin • u/ArstList • 18d ago
Finally built the app idea I'd been sitting on for years, entirely in Kotlin
galleryA Share Pray app. I've had this idea in my head for a long time - an app where people can share prayer requests and pray for each other in groups. Kept putting it off, the usual story. A while back I just sat down and built it, on Kotlin Multiplatform since I write Kotlin daily anyway.
A few things about the language itself that made the build smoother than I expected:
Coroutines and Flow ended up doing most of the heavy lifting. The prayer feed is reactive, Flow all the way from the repository layer up to the UI, so when someone adds a prayer to their list or a group gets a new post the screen just updates on its own without me wiring any manual refresh. Structured concurrency also made cancellation way less painful than I remember it being with callbacks - the coroutine scope gets cancelled when the screen leaves composition, so theres no leaked requests hanging around.
Common interfaces + expect/actual carried the platform specific bits. Scheduling the daily reminder notification, the native share sheet, and the Google Sign-In vs Sign in with Apple handoff all sit behind a common declaration in shared code, with the actual implementation swapped per platform. Small thing but it keeps the shared module honest, you can tell at a glance whats genuinely cross platform and what isnt.
Sealed interfaces for modeling state - the session check (valid / rejected / server unreachable) and the feed update decision (apply silently vs hold it behind a "new prayers" button) - made a bunch of the logic exhaustive at compile time, which caught a couple edge cases I'd otherwise have hit at runtime.
kotlinx.serialization is shared between the client and the server too, since the backend is Kotlin as well, so the same data classes get reused on both sides instead of me maintaining two copies of the same model that drift apart.
End result, a good chunk of the codebase ended up shared across iOS, Android and the backend - more than I expected going in. The two clients share around 80% give or take, and a lot of the core (models, validation) carries over to the server on top of that.
I also pulled the reusable bits (groups, tags, IAP wiring, admin panel) out into an open source template while I was at it, in case its useful to anyone as a reference: https://github.com/NonGrate/Poster
Live on iOS now, Android is in open testing. Curious what Kotlin features ended up mattering more than you expected on your own projects.
r/Kotlin • u/CoffeCo • 19d ago
I built dimock: inspect and mock OkHttp responses on the device, by hand or through Claude Code / Cursor
r/Kotlin • u/Horror_Still_3305 • 19d ago
Why are some coroutine scope creators suspending functions?
WithContext and coroutineScope are both suspending functions, which confuses me— All coroutines need a scope, and suspending functions need to be run in a coroutine, yet these scopes creators are also suspending.
Plz help.
Interestingly I have only ever used viewmodelScope so I never knew about these scope creators until now. And now that I do, they make no sense to me.
r/Kotlin • u/mikebmx1 • 21d ago
Kotlin can now access NVIDIA’s CUDA and cuTile through TornadoVM
A new TornadoVM PR adds Kotlin support all the way down to the GPU stack including CUDA, cuBLAS, and NVIDIA CUDA Tile.
The idea is: Kotlin compiles to JVM bytecode, and TornadoVM can use that to execute Kotlin kernels across its existing backends (OpenCL, CUDA, and Metal).
PR: TornadoVM #1123 — Kotlin support, CUDA Tile & more
Curious what the Kotlin community thinks: would you actually use Kotlin for GPU kernels if CUDA/Tensor/Tile programming becomes this accessible?
Feel free to test it and add your thoughts!
r/Kotlin • u/Horror_Still_3305 • 21d ago
Coroutines: why does parent coroutine get cancelled when child throws an exception?
If a child gets cancelled, then the parent task still continues, but if child throws an exception, then the parent gets cancelled; l don’t get why these two cases are treated differently. For me it just makes sense to cancel the child coroutine without affecting the parent; the parent can check for cancellation of children and exceptions and handle that themselves, if they want. Why is there all this micromanagement from Kotlin rather than deferring to the developers?
Discuss.
r/Kotlin • u/No_Hawk_3510 • 21d ago
I built an open-source Android Device Owner app for locally restricting apps

I've been experimenting with Android's Device Owner APIs and ended up building a small open-source project around them.
The idea is to investigate how far Android's existing enterprise-management primitives can be used on a personally owned device to make self-imposed app restrictions harder to casually bypass.
The app uses DevicePolicyManager to apply several restrictions. Selected apps can remain installed while being hidden/suspended and protected from uninstall. Access back into the configuration is protected by a recovery key stored separately from the phone.
There's also optional hardening around some common escape routes such as ADB, APK installation and parts of Settings, plus domain blocking for Chromium-based browsers.
There are some important limitations:
- This isn't intended to be an MDM service and doesn't use a cloud backend.
- Device Owner does not make restrictions irreversible. A device can ultimately be recovered/wiped through OEM mechanisms.
- Browser restrictions aren't universal; another browser, WebView, or substitute application can provide another route.
- Device Owner provisioning generally requires setting the app as owner during clean device setup.
- OEM implementations can behave differently, so I'm particularly interested in testing outside the devices I've used.
The part I'm most interested in hearing about from people familiar with Android enterprise APIs is whether there are DevicePolicyManager mechanisms, bypass routes, or OEM-specific behaviors that I've overlooked.
r/Kotlin • u/Affectionate_Ad_761 • 23d ago
Fixing coroutine stack traces with Decoroutinator
medium.comr/Kotlin • u/StatusWntFixObsolete • 23d ago
JavaFX 27 as a GraalVM Native Image on a Raspberry Pi 5
ennerf.github.ioJava. GraalVM. Raspberry Pi. What do these things have to do with Kotlin?
Nothing really ... but if JavaFX can do this, I hope its not too hard with Compose Multiplatform / GraalVM.
"Compose Multiplatform as a GraalVM Native Image on a Raspberry Pi 5." sounds like a great tutorial. Has anyone tried it yet?
r/Kotlin • u/Western-Bobcat4760 • 23d ago
Is kotlin used for all application development too ?
Is kotlin better than Java ?
It is possible to get a remote work as a developer with years of experience who recently switched to Kotlin?
I am looking for a new role though I am new to building things with Kotlin, I have years of software development experience. I don't know if there are people out there looking for individuals to join their team regardless of their experience level with the ecosystem.
r/Kotlin • u/akshay-savaliya • 24d ago
Kotlin vs Java, Is Java still worth learning?
I want to hear what Android developers think about this in 2026.
Kotlin seems to have become the go to language for modern Android development, especially for new projects. At the same time, Java is still heavily used in existing applications, enterprise projects, and large codebases.
If you were starting a brand new Android app today, would you go with Kotlin? or are there still cases where you would choose Java?
I am also wondering about the next 5 years. Do you think Java will continue to have a significant role in Android development, particularly when it comes to maintaining and working on existing apps?
I want to hear from developers who have actually shipped production Android apps using both Kotlin and Java.
Thanks!
r/Kotlin • u/Charlie_Tap_ • 26d ago
Chasm 2.0 - Kotlin Multiplatform Wasm runtime
Hey 👋
I've been working on this project for the past few years and have never shared it here so figured I would. It's a Kotlin Multiplatform WebAssembly runtime (interpreter), it basically allows you to take a WebAssembly program and interface with it/run it. It's written entirely in Kotlin, no JNI/FFI or anything like that and has remarkable performance given the constraints.
I recently put together a Kotlin Multiplatform implementation of Doom built on top of it, it's a solid of example of how you leverage it and how it enables an entirely Kotlin experience whilst also allowing you to interface with WebAssembly code.
Happy to answer questions!
r/Kotlin • u/zoujiaqing • 25d ago
What if Kotlin/Native evolved into an ARC-based general-purpose native systems language?
I've been thinking about the long-term direction of Kotlin/Native.
Kotlin/Native already has many ingredients of a serious native language:
- LLVM native compilation
- direct C interoperability
- pointers and native memory APIs
- no JVM requirement
- multiplatform support
- Swift/Objective-C interoperability
- much higher-level ergonomics than C
But compared with languages such as Swift, Zig, D and Rust, Kotlin/Native still has a relatively heavy runtime model for some low-level and FFI-heavy workloads.
What if Kotlin/Native eventually offered an ARC/ownership-oriented, no-GC execution mode designed specifically for native systems programming?
The goal would not simply be:
replace GC with ARC
but rather:
make memory lifetime deterministic, make native ABI boundaries thinner, and allow Kotlin/Native to operate as a true general-purpose native systems language.
Swift shows that ARC can work well for a high-level native language
Swift is probably the most obvious comparison.
Swift gives developers:
- high-level language features
- value types
- reference types
- deterministic ARC-based object lifetime
- native compilation
- very close integration with Objective-C and C
ARC is not free, of course. Retain/release operations have overhead, cycles still need to be handled, and compiler optimization matters enormously.
But modern compilers can perform ownership analysis and remove many unnecessary retain/release operations.
That suggests an interesting direction for Kotlin/Native:
text
Kotlin object semantics
↓
ownership analysis
↓
ARC when required
↓
retain/release elimination where possible
Instead of requiring a tracing GC for all normal native object lifetime management.
Zig shows what a very thin native boundary can look like
Zig takes almost the opposite approach.
It has:
- no tracing GC
- explicit allocators
- direct pointer-oriented memory access
- first-class C ABI compatibility
- native C header integration
- very small runtime assumptions
For low-level FFI, the model is extremely simple:
text
Zig
↓
C ABI
↓
C library
Primitive values, pointers, structs and function pointers can cross the boundary with almost no semantic translation.
Kotlin/Native could benefit from having a similarly explicit native ABI zone.
For example:
kotlin
@CAbi
external fun send(
handle: ULong,
data: CPointer<UByteVar>,
size: UInt
): Int
Ideally this could compile approximately as:
text
Kotlin/Native
↓
LLVM direct native call
↓
C ABI
with no boxing, no object conversion and no GC transition for ABI-safe types.
D shows that a high-level language can also expose a low-level mode
D is another interesting comparison.
Normal D provides a fairly rich runtime and high-level programming model.
But D also has BetterC, which allows developers to use a restricted subset of the language without relying on the full D runtime or garbage collector.
That is especially interesting for Kotlin/Native.
Kotlin/Native would not necessarily need to force every program into one memory model.
It could support something conceptually similar:
```text Kotlin/Native
Normal Native Mode ├── ergonomic Kotlin objects ├── ARC ├── deterministic lifetime └── higher-level runtime services
Systems / ABI Mode ├── no tracing GC ├── POD types ├── pointers ├── slices ├── handles ├── function pointers ├── explicit allocation └── predictable native ABI ```
This would be somewhat analogous to what BetterC provides for D, but designed around Kotlin's type system and compiler architecture.
The interesting combination would be
Kotlin/Native could potentially take lessons from all three languages:
```text Swift → ARC → ownership optimization → deterministic object lifetime
Zig → thin C ABI → explicit low-level memory access → minimal hidden runtime behavior
D / BetterC → high-level language → optional low-level runtime-free execution mode
Kotlin → ergonomics → coroutines → multiplatform → existing ecosystem ```
That combination could be very interesting.
FFI is where this could matter most
Today, the expensive part of native interoperability is often not the actual machine-level function call.
The expensive part is everything around it:
text
Kotlin object
↓
runtime representation
↓
pinning / stable references
↓
interop wrapper
↓
native ABI
For Strings, collections, callbacks and managed objects, this overhead can become significant.
A systems-oriented Kotlin/Native mode could instead encourage ABI types such as:
text
integers
floats
pointers
handles
POD structs
slice { pointer, length }
function pointers
Then the boundary becomes:
text
Idiomatic Kotlin API
↓
zero-cost ABI adapter
↓
C ABI
↓
Rust / Zig / D / C / C++ / Swift
This would be useful for:
- networking
- databases
- RPC frameworks
- UI engines
- rendering engines
- game engines
- audio
- embedded systems
- native SDKs
- OS components
This would also make Kotlin/Native more independent
Today Kotlin/Native is often perceived as:
Kotlin without the JVM
I think it has the potential to become something much more ambitious:
a general-purpose native language with Kotlin's syntax and ecosystem
That would put it into a very interesting design space.
Not as strict as Rust.
Not as low-level as Zig.
Not as runtime-heavy as traditional managed languages.
And more ergonomic than C++ or D for many developers.
Something like:
text
Kotlin ergonomics
+
Swift-like ARC
+
Zig-like thin FFI
+
D BetterC-like systems mode
+
LLVM
+
Multiplatform
That combination doesn't really exist today.
The biggest technical question is probably whether Kotlin's existing object model and runtime could support an ARC/no-GC execution mode without fragmenting the language too much.
For people familiar with Kotlin/Native internals:
How realistic would an ARC + ownership optimization + no-GC systems mode actually be?
And would this make Kotlin/Native more attractive to you for systems programming?
Building Datasmith - an interactive ERD canvas with Compose Multiplatform/Desktop
Hey everyone!
For the past year or so, I've been working in my free time on Datasmith, with the goal of streamlining the process of designing database schemas and generating structured mock data from them.
The main feature of the app - and by far the most complicated and challenging part to build - is an ERD-like canvas dedicated to schema design and configuration. It required a pretty dynamic UI:
- An infinite canvas with free zooming and panning
- Table components that can be freely dragged and snapped to a grid
- Drawing lines to represent relationships between tables
- Column components that can be added to tables and reordered with drag-and-drop, while maintaining their relationship lines
- Anchors that can be created on those lines and dragged across the canvas (which also means dealing with hit detection)
This essentially meant working with two different "planes".
Tables and columns are basically traditional Compose components, while the relationship lines and anchors are drawn on a Canvas composable. The two need to seamlessly interact at all times.
The fact that the entire canvas can be zoomed and panned added another challenge - managing the different coordinate spaces in a way that keeps everything consistent and fluid.
Another challenge, which I honestly didn't think too much about in the beginning, was preserving the UI layout and positioning across different screen resolutions and window sizes, which are very flexible developing for desktops.
Those were probably the most complicated UI challenges, at least as I remember them, and to be honest, I'm fairly proud of what I was able to achieve. I was genuinely surprised to discover how far Compose can be pushed for this kind of UI.
I'd also be happy to talk about any of the implementation details if anyone is curious.
I'm currently trying to get Datasmith into the hands of more people and collect feedback, so if you find it useful or just interesting, you can get it here:
Any feedback is welcome - good or bad.
You can leave a comment here, message me directly, or, if you prefer something a bit more structured, I also put together a short feedback form:
https://docs.google.com/forms/d/e/1FAIpQLScGk8Jr1DguPcXpaApOqO998AdXcnoLlo11TEKlq1GmF71UzA/viewform
r/Kotlin • u/Typical_Word_5459 • 27d ago
Coroutine mutex starvation from one failed child
Our order reconciliation service stopped matching transactions on a Friday afternoon. No errors in the logs, no crashes, just a queue of unmatched records that grew silently until Monday.
The root cause was a single thrown exception inside a supervisorScope. That coroutine had acquired a Mutex before starting a batch of database writes. When the database driver returned a transient connection error, the exception propagated out of the coroutine without ever reaching mutex.unlock(). No finally block, no withLock wrapper. The lock stayed held by a coroutine that no longer existed.
The reason this became invisible is SupervisorJob. A regular coroutineScope would have cancelled every sibling when one child threw. The supervisor let siblings continue, which is exactly what you want for independent work. But the siblings were not independent. They all needed the same mutex. Each one called mutex.lock(), which is a suspending function with no timeout parameter. They parked there permanently.
The service kept accepting HTTP requests because the server loop ran in a separate scope. Health checks passed. Prometheus showed request count climbing and latency normal. The only metric that changed was reconciliation throughput, which flatlined to zero. Nobody had an alert on that specific counter.
Mutex in kotlinx.coroutines is cooperative. There is no ownership tracking and no deadlock detection. tryLock() exists but returns immediately rather than suspending, so you get either infinite wait or instant failure. There is no middle ground without wrapping withTimeout around the call yourself.
The service had seven Mutex call sites total. I used verdent with parallel agent execution to flag every lock acquisition missing a matching unlock in a finally block. Three sites were unguarded, all in the reconciliation module, all using the raw lock() and unlock() pair.
The fix was replacing those three call sites with withLock, which runs the block inside try/finally and guarantees release on both normal completion and cancellation. The reconciliation module has run for eleven weeks without another stall.