GitPedia

D KMP sample

D-KMP Architecture official sample: it uses a shared KMP ViewModel and Navigation for Compose and SwiftUI apps.

From dbaroncelli·Updated June 3, 2026·View on GitHub·

This is the official sample of the **D-KMP architecture**, where "**D**" stands for _Declarative UI_ and "**KMP**" stands for _Kotlin MultiPlatform_. It presents a simple master/detail app, for **Android**, **iOS** and **Desktop**. The business logic is fully shared (and written in Kotlin). The UI is platform-specific: _Compose_ for **Android** and **Desktop**, _SwiftUI_ for **iOS**. The project is written primarily in Kotlin, distributed under the Apache License 2.0 license, first published in 2021. Key topics include: android, compose-desktop, d-kmp, declarative-ui, ios.

D-KMP architecture - official sample

This is the official sample of the D-KMP architecture, where "D" stands for Declarative UI and "KMP" stands for Kotlin MultiPlatform. It presents a simple master/detail app, for Android, iOS and Desktop.<br>
The business logic is fully shared (and written in Kotlin). The UI is platform-specific: Compose for Android and Desktop, SwiftUI for iOS.<br>
<br>
UPDATE MAY 2025:<br>
This repository about the D-KMP architecture will be kept online, but it won't be updated anymore.<br>
The D-KMP architecture was conceived in 2020, when nobody expected that Compose would have become a first-class UI toolkit also for iOS. Now Compose MultiPlatform is stable and production-ready for Android, iOS and Desktop, so sharing both the business logic and the UI using Compose MultiPlatform (CMP) has become the preferred KMP solution.<br>
All information about writing apps with Compose MultiPlatform can be found on the official CMP website by JetBrains.
<br>
<br>
UPDATE NOVEMBER 2025:<br>
Navigation3 is now finally available also to CMP, providing the very much awaited CMP-optimized navigation library!<br>
Google is now also mentioning Compose Multiplatform on the KMP section of the Android website, listing all the Jetpack libraries available for KMP/CMP. The path cannot be clearer. It doesn't make anymore sense to duplicate the UI for each platform. Compose has all that's needed for a robust and maintanable multiplatform app. By the end of 2026, Compose is also expected to become production ready for Web/Wasm.

<img width="500" src="https://user-images.githubusercontent.com/5320104/219511497-0c494b86-2716-420d-bbc7-fe50c552667a.png"></img>

Key features of the D-KMP architecture:

  • it uses the latest declarative UI toolkits: Compose for Android and SwiftUI for iOS
  • it fully shares the ViewModel (including navigation logic and data layer) via Kotlin MultiPlatform
  • coroutine scopes are cancelled/reinitialized automatically, based on the current active screens and the app lifecycle (using LifecycleObserver on Android and the SwiftUI lifecycle on iOS)
  • it implements the MVI pattern and the unidirectional data flow
  • it implements the CQRS pattern, by providing Command functions (via Events and Navigation) and Query functions (via StateProviders)
  • it uses Kotlin's StateFlow to trigger UI layer recompositions
  • the navigation state is processed in the shared code, and then exposed to the UI layer:
    • on SwiftUI it seamlessly integrates with the new iOS 16 navigation patterns (NavigationStack and/or NavigationSplitView)
    • on Compose it's a "remembered" data class which works on any platform (unlike Jetpack Navigation, which only works on Android)

you can find more info on these articles:

Data sources used by this sample:

Instructions to write your own D-KMP app:

If you want to create your own app using the D-KMP Architecture, here are the instructions you need:
<br>

SHARED CODE:

View Model

<img width="272" src="https://user-images.githubusercontent.com/5320104/118641163-194a8600-b7da-11eb-9bdd-b59e34392d36.png"></img>

  • :hammer_and_wrench: in the viewmodel/screens folder: create a folder for each screen of the app, containing these 3 files (as shown in the sample app structure above):
    • screenEvents.kt, where the event functions for that screen are defined
    • screenInit.kt, where the initialization settings for that screen are defined
    • screenState.kt, where the data class of the state for that screen is defined
  • :hammer_and_wrench: in the NavigationSettings.kt file in the screens folder, you should define your level 1 navigation and other settings
  • :hammer_and_wrench: in the ScreenEnum.kt file in the screens folder, you should define the enum with all screens in your app
  • :white_check_mark: the ScreenInitSettings.kt file in the screens folder doesn't need to be modified
  • :white_check_mark: the 6 files in the viewmodel folder (DKMPViewModel.kt, Events.kt, Navigation.kt, ScreenIdentifier.kt, StateManager.kt, StateProviders.kt) don't need to be modified
  • :white_check_mark: also DKMPViewModelForAndroid.kt in androidMain and DKMPViewModelForIos.kt in iosMain don't need to be modified

