Using Android Studio with the Kotlin Multiplatform Mobile plugin, I have created a KMM project, which provides support for Android and iOS.
However, I would also like to be able to use the same code base and UI to deploy to create a desktop app. Is that possible? And if yes, how?
Yes, it is possible. In fact, this tutorial details how to do it, albeit in a quite roundabout way that took me several days to complete:
https://www.kodeco.com/books/kotlin-multiplatform-by-tutorials/v1.0/chapters/1-introduction
Because of that, I have taken the liberty to creating a short summary for how you can create a basic project setup for a Desktop/Android/iOS app:
Install the Kotlin Multiplatform Mobile
and Compose Multiplatform IDE Support
plugins in Android Studio
Create a new Kotlin Multiplatform App
project (under Phone and Tablet
)
com.domain.project
In the shared/build.gradle.kts
, in the kotlin
block, after android()
, add:
jvm("desktop"){
compilations.all {
kotlinOptions.jvmTarget = "11"
}
}
Add a new desktop
folder at the top level of the app
Add a new file build.gradle.kts
into the desktop
folder, and fill it with this content:
import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose") version "1.2.2"
}
group = "com.domain.project"
version = "1.0.0"
kotlin {
jvm {
withJava()
compilations.all {
kotlinOptions.jvmTarget = "11"
}
}
sourceSets {
val jvmMain by getting {
kotlin.srcDirs("src/jvmMain/kotlin")
dependencies {
implementation(compose.desktop.currentOs)
api(compose.runtime)
api(compose.foundation)
api(compose.material)
api(compose.ui)
api(compose.materialIconsExtended)
implementation(project(":shared"))
}
}
}
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "MyProject"
macOS {
bundleID = "com.domain.project"
}
}
}
}
On the top level, in the settings.gradle.kts
add include(":desktop")
at the very end
Click on "sync now" (Or File > Sync project with gradle files
)
desktop
folder should now be recognized as a module, indicated by a little square at the bottom right of the folder iconIn the desktop
module, create the folder chain src/jvmMain/kotlin
In the just created kotlin
folder create the Kotlin file Main
, and fill it as follows:
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import androidx.compose.material.*
fun main() {
application {
val windowState = rememberWindowState()
Window(
onCloseRequest = ::exitApplication,
state = windowState,
title = "My Project"
) {
Surface(modifier = Modifier.fillMaxSize()) {
Text(text = "Welcome to my Project")
}
}
}
}
Add a run configuration of type Gradle
with the following settings:
Create the file shared/src/desktopMain/kotiln/com.domain.project/Platform.kt
, and fill it with this:
package com.domain.project
class DesktopPlatform : Platform {
override val name: String = "Desktop"
}
actual fun getPlatform(): Platform = DesktopPlatform()
You should now be able to run the desktop app
After that, you can then create shared Compose views that will work on both android and desktop. Chapter 5 of aforementioned tutorial covers that:
In addition, here's a bare-bones version of a project that I created using the above steps:
https://github.com/KiraResari/ceal-chronicler/releases/tag/basic-android-and-desktop-app