Skip to content

felipechaux/kmp-compose-multiplatform-skill

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JetBrains

KMP + Compose Multiplatform Agent Skill

Make your AI coding tool actually understand Kotlin-Compose Multiplatform. Backed by real JetBrains and Google architecture docs — not vibes.

Setup time License Compose Multiplatform Kotlin


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<List<T>> 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:

  1. Core Principles — Foundational rules for KMP development
  2. Project Structure — Module and package layout conventions
  3. Architecture Guidelines — Layer responsibilities, dependency rules, typed error handling
  4. KMP Patternsexpect/actual, source sets, platform configuration
  5. Dependency Injection — Koin modules, named qualifiers, SavedStateHandle, scopes
  6. Build System — Version catalog, BuildKonfig, KSP setup
  7. Data Persistence — Room KMP (migrations, reactive queries, Paging 3, FTS) and DataStore
  8. Networking — Ktor with auth, cert pinning, backoff jitter, caching, 429 handling
  9. Internationalization — String resources, plurals, RTL support, dynamic locale change
  10. Testing Strategy — Fakes, SharedFlow event tests, Paging tests, screenshot tests
  11. Loggingexpect/actual log functions, Timber + CrashlyticsTree (Android), os_log (iOS)
  12. Common Pitfalls — 24 mistakes to avoid in KMP projects
  13. Official References — Links to authoritative documentation

references/ — deep-dive guides:

  • architecture.md — module structures, feature flags, inter-feature comms, proto DataStore, state management
  • compose-best-practices.md@Stable, focus management, text field a11y, dynamic type, Material 3, performance
  • error-handling.mdAppError hierarchy, recoverable vs fatal, 429, error analytics, safeApiCall, retry logic
  • testing.md — fakes, Turbine, SharedFlow event testing, Paging tests, screenshot/golden tests, Compose UI tests
  • ios-interop.md — Swift naming, SKIE sealed class edge cases, Kotlin/Native memory model, iOS performance
  • navigation.md — deep links, cross-module contracts, predictive back, deep link validation, transitions
  • build-system.md — convention plugins, R8/ProGuard, Maven publishing, CI Gradle daemon, KSP, build performance
  • i18n.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?

  • binaryTarget cannot 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:

  1. File → Add Package Dependencies
  2. Enter your GitHub repo URL
  3. Select version rule → Add Package
  4. import MyShared in your Swift files

Local (development) — use your local build directly:

  1. File → Add Package Dependencies → Add Local
  2. Select the root folder containing Package.swift
  3. 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 "ci@github.com"
    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.swift manually — 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:

Reference Architecture

This skill is grounded in official, production-tested documentation:

Official Documentation Links

Contributing

Contributions that improve the skill are welcome:

  1. Fork the repository
  2. Create a branch: git checkout -b improve/feature-name
  3. Update the skill file with accurate, tested patterns
  4. Reference official documentation for any new patterns added
  5. 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

About

Claude Code skill for Kotlin Multiplatform (KMP) + Compose Multiplatform — clean architecture, Koin, Ktor, Room, based on Now in Android & official Google/JetBrains docs

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors