CMP-Unit-Converter

Introduction: A Compose Multiplatform unit converter
More: Author   ReportBugs   
Tags:

This repo contains a real-world example of a Compose Multiplatform app. CMP Unit Converter runs on Android, iOS, and the Desktop. As its name suggests, you can convert between various units and scales. While this may provide some value, the main goal of the app and the accompanying series on dev.to is to show how to use Compose Multiplatform and a couple of other multiplatform libraries while focusing on platform integration.

Among others, these libraries are used:

Unlike many other samples, this one has a strong focus on platform integration. For example, on the Desktop, you can access the settings, the About dialog, and all top-level destinations from the menu bar. On Android and iOS, a top app bar is used. The app supports dark and light mode on all platforms. Database and configuration files are stored in the preferred locations.

Noteworthy

This project follows the current default Kotlin Multiplatform project structure (also described in the recommended structure docs):

  • :shared — multiplatform library (shared UI + logic), using the Android KMP library plugin
  • :androidApp — Android application entry point (com.android.application, built-in Kotlin; no KMP plugin)
  • :desktopApp — desktop application entry point
  • iosApp/ — Xcode project consuming the Shared framework produced by :shared

Because UI is shared with Compose Multiplatform on every client, a single shared module is used (no sharedLogic / sharedUI split).

Toolchain versions live in gradle/libs.versions.toml and the Gradle wrapper. Current stack (high level): Gradle 9.7.1, AGP 9.3.2, Kotlin 2.4.10, Compose Multiplatform 1.12. Material3, Adaptive, and Navigation 3 are versioned separately from the CMP core artifacts, as documented in the CMP 1.12 release notes.

Apple Silicon is required for the iOS targets in this project: CMP 1.11+ dropped iosX64, so only iosArm64 and iosSimulatorArm64 are configured.

A note about icons

The official Android Compose documentation on Material icons recommends against adding material-icons-extended as a direct dependency (it is very large and can significantly increase build time) and instead suggests copying only the icons you need or using Google Font Icons (e.g. as SVG or Android vector drawable). This app follows that approach: the icons in use are stored as vector drawables in shared/src/commonMain/composeResources/drawable/ and referenced via AppIcons. Those icon assets are from the Material Design Icons project (Apache License 2.0).

Build and run on the command line

IntelliJ IDEA 2026.2 currently supports the Android Gradle Plugin up to 9.1.0, while this project uses AGP 9.3.2. Until the IDE catches up, build and run Android from the command line (or use Android Studio). Desktop and iOS Gradle/Xcode workflows are unaffected; ./gradlew in the IDE terminal works regardless of that AGP ceiling.

Android (build & install debug):

./gradlew :androidApp:installDebug

Desktop (run the app):

./gradlew :desktopApp:run

iOS (build & run on a simulator):

DEVICE_ID=$(xcrun simctl list devices available | sed -n 's/.*iPhone 16e (\([A-F0-9-]*\)).*/\1/p' | head -1)
xcrun simctl boot "$DEVICE_ID" 2>/dev/null || true
open -a Simulator
xcodebuild -project iosApp/iosApp.xcodeproj -scheme iosApp -configuration Debug \
  -destination "id=$DEVICE_ID" \
  -derivedDataPath /tmp/CMPUnitConverter-ios build
xcrun simctl install "$DEVICE_ID" "/tmp/CMPUnitConverter-ios/Build/Products/Debug-iphonesimulator/CMP Unit Converter.app"
xcrun simctl launch "$DEVICE_ID" de.thomaskuenneth.cmpunitconverter.CMPUnitConverter
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools
AI Daily Digest