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:
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:

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.