KMP Interview Questions & Answers
This set covers 88 Kotlin Multiplatform (KMP) interview questions with point-wise answers, written from a working mobile developer's point of view. Each answer is concise and structured the way you should speak in an interview.
KMP Fundamentals
1. What is Kotlin Multiplatform (KMP)?
- A Kotlin technology for sharing code across platforms like Android, iOS, web, and desktop.
- You write shared business logic once and reuse it everywhere.
- Each platform keeps its own native UI.
- It is developed by JetBrains.
2. What is the core idea behind KMP?
- Share logic, not UI.
- Common code holds models, networking, and business rules.
- Platform code handles UI and platform APIs.
- This maximises reuse while keeping native experiences.
3. How does KMP differ from Flutter and React Native?
- KMP shares logic but uses native UI per platform.
- Flutter and React Native typically share the UI too.
- KMP integrates into existing native apps incrementally.
- It avoids a separate UI runtime on each platform.
4. What is Compose Multiplatform?
- A declarative UI framework that extends Jetpack Compose across platforms.
- It lets you share UI code, not just logic.
- It targets Android, iOS, desktop, and web.
- It is optional; KMP can use native UI instead.
5. What is the difference between KMP and Compose Multiplatform?
- KMP shares non-UI logic across platforms.
- Compose Multiplatform additionally shares the UI layer.
- You can use KMP alone with native UIs.
- Compose Multiplatform is built on top of KMP.
6. What is the commonMain source set?
- The shared code module compiled for all targets.
- It contains platform-agnostic logic.
- It cannot use platform-specific APIs directly.
- Platform source sets provide those via
actualdeclarations.
7. What are platform-specific source sets like androidMain and iosMain?
- They hold code specific to each target platform.
- They can access that platform's native APIs.
- They provide
actualimplementations for commonexpectdeclarations. - They compile only for their respective target.
8. What are expect and actual declarations?
expectdeclares an API in common code without an implementation.actualprovides the platform-specific implementation.- It is KMP's mechanism for platform-dependent behaviour.
- The compiler ensures every
expecthas anactualper target.
9. When do you use expect/actual?
- When shared code needs platform-specific functionality.
- Examples: platform name, secure storage, date formatting.
- Define the contract once; implement per platform.
- Prefer interfaces/DI for complex cases over many expect/actuals.
10. What targets can KMP compile to?
- Android (JVM), iOS (native), and desktop JVM.
- JavaScript and WebAssembly for web.
- Native targets like macOS, Linux, and Windows.
- You declare targets in the Gradle build.
11. How does KMP compile Kotlin to iOS?
- Kotlin/Native compiles shared code to a native binary.
- It is packaged as an Objective-C/Swift-compatible framework.
- iOS code imports it like any native framework.
- No JVM runs on iOS.
12. What is Kotlin/Native?
- A Kotlin compiler backend producing native binaries without a VM.
- It targets iOS, macOS, Linux, and more.
- It enables KMP on Apple platforms.
- It interoperates with C and Objective-C.
13. What is the difference between Kotlin/JVM and Kotlin/Native?
- Kotlin/JVM runs on the JVM, used for Android and server.
- Kotlin/Native compiles directly to machine code.
- Android shared code uses JVM; iOS uses Native.
- Memory and concurrency models historically differed.
14. How is shared code consumed on iOS?
- It is exported as a framework (often via CocoaPods or SPM).
- Swift/Objective-C imports and calls it.
- Kotlin types map to Objective-C-compatible types.
- Tools like SKIE improve the Swift API ergonomics.
15. What are the main benefits of KMP?
- Share business logic to reduce duplication and bugs.
- Keep fully native UI and performance.
- Adopt incrementally in existing apps.
- One team can maintain shared logic.
Gradle, Structure & Tooling
16. How is a KMP project structured?
- A shared module with
commonMainand platform source sets. - Platform app modules (Android app, iOS app).
- Gradle configures targets and dependencies.
- Shared code is published to each platform.
17. What role does Gradle play in KMP?
- It configures targets, source sets, and dependencies.
- The Kotlin Multiplatform plugin drives the build.
- It produces platform artifacts like AARs and frameworks.
- Version catalogs help manage dependencies.
18. What is the Kotlin Multiplatform Gradle plugin?
- The plugin enabling multiplatform builds.
- It defines the
kotlin { }block with targets. - It wires source sets and their dependencies.
- It generates the platform-specific outputs.
19. How do you add a dependency to common code?
- Add it to the
commonMaindependencies block. - It must be a multiplatform-compatible library.
- Platform-only deps go in platform source sets.
- Use KMP-ready libraries like Ktor and SQLDelight.
20. What is a multiplatform library?
- A library published with artifacts for multiple targets.
- It exposes a common API usable from shared code.
- Examples: Ktor, kotlinx.serialization, SQLDelight, Koin.
- It hides platform differences behind one API.
21. How do you share a KMP module with an iOS app?
- Export it as a framework via CocoaPods or SPM.
- Configure the framework in the Gradle build.
- Import it in Xcode and call from Swift.
- Rebuild the framework when shared code changes.
22. What IDEs and tools support KMP?
- Android Studio with the KMP plugin.
- IntelliJ IDEA and Fleet.
- Xcode for the iOS app side.
- The KMP wizard scaffolds new projects.
23. What is the hierarchical source set structure?
- Intermediate source sets shared by a subset of targets.
- Example:
iosMainshared by iOS arm64 and simulator. - It avoids duplicating code across similar targets.
- It lets related platforms share more code.
24. How do you handle platform-specific dependencies?
- Declare them in the relevant platform source set.
- Use
expect/actualto bridge to common code. - Keep the common API platform-agnostic.
- Inject platform implementations via DI.
25. How do you test shared code?
- Write tests in
commonTestrunning on all targets. - Use the kotlin.test API.
- Platform tests can verify
actualimplementations. - Run them across targets in CI.
Concurrency & Coroutines
26. How does concurrency work in KMP?
- Kotlin coroutines provide structured concurrency across platforms.
- The same suspend functions run on Android and iOS.
- Dispatchers map to platform thread pools.
- The newer memory model simplifies multithreading on Native.
27. What are coroutines?
- A lightweight concurrency primitive for asynchronous code.
- Suspend functions pause without blocking threads.
- They make async code read sequentially.
- They are the standard async approach in Kotlin.
28. What is a suspend function?
- A function that can pause and resume without blocking.
- It must be called from a coroutine or another suspend function.
- It is ideal for I/O and network work.
- It is fully supported in shared KMP code.
29. What is a CoroutineScope?
- It defines the lifecycle and context of coroutines.
- Cancelling the scope cancels its coroutines.
- It enables structured concurrency.
- Tie scopes to platform lifecycles.
30. What are dispatchers in coroutines?
- They decide which thread or pool a coroutine runs on.
Dispatchers.Defaultfor CPU work,IOfor blocking I/O.Mainfor UI on supported platforms.- They abstract platform threading.
31. What is the new Kotlin/Native memory model?
- It removed the old strict object-freezing rules.
- Objects can now be shared across threads more freely.
- It greatly simplified coroutines on iOS.
- It made KMP concurrency much more ergonomic.
32. What problems did the old memory model cause?
- It required freezing objects to share across threads.
- It led to confusing
InvalidMutabilityExceptionerrors. - It complicated multithreaded coroutines on iOS.
- The new model resolved these pain points.
33. What is a Flow in Kotlin?
- A cold asynchronous stream of values built on coroutines.
- It emits multiple values over time.
- Operators transform and combine streams.
- It works in shared KMP code.
34. How do you consume a Kotlin Flow on iOS?
- Flows do not map cleanly to Swift by default.
- Wrap them or use libraries like SKIE or KMP-NativeCoroutines.
- These expose Swift-friendly async sequences or callbacks.
- It bridges Kotlin streams to Swift concurrency.
35. How do you call suspend functions from Swift?
- Kotlin exposes them as completion-handler-based methods.
- Libraries can adapt them to Swift's async/await.
- Manage cancellation carefully across the boundary.
- SKIE improves this interop significantly.
Networking, Serialization & Data
36. How do you make network calls in KMP?
- Use Ktor client, which is multiplatform.
- Configure an engine per platform.
- Write request logic once in common code.
- Handle responses with coroutines.
37. What is Ktor?
- A Kotlin framework for clients and servers.
- Its client is multiplatform and coroutine-based.
- It supports JSON, logging, auth, and more via plugins.
- It is the common choice for KMP networking.
38. How does Ktor handle different platform engines?
- Each platform supplies an HTTP engine (e.g. OkHttp, Darwin).
- The common API stays the same.
- You add the engine in the platform source set.
- This abstracts native networking.
39. How do you serialize JSON in KMP?
- Use kotlinx.serialization, which is multiplatform.
- Annotate models with
@Serializable. - It generates serializers at compile time.
- It integrates with Ktor for request/response bodies.
40. What is kotlinx.serialization?
- A Kotlin-first serialization library.
- It avoids reflection by generating code.
- It supports JSON, ProtoBuf, and more.
- It works across all KMP targets.
41. How do you persist data locally in KMP?
- Use SQLDelight for a typed, multiplatform database.
- Use multiplatform-settings for key-value storage.
- Each wraps platform storage under a common API.
- Choose based on data complexity.
42. What is SQLDelight?
- A library generating typesafe Kotlin from SQL.
- It is multiplatform, backed by SQLite per platform.
- You write SQL; it generates APIs.
- It is a common KMP persistence choice.
43. How do you store sensitive data in KMP?
- Use platform secure storage via
expect/actual. - Keychain on iOS, Keystore/EncryptedSharedPreferences on Android.
- Never store secrets in plain settings.
- Libraries like multiplatform-settings have encrypted variants.
44. How do you handle dates and time across platforms?
- Use kotlinx-datetime for multiplatform date/time.
- It provides instants, time zones, and durations.
- It avoids platform API differences.
- It works in common code.
45. How do you handle dependency injection in KMP?
- Use Koin, which is multiplatform.
- Define modules in common code.
- Provide platform implementations where needed.
- It enables testable, decoupled shared code.
Architecture & Shared Logic
46. How do you architect a KMP app?
- Put models, repositories, and use cases in shared code.
- Keep UI native per platform.
- Expose shared ViewModels or presenters.
- Use DI to wire platform implementations.
47. What is a shared ViewModel in KMP?
- Presentation logic placed in common code.
- It exposes state via Flow or observable holders.
- Both platforms drive their UI from it.
- It reduces duplicated presentation logic.
48. How do you share state between platforms?
- Expose state as
StateFlowfrom shared code. - Android collects it directly; iOS uses a bridge.
- Keep a single source of truth in common.
- UIs only render the shared state.
49. What is the repository pattern in KMP?
- A shared layer abstracting data sources.
- It combines network and local storage.
- It exposes a clean API to the domain layer.
- It centralises data logic across platforms.
50. How much code can realistically be shared with KMP?
- Often 50-85% depending on UI sharing.
- Logic, networking, and data share well.
- UI and platform integrations stay native.
- Compose Multiplatform raises the share further.
51. What should stay platform-specific?
- UI, navigation, and platform APIs.
- Permissions, sensors, and notifications.
- Anything tied to native frameworks.
- Bridge these via
expect/actualor DI.
52. How do you handle navigation in a KMP app?
- Native navigation per platform with native UI.
- Decompose or Compose Multiplatform navigation when sharing UI.
- Shared logic can drive navigation state.
- Keep routing decisions testable in common code.
53. What is Decompose?
- A library for shared lifecycle-aware components and navigation.
- It structures shared business and navigation logic.
- It works with Compose Multiplatform.
- It helps build scalable shared apps.
54. How do you handle errors across platforms?
- Model errors as sealed classes in common code.
- Map exceptions to typed results.
- Surface them to each native UI.
- Keep error handling consistent and shared.
55. What are sealed classes and why are they useful in KMP?
- They model a restricted hierarchy of types.
- Great for representing states and results.
whenover them is exhaustive.- They make shared state modelling safe.
Interoperability
56. How does Kotlin interoperate with Swift and Objective-C?
- Kotlin/Native exposes an Objective-C-compatible framework.
- Swift calls it through that bridge.
- Some Kotlin features map imperfectly to Swift.
- Tools like SKIE improve the generated API.
57. What are common interop limitations on iOS?
- Generics, sealed classes, and Flows map awkwardly.
- Default arguments are not exposed.
- Kotlin names may be mangled in Swift.
- SKIE addresses many of these gaps.
58. What is SKIE?
- A tool that enhances Kotlin-to-Swift interop.
- It maps sealed classes, Flows, and suspend functions idiomatically.
- It improves the Swift developer experience.
- It plugs into the KMP build.
59. How do you expose Kotlin enums and sealed classes to Swift?
- By default they appear as Objective-C classes.
- Exhaustive Swift handling is limited without tooling.
- SKIE exposes them as Swift enums.
- This enables idiomatic
switchin Swift.
60. How does Kotlin interop with C?
- Kotlin/Native provides C interop via cinterop.
- You generate Kotlin bindings from C headers.
- It enables using native C libraries.
- It is used under the hood by some libraries.
61. How do you call platform APIs from shared code?
- Define an
expectdeclaration in common. - Provide
actualimplementations per platform. - Or inject a platform interface implementation.
- This keeps common code clean.
62. How do you use Android-specific APIs in KMP?
- Place them in the
androidMainsource set. - Implement
actualdeclarations there. - Common code references only the
expectAPI. - This isolates Android dependencies.
63. How do you use iOS-specific APIs in KMP?
- Use the
iosMainsource set. - Kotlin/Native exposes Apple frameworks via platform bindings.
- Call UIKit/Foundation APIs from Kotlin there.
- Provide
actualimplementations for common contracts.
Performance, Build & CI
64. How does KMP performance compare to native?
- Shared logic runs as native code on each platform.
- There is no UI runtime overhead with native UI.
- Performance is generally close to native.
- Interop boundaries add minor cost on iOS.
65. What affects iOS framework size in KMP?
- Shared code and bundled dependencies add size.
- Dead-code elimination helps reduce it.
- Static vs dynamic framework choice matters.
- Keep shared dependencies lean.
66. How do you speed up KMP builds?
- Enable Gradle caching and configuration cache.
- Limit targets during development.
- Use incremental compilation.
- Cache the iOS framework build where possible.
67. How do you set up CI for a KMP project?
- Run common and platform tests on each push.
- Build Android and iOS artifacts.
- Use macOS runners for iOS builds.
- Cache Gradle and Kotlin/Native dependencies.
68. How do you distribute the shared framework to iOS developers?
- Publish via CocoaPods or Swift Package Manager.
- Or build the XCFramework in CI.
- Version it so iOS pins a known build.
- Automate regeneration on shared-code changes.
69. What is an XCFramework?
- A bundle containing a framework for multiple architectures.
- KMP can produce one for device and simulator.
- iOS apps integrate it cleanly.
- It simplifies distribution.
70. How do you debug shared KMP code?
- Debug Android shared code in Android Studio.
- Debug iOS via Xcode with Kotlin/Native support.
- Use logging that works across platforms.
- Write common tests to catch logic bugs early.
Adoption, Comparison & Best Practices
71. How do you adopt KMP incrementally in an existing app?
- Start by sharing one module like networking or models.
- Integrate the shared library into both apps.
- Expand sharing as confidence grows.
- No full rewrite is required.
72. What is a good first feature to share with KMP?
- Networking and data models.
- Validation and business rules.
- Anything UI-independent and well-tested.
- Avoid starting with UI or platform-heavy code.
73. What are the trade-offs of adopting KMP?
- Pros: shared logic, native UI, incremental adoption.
- Cons: iOS interop rough edges, build complexity.
- Tooling is improving but still maturing.
- Team needs Kotlin and native knowledge.
74. When should you not use KMP?
- For tiny apps where sharing adds overhead.
- When the team lacks Kotlin experience.
- When near-total UI sharing is the main goal (consider Flutter).
- When platform-specific logic dominates.
75. How does KMP fit teams with separate iOS and Android developers?
- Both contribute to shared Kotlin logic.
- Each owns their native UI.
- It encourages collaboration on common code.
- iOS devs may need to learn some Kotlin.
76. Is KMP production-ready?
- KMP is stable and used by many companies.
- Core tooling and libraries are mature.
- Compose Multiplatform for iOS is newer but advancing.
- Evaluate based on your risk tolerance.
77. What companies use KMP?
- Several large apps have adopted it publicly.
- Examples include companies sharing networking and logic.
- JetBrains showcases case studies.
- Adoption continues to grow.
78. How do you handle logging across platforms?
- Use a multiplatform logging library like Napier or Kermit.
- It routes to platform log systems.
- Configure it in common code.
- It keeps logging consistent.
79. How do you handle analytics in KMP?
- Define a common analytics interface.
- Provide platform implementations via
actualor DI. - Call it from shared logic.
- This centralises event definitions.
80. How do you share resources like strings in KMP?
- Use a resources library like moko-resources or Compose resources.
- It exposes localized strings and assets in common code.
- It maps to platform resource systems.
- It avoids duplicating resource handling.
81. How do you manage configuration (dev/prod) in KMP?
- Expose config via build variables or DI.
- Provide platform values where needed.
- Keep secrets out of shared source.
- Switch endpoints per build.
82. How do you write unit tests for shared logic?
- Place tests in
commonTest. - Use kotlin.test assertions.
- Mock dependencies via interfaces.
- They run on every target.
83. How do you mock platform dependencies in tests?
- Depend on interfaces, not concrete platform classes.
- Provide fake implementations in tests.
- Inject them via DI.
- This keeps shared tests platform-independent.
84. What is the difference between KMP and KMM?
- KMM (Kotlin Multiplatform Mobile) was the mobile-focused branding.
- KMP is the broader, current umbrella term.
- They refer to the same core technology.
- JetBrains now generally says KMP.
85. Can you share UI with KMP without Compose Multiplatform?
- By default KMP shares logic, not UI.
- UI stays native unless you use Compose Multiplatform.
- Some teams deliberately keep UI native.
- This preserves full platform fidelity.
86. How does Compose Multiplatform render on iOS?
- It uses a Skia-based renderer (Skiko).
- It draws the UI rather than using UIKit views.
- Interop with native views is supported.
- It is newer than the Android Compose target.
87. What are common pitfalls when starting with KMP?
- Trying to share too much, including UI, too early.
- Underestimating iOS interop rough edges.
- Skipping common tests.
- Not automating framework distribution.
88. Why would a team choose KMP over a fully cross-platform framework?
- To keep fully native UI and platform feel.
- To adopt incrementally without a rewrite.
- To reuse existing native code and skills.
- To share logic while avoiding a separate UI runtime.