Skip to content

bitsycore/compose-desktop-native-bridge-example

Repository files navigation

Bubble Wrap 🫧

A tiny, deliberately silly Material 3 bubble-wrap simulator — and a complete consumer example for compose-desktop-native's bridge plugin: one shared Compose Multiplatform codebase that runs

  • on Android (Google's androidx.compose artifacts),
  • on upstream Compose Desktop (JVM), and
  • as self-contained native executables — Windows (mingwX64), Linux (x64 / arm64) and macOS (arm64) — no JVM, rendering through SDL3/Skia.

Pop bubbles, resize them with a slider, flip dark/light, get a fresh sheet. Bouncy spring physics included. The bubble logo and the strings come from composeResources/ — same files, same generated Res.* accessors on every platform; on the native targets the bridge bundles them into data.kres next to the executable automatically.

Layout

Two modules, the current Android-recommended shape for a KMP app:

  • :shared — the whole app as a Compose Multiplatform library. The Android target comes from AGP's KMP library plugin (com.android.kotlin.multiplatform.library), declared as androidLibrary {} right inside the kotlin {} block — no android {} block, no manifest. The jvm/native desktop entry points and the bridge plugin live here too.
  • :androidApp — a plain com.android.application module: one Activity, one manifest, implementation(project(":shared")).

The point

shared/src/commonMain contains only plain Compose code against the official androidx.compose.* API, and shared/build.gradle.kts declares only the official org.jetbrains.compose.* coordinates. One line in settings.gradle.kts does the rest:

plugins { id("com.bitsycore.compose-desktop-native.bridge") version "0.1.17" }

On the Kotlin/Native desktop targets the plugin substitutes compose-desktop-native's klibs for those coordinates; every other target keeps resolving upstream — on Android, JetBrains' own artifacts already redirect to Google's androidx.compose.*, the exact same trick one layer up. SDL3 and its codecs ship as static archives inside the klibs — nothing to install, and a distributable is just the executable.

Setup

The artifacts live on GitHub Packages, which requires authentication even for public downloads. Put a classic PAT with read:packages in ~/.gradle/gradle.properties:

gpr.user=<your-github-username>
gpr.token=<your-pat>

Run

# Native — self-contained executable, no JVM
./gradlew :shared:runDebugExecutableMingwX64      # Windows
./gradlew :shared:runDebugExecutableLinuxX64      # Linux
./gradlew :shared:runDebugExecutableMacosArm64    # macOS (Apple Silicon)

# Upstream Compose Desktop (JVM) — the same App()
./gradlew :shared:run

# Android — the same App() on androidx.compose
./gradlew :androidApp:installDebug        # or open in Android Studio

Linux needs the usual GL/X11/fontconfig dev basics at link time (libfontconfig-dev libgl1-mesa-dev libx11-dev).

Developing against a local build of the port

Publish snapshots from a compose-desktop-native checkout (publishMingwX64PublicationToMavenLocal publishKotlinMultiplatformPublicationToMavenLocal :compose-desktop-native-bridge:publishToMavenLocal), then:

./gradlew :shared:runDebugExecutableMingwX64 \
  -PbridgeVersion=0.0.0-SNAPSHOT \
  -PcomposeDesktopNativeVersion=0.0.0-SNAPSHOT

License

MIT

About

Bubble Wrap — all-platform Material 3 example for the compose-desktop-native bridge plugin: official CMP coordinates, native desktop executables without a JVM

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages