Kotlin Multiplatform: その概要、shared module、expect/actual

著者: IT Sectr 公開日: 2026-02-11 読了時間: 11 分

Kotlin Multiplatform (KMP) はJetBrainsのテクノロジーで、共有KotlinコードをiOS、Android、Web、Desktop向けにコンパイルします。FlutterやReact Nativeとは異なり、KMPはネイティブUIを置き換えません — 共有ロジックはshared moduleに抽出され、各アプリのインターフェースはネイティブのままです。Kotlin Multiplatform documentation — モジュール設定とexpect/actualメカニズムの主要リファレンスです。

主要ポイント

  • KMP — ネイティブUIを置き換えずにプラットフォームAPI向けのexpect/actualを備えたKotlinの共有ロジック
  • Shared module — すべてのプラットフォーム向けのネットワーキング、データベース、バリデーション、ビジネスロジックコードを含むGradleモジュール
  • Expect/actual — 各ターゲット向けの実装を伴う共有コードでのプラットフォームAPI宣言メカニズム
  • iOS統合 — shared moduleがKotlin/Native経由でAppleフレームワークにコンパイルされます
  • KMP vs KMM — Kotlin Multiplatform Mobile(モバイルフォーカス)は現在Kotlin Multiplatformの一部です

Kotlin Multiplatformとは?

Kotlin Multiplatform はクロスコンパイルテクノロジーで、Kotlinで共有コードを記述し、さまざまなプラットフォーム(JVM(Android)、LLVM(iOS、macOS、watchOS)、JavaScript(Web)、ネイティブバイナリ(Linux、Windows))向けにコンパイルできます。KMPはUIフレームワークではありません — インターフェースではなく、ビジネスロジックの再利用の問題を解決します。

KMPアーキテクチャはshared moduleを中心に構築されています — プラットフォームに依存しないコードを含むcommonMainと、各ターゲット(androidMain、iosMain、desktopMain)のsource setsを含むGradleモジュールです。2025年のJetBrainsのデータによると、新しいKotlinプロジェクトの40%以上がプラットフォーム間でコードを共有するためにKMPを使用しています。

Kotlin Multiplatform Mobile (KMM) — iOS+Androidモバイルシナリオの以前の名称です。Kotlin 2.1+以降、KMMという用語はKotlin Multiplatformに置き換えられました。これはテクノロジーがモバイル開発を超えて拡張されたためです。Netflix、McDonald's、VMwareはモバイルアプリケーション間でコードを共有するために本番環境でKMPを使用しています。

Expect/actualメカニズム:アーキテクチャ

Expect/actual — プラットフォーム固有のコードを扱うためのKMPの主要メカニズムです。commonMainでexpect宣言(関数、クラス、プロパティ)が宣言され、各プラットフォーム固有のsource set(androidMain、iosMain)でactual実装が提供されます。コンパイラは、各expectに対して各ターゲットプラットフォームにactualが存在することを確認します。

kotlin
// commonMain — プラットフォームAPI宣言
expect fun getPlatformName(): String

expect class PlatformContext(val appVersion: String)

// androidMain — Android向けactual
actual fun getPlatformName(): String = "Android \${Build.VERSION.SDK_INT}"

// iosMain — iOS向けactual
actual fun getPlatformName(): String =
    UIDevice.currentDevice.systemName

KMPのsource sets階層により、中間レベルの作成が可能になります:たとえば、iosArm64Main(物理iOSデバイス)とiosSimulatorArm64Main(シミュレータ)と共有iosMainです。commonMainのコードはすべてのプラットフォームで利用可能ですが、iosMainのコードはiOSターゲットのみで利用可能です。これにより、実装がプラットフォームごとではなくプラットフォームのグループごとに異なる場合の重複が削減されます。

実際には、expect/actualは次の目的で使用されます:ローカルストレージへのアクセス(SharedPreferences vs NSUserDefaults)、ネットワーキング(プラットフォームごとのHttpEngine)、ファイルシステムアクセス、暗号化、分析。JetBrainsはexpect/actual宣言の数を最小限に抑え、可能な限り多くのコードをcommonMainに移動することを推奨しています。

Shared module:構造とGradle

