Kmp architecture
Skill ShinKev/kmp-skill-library/architecture/kmp-architecture
Expert guidance on setting up and maintaining a modern Kotlin Multiplatform (KMP) + Compose Multiplatform (CMP) application architecture. Use when asked about project structure, KMP module setup, Koin DI, or cross-platform clean architecture.From its SKILL.md
npx -y skills add ShinKev/kmp-skill-library --skill kmp-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.9 KB, 868 tokens by cl100k_base, as published. Nobody here has run it
KMP + CMP Modern Architecture
Instructions
Structure the application with KMP-first Clean Architecture. All layers except platform adapters live in commonMain.
1. High-Level Layers
Dependencies flow strictly inward to the core logic.
-
UI Layer (
commonMain+ platform overrides):- Composables, ViewModels.
ViewModellives incommonMainviaorg.jetbrains.androidx.lifecycle:lifecycle-viewmodel.- Never depends on Data Layer implementation details directly.
-
Domain Layer (
commonMain, no platform imports):- Use Cases (e.g.,
GetLatestNewsUseCase), Domain Models (pure Kotlin data classes). - Zero platform imports — no
android.*, noplatform.*, nokotlinx.coroutines.android. - Depends only on Repository interfaces.
- Use Cases (e.g.,
-
Data Layer (
commonMain+ platform drivers):- Repository implementations, Ktor client calls, SQLDelight queries, MultiplatformSettings.
- Platform-specific drivers (SQLite, HTTP engine) injected via Koin platform modules.
2. Dependency Injection with Koin
Use Koin for all DI. No Hilt in shared code.
// commonMain — shared modules
val repositoryModule = module {
single<NewsRepository> { OfflineFirstNewsRepository(get(), get()) }
}
val viewModelModule = module {
viewModel { NewsViewModel(get()) }
}
// androidMain — platform module
val androidPlatformModule = module {
single<SqlDriver> { AndroidSqliteDriver(AppDatabase.Schema, androidContext(), "app.db") }
single<HttpClientEngine> { OkHttp.create() }
}
// iosMain — platform module
val iosPlatformModule = module {
single<SqlDriver> { NativeSqliteDriver(AppDatabase.Schema, "app.db") }
single<HttpClientEngine> { Darwin.create() }
}
Android startup (Application.onCreate):
startKoin {
androidContext(this@MyApp)
modules(sharedModules + androidPlatformModules)
}
iOS startup (called from Swift @main):
fun initKoin() = startKoin {
modules(sharedModules + iosPlatformModules)
}
See the kmp-di-koin skill for complete setup details.
3. Module Structure
:shared ← KMP module with commonMain/androidMain/iosMain
├── src/commonMain/kotlin/
│ ├── domain/ ← Use Cases, interfaces, domain models
│ ├── data/ ← Repository implementations, Ktor, SQLDelight
│ └── presentation/ ← ViewModels, UI state models
├── src/androidMain/kotlin/
│ └── di/ ← Android Koin platform modules
└── src/iosMain/kotlin/
└── di/ ← iOS Koin platform modules
:androidApp ← Android entry point (Activity, Application, Manifest)
:iosApp ← Xcode project / iOS entry point
:feature:[name] ← Optional: standalone KMP feature modules
Core dependency rules:
:feature:*depends on:shared:androidAppdepends on:shared; applies Android-specific plugins:iosAppconsumes the compiled Kotlin/Native framework from:shared
4. Checklist
- Domain layer has zero platform imports (
android.*,platform.*,UIKit.*) -
ViewModelis incommonMainusingorg.jetbrains.androidx.lifecycle:lifecycle-viewmodel - DI uses Koin; no
@HiltViewModel,@Inject, or@AndroidEntryPointincommonMain - Repositories expose main-safe
suspendfunctions andFlowstreams - Platform drivers (SQLite, HTTP engine) injected via
androidMain/iosMainKoin modules -
applyHierarchyTemplate { }explicitly lists only your actual targets (see CLAUDE.md §9)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.