Mobile Development 12 min read

Master Kotlin Compose Multiplatform: Build, Configure, and Package Desktop Apps

This article provides a comprehensive guide to using Kotlin, Jetpack Compose, and Multiplatform for desktop applications, covering project setup, shared code structure, platform-specific implementations, UI layout, resource handling, dependency configuration, and detailed packaging options for Windows, macOS, and Linux.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Master Kotlin Compose Multiplatform: Build, Configure, and Package Desktop Apps
ed5338b1-05cd-43b5-9ea1-b84617115e04.jpg
ed5338b1-05cd-43b5-9ea1-b84617115e04.jpg

1. Introduction

Kotlin + Compose + Multiplatform

cross‑platform solution is becoming mature by 2025. Google and JetBrains are deepening cooperation, unifying Jetpack Compose and Compose Multiplatform APIs, and Kotlin 2.1 will bring full‑platform backend optimizations.

Promising outlook – Google and JetBrains collaborate on API unification; enterprises such as McDonald’s and Netflix already reuse 80%+ business logic in production.

Multi‑platform coverage – Supports Android, iOS, desktop, Web and server code sharing via Compose Multiplatform; note some Jetpack libraries have compatibility limits. Compared with Flutter, KMP compiles to native binaries, preserving platform features.

Significant productivity boost – Declarative UI with Compose and coroutine‑based async reduces boilerplate; flexible sharing strategies allow sharing only business logic or extending to UI.

Performance equals native experience – Direct compilation to native code (iOS machine code, Android bytecode) avoids runtime overhead and enables native API calls such as SwiftUI/UIKit integration.

Complete desktop case study – The article walks through a full Kotlin + Compose + Multiplatform desktop project, covering new project creation, basic layout, custom title bar, skinning, ViewModel‑like usage, networking, file I/O, page navigation, file picker, music playback, video playback, KV storage and database usage.

2. Create New Project, Configure and Package

Use the Kotlin Multiplatform Wizard to generate a project template.

Project structure:

Project structure
Project structure
androidMain

– Android‑specific code. commonMain – Shared code for all platforms. iosMain – iOS‑specific code. jvmMain – Windows/macOS/Linux specific code. wasmJsMain – Web specific code.

Platform‑specific implementations use the expect/actual mechanism:

// Definition
interface Platform {
    val name: String
}
expect fun getPlatform(): Platform

// Usage
class Greeting {
    private val platform = getPlatform()
    fun greet(): String = "Hello, ${platform.name}!"
}

Android implementation:

class AndroidPlatform : Platform {
    override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()

JVM (desktop) implementation:

class JVMPlatform: Platform {
    override val name: String = "Java ${System.getProperty("java.version")}" 
}
actual fun getPlatform(): Platform = JVMPlatform()

Dependency configuration examples: androidMain.dependencies { … } – Android‑specific libraries. commonMain.dependencies { … } – Libraries shared by all platforms. jvmMain.dependencies { … } – Desktop‑specific libraries.

Desktop packaging configuration (Compose Desktop):

compose.desktop {
    application {
        mainClass = "com.wx.music.MainKt"
        nativeDistributions {
            targetFormats(TargetFormat.Exe)
            includeAllModules = true
            jvmArgs += listOf("-Dfile.encoding=UTF-8", "--add-opens=java.base/java.lang=ALL-UNNAMED")
            javaHome = "C:\\Users\\XXXX\\.jdks\\openjdk-21.0.1"
            packageName = "WX音乐"
            packageVersion = "1.0.0"
            windows {
                iconFile.set(project.file("src/desktopMain/composeResources/drawable/qwer.ico"))
                shortcut = true
                menu = true
            }
        }
        buildTypes.release.proguard { isEnabled = false }
    }
}
Packaging configuration
Packaging configuration

Key packaging options: mainClass – Entry point for the desktop app. targetFormats – Choose .exe (Windows), .dmg (macOS) or .deb (Linux). includeAllModules = true – Bundle all dependencies. jvmArgs – Set UTF‑8 encoding and open java.lang for reflection. javaHome – Embed a specific JDK. iconFile – Set the .ico icon for Windows. shortcut and menu – Create desktop shortcuts and menu entries.

ProGuard can be disabled for release builds.

Packaging tasks such as package, packageDeb, packageDistributionForCurrentOS, packageDmg and packageExe generate installers for the respective operating systems.

Packaging result
Packaging result

3. Basic Layout, Text, Icons and Images

The UI code for Android Jetpack Compose works identically on desktop. Resources are placed under drawable (SVG XML) and images (png, jpg, webp). Example of using a local SVG icon:

Icon(
    modifier = Modifier
        .padding(0.dp, 0.dp, 80.dp, 0.dp)
        .clickable { minRequest.invoke() }
        .size(40.dp)
        .padding(0.dp, 0.dp, 0.dp, 15.dp)
        .align(Alignment.TopEnd),
    painter = painterResource("drawable/baseline_minimize_24.xml"),
    contentDescription = "Close",
    tint = MaterialTheme.colorScheme.onPrimary
)

Network images are loaded with Coil, which supports Android, iOS, JVM, JavaScript and WASM:

implementation("io.coil-kt.coil3:coil-compose:3.0.3")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.3")
AsyncImage(
    model = item.pic,
    contentDescription = "Network Image",
    modifier = Modifier.fillMaxSize().clip(RoundedCornerShape(10)),
    contentScale = ContentScale.Crop
)
Music player demo
Music player demo

4. Summary

The article presented a complete Kotlin + Compose + Multiplatform desktop case, including project creation, configuration, packaging, basic UI layout, resource handling, and outlined future topics such as custom title bars, skinning, ViewModel‑like patterns, networking, file I/O, navigation, file picker, music and video playback, KV storage and database usage.

Generated files
Generated files
Cross-PlatformKotlinDesktop DevelopmentPackagingCompose Multiplatform
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.