Shared moduleorg.jetbrains.kotlin.multiplatformプラグインを使用した標準的なGradleモジュールです。src/commonMain/kotlin/に共有コードが含まれ、src/androidMain/kotlin/src/iosMain/kotlin/にプラットフォーム固有の実装が含まれます。KMPプロジェクトには、shared moduleに依存するandroidAppiosAppも含まれます。

kotlin
// build.gradle.kts — shared module
plugins {
    kotlin("multiplatform")
    id("com.android.library")
}

kotlin {
    androidTarget()
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
            isStatic = true
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-core:3.1.0")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-okhttp:3.1.0")
            }
        }
        val iosMain by creating {
            dependencies {
                implementation("io.ktor:ktor-client-darwin:3.1.0")
            }
        }
    }
}

KMPのGradle設定では、iOSターゲット(x64(Intelシミュレータ)、arm64(物理デバイス)、simulatorArm64(Apple Siliconシミュレータ))の明示的な宣言が必要です。各ターゲットに対して個別のAppleフレームワークが生成されます。kotlin("multiplatform")プラグインは、宣言されたターゲットに応じてJVMとLLVMのコンパイルを自動的に設定します。

Ktorkotlinx.serialization — 共有コードをサポートする標準的なKMPライブラリです。Ktorは各プラットフォーム向けのエンジンを備えたHTTPクライアントを提供します(Android向けOkHttp、iOS向けDarwin)。kotlinx.serializationは、commonMainでのマルチプラットフォーム実装により、expect/actualなしですべてのプラットフォームで動作します。

Kotlin/NativeによるiOS統合

Kotlin/Native — LLVM経由でネイティブコードを生成するKotlinコンパイラです。iOSの場合、shared moduleはAppleフレームワーク(.framework)にコンパイルされ、Xcodeを介して接続されます。Swift/Objective-Cからの共有コードの呼び出しは、生成されたObjective-Cヘッダーを介して行われるため、shared module APIはObjective-Cと互換性がある必要があります。

iOS統合の制限: Kotlinコレクション(List、Map)はNSArray/NSDictionaryに変換されます。デフォルトパラメータを持つ関数はエクスポートされません — オーバーロードが必要です。suspend関数の場合、@ObjCNameとKotlin 2.0+からのasync/awaitサポートを使用したコールバックベースのメソッドが生成されます。

swift
// iOSアプリ:Swiftからshared moduleを呼び出す
import shared

class ViewModel: ObservableObject {
    let repository = UserRepository()
    
    func loadUsers() {
        repository.fetchUsers(completionHandler: { result, error in
            if let users = result as? [User] {
                print("Users: \(users.count)")
            }
        })
    }
}

Xcodeへのshared module統合はembed-and-frameworkを介して行われます — 生成された.xcframeworkがXcodeプロジェクトに追加されます。Gradleプラグインは、embedAndSignAppleFrameworkForXcodeを介してビルド中にフレームワークを自動的に更新できます。シミュレータでのテストには、iosSimulatorArm64またはiosX64バイナリで十分です。

KMP vs Flutter vs React Native

KMP、Flutter、React Nativeの選択は、優先事項(コードの再利用か完全なクロスプラットフォームか)によって異なります。KMPは各プラットフォームでネイティブUIを提供しますが、インターフェースに2つのコードベースが必要です。FlutterとReact Nativeは単一のUIを使用しますが、ネイティブ性を犠牲にします。

特徴KMPFlutterReact Native
UIフレームワークネイティブ(Android XML/Jetpack Compose + SwiftUI)Dart + 独自のSkiaレンダラーReact + ネイティブコンポーネント
共有コードビジネスロジック、ネットワーキング、DB、バリデーションネイティブプラグインを除く100%ネイティブモジュールを除く100%
パフォーマンスネイティブ(ミドルウェアなし)高い(Skia Engine)中程度(JSI Bridge)
iOSサポートKotlin/Native(優れている)優れている良い
参入障壁中程度(Kotlin + ネイティブプラットフォーム)低い(1つの言語 + 1つのUI)低い(JS/TS + React)

KMPを選ぶべき場合: プロジェクトに高性能なUI(ゲーム、マップ、アニメーション)が必要、既存のネイティブコードを再利用する必要がある、チームがすでにKotlinとネイティブプラットフォームを知っている場合。Flutter/RNを選ぶべき場合: 予算が限られたMVPやスタートアップ、単一プロファイルのチーム、UIに深いネイティブカスタマイズが不要な場合。

KMPツールとライブラリ

