skills/g1joshi/agent-skills/kotlin-multiplatform

kotlin-multiplatform

SKILL.md

Kotlin Multiplatform

Shared Kotlin code across iOS, Android, and other platforms.

When to Use

  • Sharing business logic
  • iOS and Android codesharing
  • Multiplatform libraries
  • Native UI per platform

Quick Start

// shared/src/commonMain/kotlin/Greeting.kt
class Greeting {
    private val platform = getPlatform()

    fun greet(): String {
        return "Hello, ${platform.name}!"
    }
}

expect fun getPlatform(): Platform

interface Platform {
    val name: String
}

Core Concepts

Expected/Actual

// commonMain
expect class HttpClient() {
    suspend fun get(url: String): String
}

// androidMain
actual class HttpClient {
    actual suspend fun get(url: String): String {
        return OkHttpClient.newCall(Request.Builder().url(url).build())
            .await().body?.string() ?: ""
    }
}

// iosMain
actual class HttpClient {
    actual suspend fun get(url: String): String {
        return NSURLSession.sharedSession.dataTaskWithURL(NSURL(string = url)!!)
    }
}

Architecture

// Shared ViewModel
class UserViewModel(private val repository: UserRepository) {
    private val _user = MutableStateFlow<User?>(null)
    val user: StateFlow<User?> = _user.asStateFlow()

    fun loadUser(id: String) {
        coroutineScope.launch {
            _user.value = repository.getUser(id)
        }
    }
}

// Repository
class UserRepository(private val api: ApiClient, private val db: Database) {
    suspend fun getUser(id: String): User {
        return db.getUser(id) ?: api.fetchUser(id).also {
            db.saveUser(it)
        }
    }
}

Common Patterns

Platform-Specific UI

// Android (Compose)
@Composable
fun UserScreen(viewModel: UserViewModel) {
    val user by viewModel.user.collectAsState()
    user?.let { UserCard(it) }
}

// iOS (SwiftUI)
struct UserScreen: View {
    @ObservedObject var viewModel: UserViewModelWrapper

    var body: some View {
        if let user = viewModel.user {
            UserCard(user: user)
        }
    }
}

Build Configuration

// build.gradle.kts
kotlin {
    androidTarget()
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        commonMain.dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
            implementation("io.ktor:ktor-client-core:2.3.0")
        }
        androidMain.dependencies {
            implementation("io.ktor:ktor-client-okhttp:2.3.0")
        }
        iosMain.dependencies {
            implementation("io.ktor:ktor-client-darwin:2.3.0")
        }
    }
}

Best Practices

Do:

  • Share business logic, not UI
  • Use Ktor for networking
  • Use SQLDelight for database
  • Test in commonTest

Don't:

  • Force UI sharing
  • Ignore iOS memory model
  • Skip platform testing
  • Mix paradigms

Troubleshooting

Issue Cause Solution
iOS memory issue Freezing rules Check Kotlin/Native docs
Build error Version mismatch Align KMP versions
Type mismatch Expect/actual issue Check signature match

References

Weekly Installs
2
GitHub Stars
7
First Seen
Feb 10, 2026
Installed on
mcpjam2
claude-code2
replit2
junie2
windsurf2
zencoder2