'Kotlin Multiplatform Compose + Desktop + Web + Mobile
Is it possible at the moment to have a kotlin multiplatform project using compose for sharing the ui code for desktop, web, and mobile at the same time? All the examples i found only cover multiplatform with JS Front + Jvm Backend, or JVM Android + Desktop + Common Module, and I'm having trouble setting a project with all those at the same time.
I tried doing:
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose") version "1.0.1-rc2"
id("com.android.library")
}
kotlin {
android()
jvm("desktop") {
...
}
js{
...
}
sourceSets {
val commonMain by getting {
dependencies {
...
}
}
val commonTest by getting {
dependencies {
...
}
}
val androidMain by getting {
dependencies {
...
}
}
val androidTest by getting {
dependencies {
...
}
}
val desktopMain by getting {
dependencies {
...
}
}
val desktopTest by getting
val jsMain by getting{
dependencies{
...
}
}
val jsTest by getting {
dependencies {
...
}
}
}
}
But it produces the error:
:common:jsMain: Could not resolve org.jetbrains.compose.runtime:runtime:1.0.1-rc2.
Required by:
project :common
If i comment the JS related sections it works, or if i comment all the non-js related stuff it also works
Commenting everything compose-related also works
The problem is only when combining everything
Solution 1:[1]
The short answer is: No, this is not possible at this time.
I have not been able to reproduce your error, but I assume that you have not removed compose.foundation
and compose.material
from the common dependencies.
At the moment, only compose.runtime
is available for the common module, and this makes it almost impossible to do any layout at this point: even Button
and Text
are not available.
As you can see in the JS application example, Text
is not imported from androidx.compose.material.Text
, but from org.jetbrains.compose.web.dom.Text
, which is a completely different element, so it cannot be used in a common module.
I heard on some podcast that JetBrains has plans to make it fully multiplatform for JS, but at this point, I would say that Compose JS is another framework that allows you to write UI in code similar to Compose.
Solution 2:[2]
**
This answer is not an exact answer to this question. The correct answer for this is the answer by @PhilipDukhov. However, this might help others who land on this page for finding a solution to the other problem I am just leaving it here. For more info read comments between me and @PhilipDukhov for this answer.
**
Yes, it is possible to have all three modules in a single project. TLDR
I did some workarounds and managed to get all things in a single project i.e
- Compose for Desktop
- Compose for Android
- Compose for Web
Suggestion Before You Go Further
Although below code snippets works and by going through you will be able to achieve what you want actually. I personally recommend you to just go to the Github repository here . I think it will save time if you are creating a new project. However if you are adding web module to current KMM project continue reading.
The problem can be fixed by keeping the correct dependencies
So the project structure should be something like this
Note: If you are creating a new KMM project you will have only common, desktop, and android modules.(As you already know)
Step 1: You need to add the a folder to root (where the android, common,desktop folder is located) call it as web(should not matter)
Step 2: Add several folders to this newly created directory web your web directory should look something like this
Note : Dont add build (its autogenerated) add only
src/jsMain
-kotlin
-resources
src/jsTest
-kotlin
-resources
and create a file called build.gradle.kts
Step 3: Change the content of this newly added Gradle file to something like this
import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose") version "1.0.0"
}
group = "com.example"
version = "1.0"
kotlin {
js(IR) {
browser {
testTask {
testLogging.showStandardStreams = true
useKarma {
useChromeHeadless()
useFirefox()
}
}
}
binaries.executable()
}
sourceSets {
val jsMain by getting {
dependencies {
implementation(compose.web.core)
implementation(compose.runtime)
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
}
}
Step 4: And Add Main.kt to jsMain/kotlin
with following content
renderComposable(rootElementId = "root") {
Div(
attrs = {
// specify attributes here
style {
// specify inline style here
}
}
) {
Text("A text in <div>")
}
}
Step 4 : Add index.html to jsMain/resources with content
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MultiplatformTest Sample</title>
</head>
<body>
<div id="root"></div>
<script src="web.js"></script>
</body>
</html>
Note: web.js file mentioned in the above snippet is sensitive and the project generated you need to make sure it is web.js only or else the folder_name.js which you created in step 1
Step 5: Finally add web module to settings.gradle.kts file
pluginManagement {
repositories {
google()
jcenter()
gradlePluginPortal()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
}
rootProject.name = "MultiplatformTest"
include(":android")
include(":desktop")
include(":common")
include(":web") // Note web module is included here
I have created a repo check this repo and you can use it as a template for your projects
Link to the repo: https://github.com/PSPanishetti/ComposeMultiplatform
If you get any doubts feel free to ask them.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | AgentP |
Solution 2 |