kmp-developer

star 1

General Kotlin Multiplatform development for implementing features, fixing bugs, and refactoring code. Use when: (1) Implementing new features with vertical slice architecture, (2) Fixing bugs in feature modules, (3) Adding repositories, ViewModels, or data layers, (4) Creating Compose UI screens, (5) Writing tests with Kotest. Keywords: feature implementation, bug fixes, refactoring, vertical slice, KMP development

niltsiar By niltsiar schedule Updated 2/14/2026

name: kmp-developer description: "General Kotlin Multiplatform development for implementing features, fixing bugs, and refactoring code. Use when: (1) Implementing new features with vertical slice architecture, (2) Fixing bugs in feature modules, (3) Adding repositories, ViewModels, or data layers, (4) Creating Compose UI screens, (5) Writing tests with Kotest. Keywords: feature implementation, bug fixes, refactoring, vertical slice, KMP development"

When to Use

Use this skill when working on:

  • Implementing new features following vertical slice architecture
  • Fixing bugs in existing feature modules (api, data, presentation, ui, wiring)
  • Refactoring code within feature boundaries
  • Adding or modifying repositories, ViewModels, and data layers
  • Creating or updating Compose UI screens
  • Writing or updating tests (Kotest in androidUnitTest/)
  • Adding new dependencies via version catalog
  • Making changes to Koin DI wiring modules

Do NOT use this skill for:

  • Product/PRD decisions → switch to Product Design Mode
  • Visual design/animations → switch to UI/UX Design Mode
  • SwiftUI iOS screens → switch to SwiftUI Screen Implementation Mode
  • Test planning/strategy → switch to Testing Strategy Mode
  • Ktor backend changes → switch to Backend Development Mode

Decision Framework

Before implementing, ask yourself:

  1. What layer needs work?

    • New feature contracts → :api module
    • Data fetching/storage → :data module (repo + DTOs)
    • UI state management → :presentation module (ViewModel)
    • User interface → :ui-material or :ui-unstyled modules
    • Dependency wiring → :wiring or :wiring-ui-* modules
  2. What patterns apply?

    • Repository → Either<RepoError, T> + Impl+Factory
    • ViewModel → Pass scope to constructor, use onStart() not init
    • Tests → Property tests for mappers, Turbine for ViewModels, all error paths for repos
  3. What breaks if I change this?

    • Always run validation: ./gradlew :composeApp:assembleDebug test --continue
    • Check cross-module dependencies if modifying :api
    • Verify iOS exports if changing :api or :presentation

Essential Workflows

Workflow 1: Implement New Feature (Vertical Slice)

MANDATORY - READ ENTIRE FILE: Before implementing new features, you MUST read feature-workflow.md (~100 lines) for complete vertical slice implementation steps.

Quick summary: Create feature directory with 8 layers (api, data, presentation, ui-material, ui-unstyled, wiring, wiring-ui-material, wiring-ui-unstyled), implement repository with Either boundary, create lifecycle-aware ViewModel, wire with Koin, write tests, validate.

Workflow 2: Fix Bug in Existing Feature

To diagnose and fix bugs:

  1. Identify the affected layer from error symptoms:

    • UI issues → check :ui module screens
    • Data/loading issues → check :presentation ViewModel
    • Network/parsing errors → check :data repository implementation
    • DI/runtime errors → check :wiring module configuration
  2. Locate relevant test file in androidUnitTest/:

    • Repositories → :data/src/androidUnitTest
    • ViewModels → :presentation/src/androidUnitTest
    • Mappers → :data/src/androidUnitTest
  3. Reproduce the failing test case

  4. Fix the implementation following canonical patterns:

    • ViewModels: pass viewModelScope to constructor, use onStart() not init
    • Repositories: return Either<RepoError, T>, use Either.catch { }.mapLeft { }
    • Impl+Factory: internal implementation class, public factory function
  5. Run tests to verify fix:

    ./gradlew :composeApp:assembleDebug test --continue
    
  6. Add regression test for the bug fix

Workflow 3: Add or Update Tests

To maintain test coverage requirements (100% for mappers, 30-40% property tests):

  1. For mapper tests (REQUIRED - 100% property coverage):

    class <Feature>MapperSpec : FreeSpec({
        "dto to domain preserves all properties" {
            checkAll(Arb.<Feature>Dto()) { dto ->
                val domain = dto.toDomain()
                domain.id shouldBe dto.id
                // verify all properties
            }
        }
    })
    
  2. For ViewModel tests (REQUIRED - Turbine for flows):

    class <Feature>ViewModelSpec : FreeSpec({
        lateinit var repository: <Feature>Repository
        lateinit var testScope: TestScope
        lateinit var viewModel: <Feature>ViewModel
    
        beforeTest {
            repository = mockk()
            testScope = TestScope()
            viewModel = <Feature>ViewModel(repository, testScope)
        }
    
        "state transitions correctly on success" {
            val data = listOf(<Feature>Data(...))
            coEvery { repository.getData() } returns data.right()
    
            viewModel.uiState.test {
                awaitItem() shouldBe <Feature>UiState.Loading
                viewModel.onStart(owner)
                testScope.advanceUntilIdle()
                val content = awaitItem().shouldBeInstanceOf<<Feature>UiState.Content>()
                content.data shouldHaveSize 1
            }
        }
    })
    
  3. For repository tests (REQUIRED - all error paths):

    class <Feature>RepositorySpec : FreeSpec({
        "returns Network error on IOException" {
            coEvery { api.getData() } throws IOException("network error")
            repository.getData().fold(
                ifLeft = { error -> error shouldBeInstanceOf RepoError.Network::class },
                ifRight = { fail("Expected left") }
            )
        }
    })
    
  4. Run tests:

    ./gradlew :composeApp:assembleDebug test --continue
    