KMPツールのエコシステムには、アプリケーションのすべての層向けのライブラリが含まれています:ネットワーキング(Ktor)、シリアル化(kotlinx.serialization)、データベース(SQLDelight)、ナビゲーション(Decompose)、DI(Koin)、データストレージ(multiplatform-settings)。JetBrainsはCompose Multiplatformをサポートしています — すべてのプラットフォームで動作するKotlin UIフレームワークです。

kotlin
// SQLDelight + Ktorを使用したKMPリポジトリ
class UserRepository(
    private val httpClient: HttpClient,
    private val db: AppDatabase
) {
    suspend fun syncUsers(): List<User> {
        val remote = httpClient.get("https://api.example.com/users")
            .body<List<UserDto>>()
        
        db.userQueries.replaceAll(remote.map { it.toDomain() })
        
        return db.userQueries.selectAll().executeAsList()
    }
}

Compose Multiplatform — Jetpack ComposeベースのKMP向けUIフレームワークです。Android、iOS、Desktop、Web向けにKotlinでインターフェースを記述できます。2025年、Compose MultiplatformはAndroidとDesktopで安定したステータスに達しました。iOSターゲットはベータ版です。ネイティブUIを使用する本番プロジェクトでは、KMPの優位性がFlutterとの主な違いであり続けています。

よくある質問

Kotlin MultiplatformとKotlin Multiplatform Mobileの違いは何ですか?

KMM — iOSとAndroid向けのKMPのモバイルシナリオです。Kotlin 2.1+以降、JetBrainsは両方の用語をKotlin Multiplatformに統合しました。これはテクノロジーがモバイルプラットフォームだけでなく、DesktopやWebもサポートするためです。KMMプロジェクトは引き続き動作しますが、現在は全体的なKMPの一部です。

KMPをSwiftUIで使用できますか?

はい。KMPはObjective-Cヘッダーを使用してKotlin/Native経由でAppleフレームワークにコンパイルされます。SwiftUIはこのフレームワークを通常のライブラリとしてインポートします。Shared moduleはKotlinクラスと関数をエクスポートし、いくつかの制限付きでSwiftから呼び出されます(たとえば、KotlinコレクションはFoundation型に変換されます)。

iOSでshared moduleをテストするには?

iOSでは、shared moduleはiosTest source setでのKotlin/Nativeテストを通じてテストされます。UIテストには、インポートされたフレームワークを使用してXcodeでXCTestが使用されます。KotlinテストはcommonTestでkotlin.testを使用して記述され、iosSimulatorArm64Test Gradleタスクを介してiOSシミュレータで実行されます。

KMPで利用可能なライブラリは?

主要なKMPライブラリ:Ktor(ネットワーキング)、kotlinx.serialization(JSON)、SQLDelight(DB)、Koin(DI)、Decompose(ナビゲーション)、multiplatform-settings(SharedPreferences/NSUserDefaults)、Apollo GraphQL、Firebase(KMP-NativeCoroutines経由)。Compose MultiplatformはすべてのプラットフォームにUIを提供します。

KMPはGradle 8をサポートしていますか?

はい。KMPはGradle 8.5+と完全に互換性があります。Kotlin 2.1以降、公式プラグインはGradle 8をサポートしています。build.gradle.ktsを使用したkotlin("multiplatform")の設定にはGradle 7.6+が必要ですが、最適なビルドパフォーマンスのためにバージョン8.5が推奨されています。

まとめ

  • Kotlin Multiplatform — ネイティブUIを置き換えずに共有コードを実現するJetBrainsのクロスプラットフォームテクノロジー
  • Expect/actual — 各ターゲット向けの実装を伴うcommonMainでのプラットフォームAPI宣言メカニズム
  • Shared module — commonMainとプラットフォーム固有のsource sets(androidMain、iosMain)を備えたGradleモジュール
  • Kotlin/Nativeがshared moduleをAppleフレームワークにコンパイルし、SwiftおよびObjective-Cから呼び出し可能
  • KMP vs Flutter/RN — ロジックの再利用 + ネイティブUI vs 単一のコードベースとUI
  • Compose Multiplatform — Android、iOS、Desktop、Web向けのKotlin UIフレームワーク
  • エコシステム — すべてのアプリケーション層向けのKtor、SQLDelight、Koin、kotlinx.serialization、Decompose

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください