Desktop and Web

Compose Multiplatform for Desktop and Web

Compose Multiplatform 25,990 keeps Jetpack Compose 234 's API (@Composable, Column, remember, Material 3 15,533 ) and swaps the renderer: Android's own on Android, and Skia 351,502 , through JetBrains' Skiko 2,191 library, everywhere else. BookNest's :desktop module is Kotlin/JVM with the org.jetbrains.compose plugin 1.12.1 and compose.desktop.currentOs, depending on :shared. Its DesktopCatalog(books) composable, a Column of Material 3 Cards using formatPrice(), would compile unchanged on Android; only main is desktop code:

desktop/src/main/kotlin/.../Main.kt: a window, or a PNG when there is no displayKotlin
fun main(args: Array<String>) {
  val catalog = Catalog(File(args[0]).readText())         // context/tools/booknest-data.json
  if ("--png" in args) {                                   // no display: draw off screen
    val scene = ImageComposeScene(700, 1000, Density(1.5f)) { DesktopCatalog(catalog.books) }
    val png = scene.render().encodeToData(EncodedImageFormat.PNG)!!.bytes
    File("desktop-catalog.png").writeBytes(png)
    scene.close()
    println("wrote desktop-catalog.png, ${png.size} bytes")
  } else application {
    Window(onCloseRequest = ::exitApplication, title = "BookNest") {
      DesktopCatalog(catalog.books)
    }
  }
}

application { Window { } } opens a real window; this machine has no display, so --png draws the same composable with ImageComposeScene, Compose's off-screen renderer. ./gradlew :desktop:run --args="... --png" took 1m 20s and printed wrote desktop-catalog.png, 84360 bytes:

BookNest's catalog drawn by Compose Multiplatform on the desktop JVM, from the shared data layer
BookNest's catalog drawn by Compose Multiplatform on the desktop JVM, from the shared data layer

The colors are Material 3's defaults because BookNestTheme lives in the Android app. ./gradlew :desktop:packageDistributionForCurrentOS builds a .deb, .msi or .dmg with a bundled JVM.

On the web, Compose Multiplatform runs through Kotlin/Wasm (Beta): the wasmJs target compiles the same composables to WebAssembly and draws them on a <canvas>. Unlike Framework7 572,986 (Framework7) it produces no HTML elements, so find-in-page and SEO need extra work; it suits app-like pages rather than content sites.