
felipechaux/kmp-compose-multiplatform-skill
Developer toolsClaude Code skill for Kotlin Multiplatform (KMP) + Compose Multiplatform — clean architecture, Koin, Ktor, Room, based on Now in Android & official Google/JetBrains docs
Overview
Backed by real JetBrains and Google architecture docs — not vibes. A that turns any Claude agent into an expert in and development — following Google's official architecture guidelines and JetBrains best practices. Without this skill, Claude gives you generic Android advice. With it, Claude understands shared commonMain source sets, expect/actual declarations, Koin multiplatform DI, Room KMP setup, Ktor client configuration, and the full Clean Architecture layer separation that makes KMP projects maintainable across Android and iOS. Claude Code automatically picks up skill directories from .claude/skills/. No configuration required. Once installed, invoke the skill in Claude Code: The skill (.claude/skills/kmp-compose-multiplatform/) is structured as a precise instruction set Claude follows when invoked: — core instruction set: 1. — Foundational rules for KMP development 2. — Module and package layout conventions 3.
README
A Claude Code skill that turns any Claude agent into an expert in Kotlin Multiplatform (KMP) and Compose Multiplatform development — following Google’s official architecture guidelines and JetBrains best practices.
Without this skill, Claude gives you generic Android advice. With it, Claude understands shared commonMain source sets, expect/actual declarations, Koin multiplatform DI, Room KMP setup, Ktor client configuration, and the full Clean Architecture layer separation that makes KMP projects maintainable across Android and iOS.
What This Skill Covers
| Area | Details |
|---|---|
| Architecture | Clean Architecture, feature-based modularization, feature flags, inter-feature comms, proto DataStore |
| UI | Compose Multiplatform, Material 3, @Stable, state hoisting, focus management, text field a11y, dynamic type |
| Navigation | Deep links, cross-module contracts, predictive back, nested nav, back handling, transitions, SavedStateHandle |
| DI | Koin Multiplatform — modules, named qualifiers, ViewModels + SavedStateHandle, scopes, platform DI |
| Networking | Ktor — auth bearer, HttpRequestRetry, cert pinning, backoff jitter, 429 handling, caching |
| Persistence | Room KMP + DataStore KMP — migrations, reactive queries, Paging 3, FTS, type converters |
| State | UDF pattern, StateFlow, SharedFlow buffer strategies, stateIn(), Resource sealed class |
| Error Handling | Typed AppError, recoverable vs fatal, 429, error analytics/breadcrumbs, retry with backoff |
| Build System | Convention plugins, R8/ProGuard, Maven publishing, CI Gradle daemon, KSP, version catalog |
| iOS | SPM wrapper, SKIE (sealed enum edge cases), Kotlin/Native memory model, iOS performance, Swift interop |
| Testing | Fakes + Turbine, SharedFlow event tests, Paging tests, screenshot/golden tests, Compose UI tests |
| Logging | Log levels, Timber + CrashlyticsTree (Android), os_log (iOS), sensitive data redaction |
| i18n | String resources, plurals, RTL support, dynamic locale change, locale-aware number/currency formatting |
Installation
Option 1: Project-level (recommended for KMP projects)
git clone https://github.com/felipechaux/kmp-compose-multiplatform-skill
cp -r kmp-compose-multiplatform-skill/.claude/skills/kmp-compose-multiplatform .claude/skills/
Option 2: Global (available in all projects)
git clone https://github.com/felipechaux/kmp-compose-multiplatform-skill
cp -r kmp-compose-multiplatform-skill/.claude/skills/kmp-compose-multiplatform ~/.claude/skills/
Option 3: Git submodule
git submodule add https://github.com/felipechaux/kmp-compose-multiplatform-skill .claude/kmp-skill
cp -r .claude/kmp-skill/.claude/skills/kmp-compose-multiplatform .claude/skills/
That’s it. Claude Code automatically picks up skill directories from
.claude/skills/. No configuration required.
Usage
Once installed, invoke the skill in Claude Code:
/kmp-compose-multiplatform
Or reference it inline:
Using the kmp-compose-multiplatform skill, create a new feature module for user authentication
Using the kmp-compose-multiplatform skill, review my ViewModel for UDF violations
Using the kmp-compose-multiplatform skill, set up Room KMP for both Android and iOS
Using the kmp-compose-multiplatform skill, configure Ktor client with auth interceptor and error handling
Using the kmp-compose-multiplatform skill, generate a Koin module for my data layer
What Changes With This Skill
| Without skill | With skill |
|---|---|
| Generic Android ViewModel patterns | UDF pattern with StateFlow, SharedFlow events, stateIn(), buffer strategies |
| Android-only Room setup | Room KMP with migrations, reactive Flow> queries, Paging 3, FTS |
Hilt / Dagger suggestions |
Koin Multiplatform with named qualifiers, SavedStateHandle, scopes, test teardown |
| Single-platform Retrofit | Ktor with auth bearer, cert pinning, backoff jitter, 429 handling, caching |
Raw String errors everywhere |
Typed AppError sealed class, recoverable vs fatal, error analytics, 429 retry |
| Mixed architecture advice | Strict Clean Architecture with feature flags and inter-feature communication patterns |
| Guessed iOS integration | SPM wrapper, SKIE sealed enum edge cases, Kotlin/Native memory model, iOS performance |
println() for debugging |
Timber + CrashlyticsTree (Android), os_log (iOS), sensitive data redaction |
| Hardcoded UI strings | String resources, plurals, RTL support, dynamic locale change |
| No accessibility guidance | Focus management, text field a11y, 48dp touch targets, screen reader semantics |
| No screenshot regression tests | Paparazzi golden tests, SharedFlow event tests, Paging tests |
| No build optimization | R8/ProGuard rules, Maven publishing, CI Gradle daemon config, convention plugins |
Skill Content Overview
The skill (.claude/skills/kmp-compose-multiplatform/) is structured as a precise instruction set Claude follows when invoked:
SKILL.md — core instruction set:
- Core Principles — Foundational rules for KMP development
- Project Structure — Module and package layout conventions
- Architecture Guidelines — Layer responsibilities, dependency rules, typed error handling
- KMP Patterns —
expect/actual, source sets, platform configuration - Dependency Injection — Koin modules, named qualifiers,
SavedStateHandle, scopes - Build System — Version catalog, BuildKonfig, KSP setup
- Data Persistence — Room KMP (migrations, reactive queries, Paging 3, FTS) and DataStore
- Networking — Ktor with auth, cert pinning, backoff jitter, caching, 429 handling
- Internationalization — String resources, plurals, RTL support, dynamic locale change
- Testing Strategy — Fakes, SharedFlow event tests, Paging tests, screenshot tests
- Logging —
expect/actuallog functions, Timber + CrashlyticsTree (Android),os_log(iOS) - Common Pitfalls — 24 mistakes to avoid in KMP projects
- Official References — Links to authoritative documentation
references/ — deep-dive guides:
architecture.md— module structures, feature flags, inter-feature comms, proto DataStore, state managementcompose-best-practices.md—@Stable, focus management, text field a11y, dynamic type, Material 3, performanceerror-handling.md—AppErrorhierarchy, recoverable vs fatal, 429, error analytics,safeApiCall, retry logictesting.md— fakes, Turbine, SharedFlow event testing, Paging tests, screenshot/golden tests, Compose UI testsios-interop.md— Swift naming, SKIE sealed class edge cases, Kotlin/Native memory model, iOS performancenavigation.md— deep links, cross-module contracts, predictive back, deep link validation, transitionsbuild-system.md— convention plugins, R8/ProGuard, Maven publishing, CI Gradle daemon, KSP, build performancei18n.md— string resources, plurals, RTL support, dynamic locale change, locale-aware number/currency formatting
Architecture Reference
This skill implements the architecture pattern shown below, directly inspired by Now in Android:
┌─────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ ViewModel → UiState → Composable Screen │
└─────────────────────┬───────────────────────────────────┘
│ uses
┌─────────────────────▼───────────────────────────────────┐
│ Domain Layer │
│ UseCase → Repository Interface → Model │
└─────────────────────┬───────────────────────────────────┘
│ implements
┌─────────────────────▼───────────────────────────────────┐
│ Data Layer │
│ Repository Impl → Remote/Local Source → DTO │
└─────────────────────────────────────────────────────────┘
Feature Module Structure
feature/
└── auth/
├── data/
│ ├── local/ ← Room entities, DAOs
│ ├── remote/ ← Ktor API services
│ ├── repository/ ← Repository implementations
│ └── mapper/ ← DTO ↔ Domain mappers
├── domain/
│ ├── model/ ← Pure Kotlin domain models
│ ├── repository/ ← Repository interfaces
│ └── usecase/ ← Business logic (one action per class)
├── presentation/
│ ├── ui/ ← Composable screens
│ ├── viewmodel/ ← State holders
│ └── state/ ← UiState sealed classes
└── di/ ← Koin module
Source Set Layout
src/
├── commonMain/ ← Shared business logic, UI, ViewModels
├── androidMain/ ← Android-specific implementations
├── iosMain/ ← iOS-specific implementations
├── commonTest/ ← Shared unit tests with fakes
├── androidUnitTest/ ← Android-specific tests
└── iosTest/ ← iOS-specific tests
iOS Integration via Swift Package Manager
The recommended pattern for distributing the KMP shared module to an iOS app is a SPM Wrapper target — this is required because a binaryTarget (the compiled XCFramework) cannot declare Swift package dependencies on its own.
Package.swift Structure
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyShared",
platforms: [.iOS(.v16)],
products: [
// Expose the wrapper, not the binary directly
.library(name: "MyShared", targets: ["MySharedWrapper"]),
],
dependencies: [
// Add Swift-only dependencies here (RevenueCat, Firebase, etc.)
.package(url: "https://github.com/RevenueCat/purchases-hybrid-common.git", exact: "17.32.0"),
],
targets: [
// Binary target — the compiled XCFramework from Kotlin/Native
.binaryTarget(
name: "MySharedBinary",
url: "https://github.com/org/repo/releases/download/v1.0.0/MyShared.xcframework.zip",
checksum: "abc123..." // sha256 — auto-computed in CI
),
// Wrapper target — bridges the binary with Swift dependencies
.target(
name: "MySharedWrapper",
dependencies: [
"MySharedBinary",
.product(name: "PurchasesHybridCommon", package: "purchases-hybrid-common"),
]
)
]
)
Why the Wrapper pattern?
binaryTargetcannot declare Swift package dependencies directly- The wrapper is an empty Swift target whose only job is to re-export the binary alongside any Swift-only dependencies
- Your iOS app only needs to
import MyShared— no knowledge of the wrapper internals
Integrating in Xcode
Remote (production) — add published releases via SPM:
File → Add Package Dependencies- Enter your GitHub repo URL
- Select version rule → Add Package
import MySharedin your Swift files
Local (development) — use your local build directly:
File → Add Package Dependencies → Add Local- Select the root folder containing
Package.swift - No checksum needed — uses the local XCFramework build
iOS Entry Point
// iosMain/MainViewController.kt
fun MainViewController(): UIViewController = ComposeUIViewController {
initKoin()
AppTheme { AppNavigation() }
}
// ContentView.swift
import SwiftUI
import MyShared
struct ContentView: View {
var body: some View {
ComposeView().ignoresSafeArea(.all)
}
}
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
CI/CD — Auto-generating Package.swift
Your GitHub Actions release workflow should:
- name: Build XCFramework
run: ./gradlew :shared:assembleReleaseXCFramework
- name: Zip XCFramework
run: zip -r MyShared.xcframework.zip shared/build/XCFrameworks/release/MyShared.xcframework
- name: Compute checksum
run: echo "CHECKSUM=$(swift package compute-checksum MyShared.xcframework.zip)" >> $GITHUB_ENV
- name: Update Package.swift
run: |
sed -i '' "s|url: \".*xcframework.zip\"|url: \"https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/MyShared.xcframework.zip\"|" Package.swift
sed -i '' "s|checksum: \".*\"|checksum: \"$CHECKSUM\"|" Package.swift
- name: Commit Package.swift
run: |
git config user.email "[email protected]"
git config user.name "GitHub Actions"
git add Package.swift
git commit -m "chore: update Package.swift for ${{ github.ref_name }} [skip ci]"
git push
Never edit
Package.swiftmanually — it should be generated by CI on every release.
Recommended Tech Stack
| Concern | Library | Version |
|---|---|---|
| UI | Compose Multiplatform | 1.8.0+ |
| DI | Koin | 4.1.1+ |
| Networking | Ktor | 3.0.3+ |
| DB | Room KMP | 2.8.4+ |
| Prefs | DataStore KMP | 1.1.1+ |
| Nav | Navigation Compose | 2.9.1+ |
| Images | Coil 3 | 3.0.4+ |
| DateTime | kotlinx-datetime | 0.6.1+ |
| Serialization | kotlinx-serialization | 1.7.3+ |
| Config | BuildKonfig | 0.17.1+ |
| Code gen | KSP | 2.3.0+ |
Examples
See the examples/ directory for ready-to-use scaffolds:
examples/feature-template/— Complete feature module with all layers wiredexamples/build-logic/— Convention plugin examples for multi-module buildsexamples/core-template/— Core module setup (network, database, DI)
Reference Architecture
This skill is grounded in official, production-tested documentation:
- Now in Android — Google’s official Android architecture reference app
- Android Architecture Guide — Official Google architecture documentation
- KMP Documentation — JetBrains official KMP docs
- Compose Multiplatform — JetBrains official CMP docs
- Real-world production KMP project patterns
Official Documentation Links
- Kotlin Multiplatform
- Compose Multiplatform
- Android Architecture Guide
- Now in Android
- Room KMP
- DataStore KMP
- Koin Multiplatform
- Ktor Client
- Navigation Compose
- Compose State Guide
- Compose Layouts
- Compose Multiplatform Resources (i18n)
- Predictive Back Gesture
- Paging 3
Contributing
Contributions that improve the skill are welcome:
- Fork the repository
- Create a branch:
git checkout -b improve/feature-name - Update the skill file with accurate, tested patterns
- Reference official documentation for any new patterns added
- Submit a pull request with a clear description
What makes a good contribution: new expect/actual patterns, corrected library APIs, additional common pitfalls, updated version references.
License
MIT License — see LICENSE
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add felipechaux/kmp-compose-multiplatform-skill