Files
Meshtastic-Android/desktop

:desktop — Meshtastic Desktop

A Compose Desktop application target — the first full non-Android target for the shared KMP module graph. This module serves as:

  1. First multi-target milestone — Proves the KMP architecture supports real application targets beyond Android.
  2. Build smoke-test — Validates that all core:* KMP modules compile and link on a JVM Desktop target.
  3. Shared navigation proof — Uses the same Navigation 3 routes from core:navigation and the same NavDisplay + entryProvider pattern as the Android app, proving the shared backstack architecture works cross-target.
  4. Desktop app scaffold — A working Compose Desktop application with a NavigationRail for top-level destinations and placeholder screens for each feature.

Quick Start

# Run the desktop app
./gradlew :desktop:run

# Run tests
./gradlew :desktop:test

# Package native distribution (DMG/MSI/DEB)
./gradlew :desktop:packageDistributionForCurrentOS

Architecture

The module depends on the JVM variants of KMP modules:

  • core:common, core:model, core:di, core:navigation, core:repository
  • core:domain, core:data, core:database, core:datastore, core:prefs
  • core:network, core:resources, core:ui

Navigation: Uses JetBrains multiplatform forks of Navigation 3 (org.jetbrains.androidx.navigation3:navigation3-ui) and Lifecycle (org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose, lifecycle-runtime-compose). A SavedStateConfiguration with polymorphic SerializersModule is configured for non-Android NavKey serialization. Desktop shares route keys with Android via core:navigation, but graph wiring remains platform-specific; parity policy is tracked in docs/decisions/navigation3-parity-2026-03.md.

Coroutines: Requires kotlinx-coroutines-swing for Dispatchers.Main on JVM/Desktop. Without it, any code using lifecycle.coroutineScope or Dispatchers.Main (e.g., NodeRepositoryImpl, RadioConfigRepositoryImpl) will crash at runtime.

DI: A Koin DI graph is bootstrapped in Main.kt with stub implementations for Android-only services.

UI: JetBrains Compose for Desktop with Material 3 theming, sharing Compose components from core:ui.

Localization: Desktop exposes a language picker in ui/settings/DesktopSettingsScreen.kt, persisting the selected BCP-47 tag in UiPreferencesDataSource.locale. Main.kt applies the override to the JVM default Locale and uses a staticCompositionLocalOf-backed recomposition trigger so Compose Multiplatform stringResource() calls update immediately without recreating the Navigation 3 backstack.

Key Files

File Purpose
Main.kt App entry point — Koin bootstrap, Compose Desktop window, theme + locale application
DemoScenario.kt Offline demo data for testing without a connected device
ui/DesktopMainScreen.kt Navigation 3 shell — NavigationRail + NavDisplay + SavedStateConfiguration
navigation/DesktopNavigation.kt Nav graph entry registrations for all top-level destinations
navigation/DesktopSettingsNavigation.kt Real settings feature composables wired into nav graph (~35 screens)
navigation/DesktopNodeNavigation.kt Real adaptive node list-detail + real metrics screens (logs + charts); map routes remain placeholders
navigation/DesktopMessagingNavigation.kt Real adaptive contacts list-detail + real Messages/Share/QuickChat route screens
radio/DesktopRadioInterfaceService.kt TCP socket transport with auto-reconnect, heartbeat, and backoff retry
radio/DesktopMeshServiceController.kt Mesh service lifecycle — orchestrates want_config handshake chain
radio/DesktopMessageQueue.kt Message queue for outbound mesh packets
ui/firmware/DesktopFirmwareScreen.kt Placeholder firmware screen (native DFU is Android-only)
ui/settings/DesktopSettingsScreen.kt Desktop-specific top-level settings screen, including theme/language/app-info controls
ui/settings/DesktopDeviceConfigScreen.kt Device config with JVM ZoneId timezone (replaces Android BroadcastReceiver)
ui/settings/DesktopPositionConfigScreen.kt Position config without Android Location APIs
ui/settings/DesktopNetworkConfigScreen.kt Network config without QR/NFC scanning
ui/settings/DesktopSecurityConfigScreen.kt Security config with JVM SecureRandom (omits file export)
ui/settings/DesktopExternalNotificationConfigScreen.kt External notification config without MediaPlayer/file import
ui/settings/DesktopDebugScreen.kt Desktop-specific debug info screen
ui/nodes/DesktopAdaptiveNodeListScreen.kt Adaptive node list-detail using JetBrains ListDetailPaneScaffold
ui/messaging/DesktopAdaptiveContactsScreen.kt Adaptive contacts list-detail using JetBrains ListDetailPaneScaffold
ui/messaging/DesktopMessageContent.kt Desktop message content with send, reactions, and selection
di/DesktopKoinModule.kt Koin module with stub implementations
di/DesktopPlatformModule.kt Platform-specific Koin bindings
stub/NoopStubs.kt No-op implementations for all repository interfaces

What This Validates

Module What's Tested
core:common Base64Factory, NumberFormatter, UrlUtils, DateFormatter, CommonUri
core:model DeviceVersion, Capabilities, SfppHasher, platformRandomBytes, getShortDateTime, Channel.getRandomKey
core:ui Shared Compose components compile and render on Desktop
Build graph All core modules compile and link without Android SDK

Roadmap

  • Implement real navigation with shared core:navigation routes (Navigation 3 shell)
  • Adopt JetBrains multiplatform forks for lifecycle and navigation3
  • Wire feature:settings composables into the nav graph (first real feature — ~30 screens)
  • Wire feature:node composables into the nav graph (node list with shared ViewModel + NodeItem)
  • Wire feature:messaging composables into the nav graph (contacts list with shared ViewModel)
  • Add JetBrains Material 3 Adaptive ListDetailPaneScaffold to node and messaging screens
  • Implement TCP transport (DesktopRadioInterfaceService) with auto-reconnect and backoff retry
  • Implement mesh service controller (DesktopMeshServiceController) with full want_config handshake
  • Create connections screen using shared feature:connections with dynamic transport detection
  • Replace 5 placeholder config screens with real desktop implementations (Device, Position, Network, Security, ExtNotification)
  • Add desktop language picker backed by shared UiPreferencesDataSource.locale with live translation updates
  • Wire remaining feature:* composables (map) into the nav graph
  • Move remaining node detail and message composables from androidMain to commonMain
  • Add serial/USB transport for direct radio connection on Desktop
  • Add MQTT transport for cloud-connected operation
  • Package as native distributions (DMG, MSI, DEB) via CI release pipeline