Data Layer

<img width="322" src="https://user-images.githubusercontent.com/5320104/114903196-d7af6f80-9e16-11eb-823c-8ef9e2039ab6.png"></img>

  • :hammer_and_wrench: in the datalayer/functions folder: create a file for each repository function to be called by the ViewModel's StateReducers
  • :hammer_and_wrench: in the datalayer/objects folder: create a file for each data class used by the repository functions
  • :hammer_and_wrench: in the datalayer/sources folder: create a folder for each datasource, where the datasource-specific functions (called by the repository functions) are defined
  • :white_check_mark: the datalayer/Repository.kt file should be modified only in case you want to add an extra datasource

<br><br>

PLATFORM-SPECIFIC CODE:

Android

<img width="352" alt="Schermata 2021-06-26 alle 16 54 32" src="https://user-images.githubusercontent.com/5320104/123515260-f0e65f00-d696-11eb-9ba5-9d44faa58563.png"></img>

<img width="390" alt="Schermata 2021-06-26 alle 17 03 13" src="https://user-images.githubusercontent.com/5320104/123515523-0d36cb80-d698-11eb-9be9-257e1603174d.png"></img>

  • :white_check_mark: the App.kt file doesn't need to be modified
  • :white_check_mark: the MainActivity.kt file doesn't need to be modified
  • The composables are used by both Android and Desktop apps:
    • :hammer_and_wrench: the Level1BottomBar.kt and Level1NavigationRail.kt files in the navigation/bars folder should be modified to custom the Navigation bars items
    • :white_check_mark: the TopBar.kt file in the navigation/bars folder doesn't need to be modified
    • :white_check_mark: the OnePane.kt and TwoPane.kt files in the navigation/templates folder don't need to be modified
    • :white_check_mark: the HandleBackButton.kt file in the navigation folder doesn't need to be modified
    • :white_check_mark: the Router.kt file in the navigation folder doesn't need to be modified
    • :hammer_and_wrench: in the ScreenPicker.kt file in the navigation folder, you should define the screen composables in your app
    • :hammer_and_wrench: in the screens folder: create a folder for each screen of the app, containing all composables for that screen
    • :white_check_mark: the MainComposable.kt file doesn't need to be modified <br>

iOS

<img width="307" alt="ios-files" src="https://user-images.githubusercontent.com/5320104/219498843-a2db7d84-6bd8-40f9-a730-79732d320d8a.png"></img>

  • :hammer_and_wrench: the Level1BottomBar.swift and Level1NavigationRail.swift files in the composables/navigation/bars folder should be modified to custom the Navigation bars items
  • :white_check_mark: the TopBar.swift file in the composables/navigation/bars folder doesn't need to be modified
  • :white_check_mark: the OnePane.swift and TwoPane.swift files in the composables/navigation/templates folder don't need to be modified
  • :white_check_mark: the Router.swift file in the composables/navigation folder doesn't need to be modified
  • :hammer_and_wrench: in the ScreenPicker.swift file in the views/navigation folder, you should define the screen composables in your app
  • :hammer_and_wrench: in the views/screens folder: create a folder for each screen of the app, containing all SwiftUI views for that screen
  • :white_check_mark: the App.swift file doesn't need to be modified
  • :white_check_mark: the AppObservableObject.swift file doesn't need to be modified <br>

Desktop

<img width="298" alt="Schermata 2021-06-26 alle 16 54 15" src="https://user-images.githubusercontent.com/5320104/123515803-3efc6200-d699-11eb-9703-4ca4850c89d9.png"></img>

<img width="390" alt="Schermata 2021-06-26 alle 17 03 13" src="https://user-images.githubusercontent.com/5320104/123515523-0d36cb80-d698-11eb-9be9-257e1603174d.png"></img>

  • :white_check_mark: the main.kt file doesn't need to be modified
  • The composables are used by both Android and Desktop apps:

Contributors

Showing top 1 contributor by commit count.

View all contributors on GitHub →

This article is auto-generated from dbaroncelli/D-KMP-sample via the GitHub API.Last fetched: 6/15/2026