AgentSkillsCN

kotlin-multiplatform-library-fundamentals

以API设计与跨平台兼容性为核心,指导开发者打造稳健、可投入生产的Kotlin多平台(KMP)库。 在以下场景中使用:当你需要按照JVM、iOS与JS目标的最佳实践,创建全新的KMP共享库时。

SKILL.md
--- frontmatter
name: kotlin-multiplatform-library-fundamentals
description: |
  Guides the creation of robust, production-ready Kotlin Multiplatform (KMP) libraries with a focus on API design and cross-platform compatibility.
  Use when: you need to create a new KMP shared library following best practices for JVM, iOS, and JS targets.

Kotlin Multiplatform Library Fundamentals

This skill provides a structured workflow for creating high-quality Kotlin Multiplatform (KMP) libraries. It acts as a Staff Software Architect, ensuring best practices for API design, build configuration, and platform compatibility are followed from the start.

The primary goal is to produce modular, maintainable libraries that seamlessly integrate with legacy JVM (Java 8) ecosystems, as well as modern native (iOS) and JavaScript targets.

Workflow: Creating a KMP Library

Follow these sequential steps to ensure a consistent and robust library setup.

1. Initialize the Module Structure

A clean, conventional directory structure is the foundation of a KMP library. This skill provides a script to automate this process.

  1. Execute the Scaffolding Script: Run the init_gradle_module.sh script to create the standard source sets (commonMain, jvmMain, iosMain, jsMain) and a pre-configured build.gradle.kts file.

    bash
    /bin/bash ./scripts/init_gradle_module.sh <your-module-name>
    
  2. Review the Generated Files: Inspect the created directory structure and the initial build.gradle.kts. It includes essential configurations covered in the next step.

2. Configure the Gradle Build (build.gradle.kts)

Proper Gradle configuration is critical for compatibility and API stability.

  1. Set JVM Compatibility: Ensure the jvmToolchain is set to 8. This guarantees that the generated bytecode is compatible with legacy Java 8 runtimes.

    kotlin
    kotlin {
        jvm {
            withJava()
            jvmToolchain(8)
        }
        // ... other targets
    }
    
  2. Enforce Explicit API Mode: All KMP libraries must use explicit API mode to prevent unintentionally exposing internal APIs. This makes the public API surface deliberate and clear.

    kotlin
    kotlin {
        explicitApi() // Or explicitApiWarning() during initial development
    }
    
  3. Define Targets: Configure the required targets (e.g., jvm, iosX64, iosArm64, iosSimulatorArm64, js).

3. Design the Shared API (commonMain)

The commonMain source set contains the core logic and public API of your library.

  1. Prioritize Dependency Injection: Avoid overusing expect/actual. For platform-specific implementations, prefer passing interfaces into your commonMain code from the platform-specific source sets. For a detailed guide, read references/kmp_architecture.md.

  2. Embrace Immutability: Design your data classes and state holders to be immutable (val over var). This is crucial for preventing concurrency issues, especially on native platforms like iOS.

  3. Expose Suspending Functions for Asynchrony: Use suspend functions for asynchronous operations. This pattern translates well across platforms and coroutines runtimes.

4. Manage Dependencies

  1. Use commonMain for Shared Dependencies: Declare dependencies that are published for all targets in the commonMain source set.
    kotlin
    sourceSets {
        val commonMain by getting {
            dependencies {
                api("io.insert-koin:koin-core:x.y.z") // Example: DI framework
            }
        }
    }
    
  2. Use Platform-Specific Source Sets for Platform Dependencies: For dependencies that are specific to a platform (e.g., OkHttp for JVM), declare them in the corresponding source set (jvmMain, nativeMain, etc.).

5. Address iOS Interoperability

When exposing your API to Swift/Objective-C, certain Kotlin features require careful handling. Review references/ios_interop_guidelines.md for a complete list of pitfalls and solutions.