MULTIPLATFORM.md
April 23, 2026 ยท View on GitHub
General requirements
- Java 21 (should be specified in JAVA_HOME and in the IDE)
- Android SDK downloaded from Android Studio and specified in
ANDROID_SDK_ROOT - (on Windows) Git "symlinks" is enabled. Call
git config --global core.symlinks trueto set it globally.core.symlinksrequires running git commands with admin priviligies, or with Developer mode enabled
Developing in IDE
- Download Android Studio from the official site (it is mandatory to use the version, written here). As an alternative you can use IDEA, which is compatible with this AGP version, or you can disable Android plugin in IDEA plugins, to develop non-Android targets.
- Download Android SDK via Android Studio and specify it in
ANDROID_SDK_ROOTenvironment variable. - Specify Gradle JVM to use JDK 17 in InteliJ IDEA Preferences (
Build, Execution, Deployment -> Build Tools -> Gradle)
Run tests
Run tests for Desktop:
./gradlew desktopTest
Run tests for Web:
./gradlew :mpp:testWeb
Run tests for iOS:
./gradlew :mpp:testIos'
Run iOS instrumented tests. Note: To ensure the test runs on an iOS simulator with a detached hardware keyboard, we must shut down all simulators and update the ConnectHardwareKeyboard flag.
xcrun simctl shutdown all
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool false
cd compose/ui/ui/src/uikitInstrumentedTest/launcher
xcodebuild test -scheme Launcher -project Launcher.xcodeproj -destination 'platform=iOS Simulator,name=iPhone 16'
API checks
Compose Multiplatform stores all public API in *.api files. If any API is added/changed, ./gradlew jbApiCheck will fail with an error that API is changed (it runs on CI). Example:
Execution failed for task ':compose:material3:material3:desktopApiCheck'.
> API check failed for project material3.
--- D:\Work\compose-multiplatform-core\compose\material3\material3\api\desktop\material3.api
+++ D:\Work\compose-multiplatform-core\out\androidx\compose\material3\material3\build\api\desktop\material3.api
@@ -552,6 +552,11 @@
public abstract interface annotation class androidx/compose/material3/ExperimentalMaterial3Api : java/lang/annotation/Annotation {
}
+public final class androidx/compose/material3/FF {
+ public static final field $stable I
+ public fun <init> ()V
+}
+
public final class androidx/compose/material3/FabPosition {
public static final field Companion Landroidx/compose/material3/FabPosition$Companion;
public static final synthetic fun box-impl (I)Landroidx/compose/material3/FabPosition;
You can run :material3:apiDump task to overwrite API declarations
To fix this error:
- Run
./gradlew jbApiDumpor (for Linux/Window host) CI task that creates a commit "Dump API" in a branch - See what has changed in *.api files.
- If there are only additions - there is no binary incompatible change.
- If there are some removals - most probably there is a binary incompatible change and it needs to be fixed before merging it to the main branch.
Publishing
Compose Multiplatform core libraries can be published to local Maven with the following steps:
-
Use these gradle properties to set the published libraries versions
-Pjetbrains.publication.version.CORE_BUNDLE,-Pjetbrains.publication.version.CORE_URI,-Pjetbrains.publication.version.COMPOSE,-Pjetbrains.publication.version.COMPOSE_MATERIAL3_ADAPTIVE,-Pjetbrains.publication.version.LIFECYCLE,-Pjetbrains.publication.version.NAVIGATION,-Pjetbrains.publication.version.NAVIGATION_3,-Pjetbrains.publication.version.NAVIGATION_EVENT,-Pjetbrains.publication.version.SAVEDSTATE,-Pjetbrains.publication.version.WINDOW,The default value for the version is
0.0.0-SNAPSHOTAnd library groups:
-Pjetbrains.publication.libraries=COMPOSE,COMPOSE_MATERIAL3_ADAPTIVE,LIFECYCLE,NAVIGATION,NAVIGATION_3,NAVIGATION_EVENT,SAVEDSTATE,WINDOWThe default value includes all libraries.
-
Publish core libraries
./gradlew :mpp:publishComposeJbToMavenLocal -Pcompose.platforms=all -Pjetbrains.publication.version.COMPOSE=9999.0.0-alpha01 -Pjetbrains.publication.version.LIFECYCLE=9999.0.0-alpha01-Pcompose.platforms=allcould be replace with comma-separated list of platforms, such asjs,jvm,androidDebug,androidRelease,macosx64,ios. -
Publish extended icons
./gradlew :mpp:publishComposeJbExtendedIconsToMavenLocal -Pcompose.platforms=all --max-workers=1 -
(Optional) Publish Gradle plugin using instructions to check changes locally.
Run samples
Run jvm desktop samples:
./gradlew :compose:mpp:demo:runDesktop
./gradlew :compose:desktop:desktop:desktop-samples:run1
./gradlew :compose:desktop:desktop:desktop-samples:run2
./gradlew :compose:desktop:desktop:desktop-samples:run3
./gradlew :compose:desktop:desktop:desktop-samples:runSwing
./gradlew :compose:desktop:desktop:desktop-samples:runWindowApi
./gradlew :compose:desktop:desktop:desktop-samples:runVsync
./gradlew :compose:desktop:desktop:desktop-samples:runLayout
./gradlew :compose:desktop:desktop:desktop-samples-material3:runScaffold
Run wasm sample:
./gradlew :compose:mpp:demo:jsRun
Run native macos X64 sample:
./gradlew :compose:mpp:demo:runDebugExecutableMacosX64
Run native macos Arm64 sample:
./gradlew :compose:mpp:demo:runDebugExecutableMacosArm64
Run in KMP Wizard project
To use a locally built compose in KMP with Compose wizard project you need to perform some extra steps:
- Checkout https://github.com/JetBrains/compose-multiplatform.
- Open
gradle-pluginsincompose-multiplatform. - Update
gradle.propertiesby settingcompose.versionanddeploy.versionto the version you've published (9999.0.0-alpha01in example above). - Run
./gradlew publishToMavenLocal. - Open
componentsincompose-multiplatform. - Update
gradle.propertiesby settingcompose.useMavenLocaltotrueandcompose.versionto the version you've published. - Run
./gradlew publishToMavenLocal. - Open KMP wizard project.
- Update
settings.gradle.ktsby addingmavenLocal()to the end of bothrepositoriesblocks. - Update
gradle/libs.versions.tomlby settingcompose-pluginto the version you've published. - Sync gradle.
Now the project will build with the locally published Compose.
Run mpp/demo-swiftui sample on iOS with Xcode
Open the iosApp.xcodeproj with XCode and press the Run button.
Run mpp/demo sample on iOS with Xcode
Run script:
./compose/mpp/demo/regenerate_xcode_project.sh
Wait while Xcode is opening, and press run button.
Clean IDE and Gradle cache
-
Close project
-
./cleanTempFiles.sh