Critical Guardrails

  1. NEVER do work in ViewModel init block → override onStart(owner: LifecycleOwner) instead (lifecycle-aware initialization prevents premature work before UI attachment)

  2. NEVER store CoroutineScope as field → pass viewModelScope to constructor with default value (enables TestScope injection for deterministic testing)

  3. NEVER return nullable or Result from repositories → return Either<RepoError, T> with Either.catch { }.mapLeft { } (type-safe error handling with exhaustive when clauses)

  4. NEVER export :data, :ui, :wiring to iOS → only :api and :presentation are exported via :shared framework (iOS uses SwiftUI, not Compose; implementation details stay private)

  5. NEVER use star imports → always use explicit imports (prevents namespace pollution, enforced by .editorconfig)

  6. NEVER skip tests when adding code → every production file requires a test file in androidUnitTest/ (current coverage: 114 tests passing, maintain this standard)

  7. NEVER create empty use cases → call repositories directly from ViewModels when no orchestration needed (reduces unnecessary abstraction layers)

  8. NEVER swallow CancellationExceptionEither.catch respects cancellation automatically (cooperative cancellation is critical for coroutine correctness)

  9. NEVER skip Primary Validation before committing → ./gradlew :composeApp:assembleDebug test --continue must pass (builds app + runs 114 tests in ~45s, catches integration issues early)

  10. NEVER mix feature concerns → each feature is a self-contained vertical slice (violating this breaks compilation avoidance and team autonomy)

Quick Reference

Command Purpose When to Run
./gradlew :composeApp:assembleDebug test --continue Primary validation (Android build + all tests) Always, before committing
./gradlew :composeApp:run Run desktop app Local development
./gradlew dependencyUpdates Check for dependency updates Periodically
./gradlew recordRoborazziDebug Record screenshot baselines When adding UI tests
./gradlew verifyRoborazziDebug Verify screenshots match baselines Running UI tests
./gradlew :features:<feature>:<layer>:testDebugUnitTest Run specific module tests Focused testing

Cross-References

Skills (by Category)

Architecture

Skill Purpose Link
@kmp-architecture Module structure, vertical slicing, feature boundaries SKILL.md
@kmp-critical-patterns 6 core patterns quick reference (ViewModel, Either, Impl+Factory, Navigation, Testing, Plugins) SKILL.md

Layer Implementation

Skill Purpose Link
@kmp-presentation ViewModels, lifecycle, SavedStateHandle, UI state management SKILL.md
@kmp-data-layer Repository patterns, Either<RepoError, T>, DTO mapping SKILL.md
@kmp-domain Domain models, use cases, domain exceptions SKILL.md
@kmp-di Koin dependency injection patterns and configuration SKILL.md

Platform & Navigation

Skill Purpose Link
@kmp-ios SwiftUI + KMP ViewModels Direct Integration, iOS export SKILL.md
@kmp-navigation Navigation 3 modular architecture, scoped routes SKILL.md
@kmp-desktop Desktop (JVM) SavedStateHandle, Koin, platform-specific patterns SKILL.md

Design & Build

Skill Purpose Link
@kmp-design-systems Design tokens, component library, icon strategy SKILL.md
@kmp-compose-unstyled Headless components, Compose Unstyled patterns SKILL.md
@kmp-api-services Ktor Client, DTOs, API service patterns SKILL.md
@kmp-gradle Convention plugins, Gradle build configuration SKILL.md
@kmp-commands CLI reference, build commands, validation scripts SKILL.md

Testing

Skill Purpose Link
@kmp-testing-strategy Testing philosophy, coverage guidelines, test planning SKILL.md
@kmp-testing-patterns Kotest, MockK, Turbine, property-based testing patterns SKILL.md

Documents

Document Purpose Link
Architecture + conventions Master reference for architecture, modules, DI @kmp-architecture
iOS integration SwiftUI + KMP ViewModels Direct Integration details @kmp-ios
Dependency injection Koin patterns and troubleshooting @kmp-di

Reference Implementation: pokemonlist feature demonstrates all patterns:

Install via CLI
npx skills add https://github.com/niltsiar/kotlin_multiplatform_pokedex --skill kmp-developer
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator