Kotlin Multiplatform Common — Complete Guide
In this tutorial, you'll learn about Kotlin Multiplatform Common. We cover key concepts, practical examples, and best practices.
The Problem
Your KMP project doesn't compile because expect functions don't have matching actual implementations, or common code can't use platform-specific APIs.
Wrong Approach ❌
// expect declaration without actual on all platforms
expect fun getPlatformName(): String
// Missing actual in androidMain and iosMain!
// Putting platform code in commonMain
// commonMain
fun formatDate(date: Date): String { // Date is JVM-only!
return SimpleDateFormat("yyyy-MM-dd").format(date)
}
Output: Compilation error: Actual declaration for expect fun getPlatformName() not found. Platform type in common code.
Right Approach ✅
// commonMain
// Define your expect declarations
expect fun getPlatformName(): String
// Common business logic — no platform types
data class User(val id: String, val name: String)
// Use interfaces for platform-specific behavior
expect class PlatformContext
expect class Database {
fun saveUser(user: User)
fun getUser(id: String): User?
}
// Common code using expects
class UserRepository(private val db: Database) {
fun greet(): String = "Hello from ${getPlatformName()}"
fun save(user: User) = db.saveUser(user)
}
// androidMain
actual fun getPlatformName(): String = "Android ${Build.VERSION.SDK_INT}"
actual class Database(private val context: PlatformContext) {
actual fun saveUser(user: User) { /* Room DB */ }
actual fun getUser(id: String): User? { /* Room query */ }
}
// iosMain
actual fun getPlatformName(): String = "iOS ${UIDevice.currentDevice.systemVersion}"
actual class Database {
actual fun saveUser(user: User) { /* CoreData */ }
actual fun getUser(id: String): User? { /* CoreData fetch */ }
}
// Use kotlinx-datetime for cross-platform date handling
// In build.gradle.kts:
// commonMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") }
Output: KMP project compiles across all platforms with proper expect/actual.
Prevention
- Keep business logic in
commonMain. - Use
expect/actualfor platform-specific APIs. - Never put platform-specific types in
commonMain. - Use KMP-compatible libraries (
kotlinx-datetime,kotlinx-serialization). - Use
@OptionalExpectationfor optional actual declarations.
Common Mistakes with multiplatform common
- Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
These mistakes appear frequently in real-world KOTLIN code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro