11 KiB
KMP Material 3 Adaptive Compose — Evaluation
Date: 2026-03-10
This evaluation assesses the availability and readiness of Compose Material 3 Adaptive libraries for Kotlin Multiplatform, specifically for enabling shared list-detail layouts (nodes, messaging) across Android and Desktop.
Executive Summary
Material 3 Adaptive is available as a multiplatform library via JetBrains forks, with desktop and iOS targets. Version 1.3.0-alpha05 is built against the exact same CMP and Navigation 3 versions the project already uses. This unblocks moving ListDetailPaneScaffold-based screens into commonMain and wiring real adaptive layouts on desktop — no more placeholder screens for nodes and messaging.
Current State in the Project
What the project uses today
| API | File | Source Set | Maven Coordinates |
|---|---|---|---|
ListDetailPaneScaffold |
app/.../AdaptiveNodeListScreen.kt |
app (Android-only) |
androidx.compose.material3.adaptive:adaptive-layout:1.2.0 |
ListDetailPaneScaffold |
feature/messaging/.../AdaptiveContactsScreen.kt |
androidMain |
androidx.compose.material3.adaptive:adaptive-layout:1.2.0 |
NavigationSuiteScaffold |
app/.../Main.kt |
app (Android-only) |
androidx.compose.material3:material3-adaptive-navigation-suite (BOM) |
currentWindowAdaptiveInfo |
app/.../Main.kt |
app (Android-only) |
androidx.compose.material3.adaptive:adaptive:1.2.0 |
Imports used across the codebase
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldDefaults
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
Where the dependencies are declared
gradle/libs.versions.toml:androidxComposeMaterial3Adaptive = "1.2.0"→ AndroidX (Android-only)app/build.gradle.kts:androidMainonlyfeature/messaging/build.gradle.kts:androidMainonly
JetBrains Multiplatform Adaptive Artifacts
JetBrains publishes multiplatform forks of Material 3 Adaptive with full target coverage:
Artifact inventory
| JetBrains Artifact | AndroidX Equivalent | Desktop | iOS | Status |
|---|---|---|---|---|
org.jetbrains.compose.material3.adaptive:adaptive |
androidx.compose.material3.adaptive:adaptive |
✅ | ✅ | Published on Maven Central |
org.jetbrains.compose.material3.adaptive:adaptive-layout |
androidx.compose.material3.adaptive:adaptive-layout |
✅ | ✅ | Published on Maven Central |
org.jetbrains.compose.material3.adaptive:adaptive-navigation |
androidx.compose.material3.adaptive:adaptive-navigation |
✅ | ✅ | Published on Maven Central |
org.jetbrains.compose.material3.adaptive:adaptive-navigation3 |
(new, no AndroidX equivalent) | ✅ | ✅ | Published on Maven Central (1.3.0+ only) |
org.jetbrains.compose.material3:material3-adaptive-navigation-suite |
androidx.compose.material3:material3-adaptive-navigation-suite |
✅ | ✅ | Bundled with CMP material3 at composeMaterial3Version |
Package names are identical
The JetBrains forks use the same androidx.compose.material3.adaptive.* package names as AndroidX. No import changes are needed — only the Maven coordinates in build.gradle.kts change.
Version compatibility matrix
| JB Adaptive Version | CMP Version | Navigation 3 | Kotlin | Match? |
|---|---|---|---|---|
1.3.0-alpha05 |
1.11.0-alpha03 |
1.1.0-alpha03 |
2.2.20 |
✅ Exact match on CMP + Nav3 |
1.2.0 |
1.9.0 |
— | 2.1.21 |
❌ Too old for this project |
1.1.2 |
1.8.x |
— | — | ❌ Too old |
1.3.0-alpha05 is the correct version — it is built against foundation:1.11.0-alpha03 and navigation3-ui:1.1.0-alpha03, both of which are the exact versions the project uses today.
adaptive-navigation3 — new Navigation 3 integration
The adaptive-navigation3 artifact is a brand-new addition at 1.3.0. It provides Navigation 3-aware adaptive scaffolding. Its POM shows dependencies on:
navigation3-ui-desktop:1.1.0-alpha03✅navigationevent-compose-desktop:1.0.1
This could eventually enable deeper Nav3 + adaptive integration (e.g., ListDetailPaneScaffold directly managing Nav3 back stacks), but it's not required for the initial migration.
What This Enables
Immediate opportunity: shared ListDetailPaneScaffold
The ListDetailPaneScaffold and its navigator can move into commonMain code. This directly enables:
AdaptiveNodeListScreen— currently inapp(Android-only) — can be restructured so the scaffold pattern works cross-platformAdaptiveContactsScreen— currently infeature:messaging/androidMain— same opportunity- Desktop gets real list-detail layouts instead of placeholder text
Remaining Android-only blockers per file
Even with adaptive layouts available in commonMain, each file has additional Android-specific code that must be handled separately:
| File | Android-Only APIs Used | Migration Strategy |
|---|---|---|
AdaptiveNodeListScreen.kt |
BackHandler, LocalFocusManager |
BackHandler → expect/actual; LocalFocusManager is already in CMP |
AdaptiveContactsScreen.kt |
BackHandler (same pattern) |
Same as above |
NodeListScreen.kt |
ExperimentalMaterial3ExpressiveApi, animateFloatingActionButton, LocalContext, showToast |
Expressive APIs → standard M3; toast → platform callback |
NodeDetailScreen.kt |
android.Manifest, Intent, ActivityResultContracts, tooling.preview |
Heavy Android — keep in androidMain, create desktop variant |
Main.kt (app) |
currentWindowAdaptiveInfo, NavigationSuiteScaffold |
App-only, desktop already uses NavigationRail — no migration needed |
NavigationSuiteScaffold in desktop
The desktop already uses NavigationRail directly (in DesktopMainScreen.kt). The NavigationSuiteScaffold from the main material3 group is already available multiplatform via compose.material3AdaptiveNavigationSuite in the CMP DSL (composeMaterial3Version = "1.9.0"), but it's not needed — the desktop's NavigationRail is a deliberate design choice that works better for desktop form factors.
Risk Assessment
| Factor | Assessment |
|---|---|
| Library stability | Alpha, but same stability tier as CMP 1.11.0-alpha03 and Nav3 1.1.0-alpha03 already in use |
| API surface stability | ListDetailPaneScaffold API is stable in practice (widely adopted since AndroidX 1.0.0) |
| Build pipeline alignment | 1.3.0-alpha05 is produced by the same JetBrains compose-multiplatform build that produces CMP 1.11.0-alpha03 |
| Breaking change risk | Low — API surface matches AndroidX; only coordinates change |
| Dependency policy alignment | Follows project rule: "alpha only behind hard abstraction seams" (adaptive is behind feature module boundaries) |
Recommended Approach
Phase 1 — Add JetBrains adaptive dependencies ✅ DONE
Added to gradle/libs.versions.toml:
jetbrains-adaptive = "1.3.0-alpha05"
jetbrains-compose-material3-adaptive = { module = "org.jetbrains.compose.material3.adaptive:adaptive", version.ref = "jetbrains-adaptive" }
jetbrains-compose-material3-adaptive-layout = { module = "org.jetbrains.compose.material3.adaptive:adaptive-layout", version.ref = "jetbrains-adaptive" }
jetbrains-compose-material3-adaptive-navigation = { module = "org.jetbrains.compose.material3.adaptive:adaptive-navigation", version.ref = "jetbrains-adaptive" }
Added to desktop/build.gradle.kts:
implementation(libs.jetbrains.compose.material3.adaptive)
implementation(libs.jetbrains.compose.material3.adaptive.layout)
implementation(libs.jetbrains.compose.material3.adaptive.navigation)
Desktop compile verified: ./gradlew :desktop:compileKotlin — BUILD SUCCESSFUL.
Phase 2 — Desktop adaptive contacts screen ✅ DONE
- Moved
adaptive,adaptive-layout,adaptive-navigationdependencies fromandroidMain.dependencies→commonMain.dependenciesinfeature:messaging/build.gradle.kts(using JetBrains coordinates, replacing AndroidX adaptive) - Created
desktop/.../DesktopAdaptiveContactsScreen.ktusingListDetailPaneScaffoldwith:- List pane: shared
ContactItemcomposable withisActivehighlighting on selected contact - Detail pane: real
DesktopMessageContent— non-paged message list with send input using sharedMessageViewModel
- List pane: shared
- Wired into
DesktopMessagingNavigation.ktforContactsRoutes.ContactsGraphandContactsRoutes.Contacts - Verified:
./gradlew :desktop:compileKotlin :feature:messaging:compileKotlinJvm :app:compileFdroidDebugKotlin— BUILD SUCCESSFUL
Phase 3 — Desktop adaptive node list screen ✅ DONE
- Added JetBrains adaptive dependencies to
feature:node/build.gradle.ktscommonMain.dependencies - Created
desktop/.../DesktopAdaptiveNodeListScreen.ktusingListDetailPaneScaffoldwith:- List pane: shared
NodeItem,NodeFilterTextField,MainAppBarcomposables; context menu for favorite/ignore/mute/remove;isActivehighlighting - Detail pane: real
NodeDetailContentfrom commonMain — sharedNodeDetailListwith identity, device actions, position, hardware, notes, admin sections
- List pane: shared
- Wired into
DesktopNodeNavigation.ktforNodesRoutes.NodesGraphandNodesRoutes.Nodes - Metrics log screens (TracerouteLog, NeighborInfoLog, HostMetricsLog) wired as real screens with
MetricsViewModel(replacing placeholders) - Verified:
./gradlew :desktop:compileKotlin :feature:node:compileKotlinJvm :app:compileFdroidDebugKotlin— BUILD SUCCESSFUL
Phase 4 — Optional: evaluate adaptive-navigation3
The new adaptive-navigation3 artifact may offer cleaner Nav3 integration for list-detail patterns. Evaluate once the basic adaptive migration is stable.
Decision
Proceed with JetBrains adaptive 1.3.0-alpha05.
The version alignment is perfect, the risk profile matches what the project already accepts for CMP/Nav3/lifecycle, and the payoff is significant: shared list-detail layouts for nodes and messaging across Android and Desktop.
References
- Maven Central:
org.jetbrains.compose.material3.adaptive:adaptive - Maven Central:
adaptive-navigation3 - AndroidX source:
ListDetailPaneScaffold.ktincommonMain - Current project dependency:
androidxComposeMaterial3Adaptive = "1.2.0"ingradle/libs.versions.toml