$npx -y skills add Kotlin/kotlin-agent-skills --skill kotlin-tooling-agp9-migrationMigrates Kotlin Multiplatform (KMP) projects to Android Gradle Plugin 9.0+. Handles plugin replacement (com.android.kotlin.multiplatform.library), module splitting, DSL migration, and the new default project structure. Use when upgrading AGP, when build fails due to KMP+AGP incom
| 1 | # KMP AGP 9.0 Migration |
| 2 | |
| 3 | Android Gradle Plugin 9.0 makes the Android application and library plugins incompatible |
| 4 | with the Kotlin Multiplatform plugin in the same module. This skill guides you through the |
| 5 | migration. |
| 6 | |
| 7 | ## Step 0: Analyze the Project |
| 8 | |
| 9 | Before making any changes, understand the project structure: |
| 10 | 1. Read `settings.gradle.kts` (or `.gradle`) to find all modules |
| 11 | 2. For each module, read its `build.gradle.kts` to identify which plugins are applied |
| 12 | 3. Check if the project uses a Gradle version catalog (`gradle/libs.versions.toml`). If it exists, |
| 13 | read it for current AGP/Gradle/Kotlin versions. If not, find versions directly in `build.gradle.kts` |
| 14 | files (typically in the root `buildscript {}` or `plugins {}` block). **Adapt all examples in this |
| 15 | guide accordingly** — version catalog examples use `alias(libs.plugins.xxx)` while direct usage |
| 16 | uses `id("plugin.id") version "x.y.z"` |
| 17 | 4. Read `gradle/wrapper/gradle-wrapper.properties` for the Gradle version |
| 18 | 5. Check `gradle.properties` for any existing workarounds (`android.enableLegacyVariantApi`) |
| 19 | 6. Check for `org.jetbrains.kotlin.android` plugin usage — AGP 9.0 has built-in Kotlin and this plugin must be removed |
| 20 | 7. Check for `org.jetbrains.kotlin.kapt` plugin usage — incompatible with built-in Kotlin, must migrate to KSP or `com.android.legacy-kapt` |
| 21 | 8. Check for third-party plugins that may be incompatible with AGP 9.0 (see "Plugin Compatibility" section below) |
| 22 | |
| 23 | If Bash is available, run `scripts/analyze-project.sh` from this skill's directory to get a structured summary. |
| 24 | |
| 25 | ### Classify Each Module |
| 26 | |
| 27 | For each module, determine its type: |
| 28 | |
| 29 | | Current plugins | Migration path | |
| 30 | |--------------------------------------------------------------------------|---------------------------------------------| |
| 31 | | `kotlin.multiplatform` + `com.android.library` | **Path A** — Library plugin swap | |
| 32 | | `kotlin.multiplatform` + `com.android.application` | **Path B** — Mandatory Android split | |
| 33 | | `kotlin.multiplatform` with multiple platform entry points in one module | **Path C** — Full restructure (recommended) | |
| 34 | | `com.android.application` or `com.android.library` (no KMP) | See "Pure Android Tips" below | |
| 35 | |
| 36 | ### Determine Scope |
| 37 | |
| 38 | - **Path B is mandatory** for any module combining KMP + Android application plugin |
| 39 | - **Path C is recommended** when the project has a monolithic `composeApp` (or similar) module |
| 40 | containing entry points for multiple platforms (Android, Desktop, Web). This aligns with the |
| 41 | new JetBrains default project structure where each platform gets its own app module. |
| 42 | - **Ask the user** whether they want Path B only (minimum required) or Path C (recommended full restructure) |
| 43 | |
| 44 | ## Path A: Library Module Migration |
| 45 | |
| 46 | Use this when a module applies `kotlin.multiplatform` + `com.android.library`. |
| 47 | |
| 48 | See [references/MIGRATION-LIBRARY.md](references/MIGRATION-LIBRARY.md) for full before/after code. |
| 49 | |
| 50 | Summary: |
| 51 | |
| 52 | 1. **Replace plugin**: `com.android.library` → `com.android.kotlin.multiplatform.library` |
| 53 | 2. **Remove `org.jetbrains.kotlin.android`** plugin if present (AGP 9.0 has built-in Kotlin support) |
| 54 | 3. **Migrate DSL**: Move config from top-level `android {}` block into `kotlin { android {} }`: |
| 55 | ```kotlin |
| 56 | kotlin { |
| 57 | android { |
| 58 | namespace = "com.example.lib" |
| 59 | compileSdk = 35 |
| 60 | minSdk = 24 |
| 61 | } |
| 62 | } |
| 63 | ``` |
| 64 | 4. **Rename source directories** (only if the module uses classic Android layout instead of KMP layout): |
| 65 | - `src/main` → `src/androidMain` |
| 66 | - `src/test` → `src/androidHostTest` |
| 67 | - `src/androidTest` → `src/androidDeviceTest` |
| 68 | - If the module already uses `src/androidMain/`, no directory renames are needed |
| 69 | 5. **Move dependencies** from top-level `dependencies {}` into `sourceSets`: |
| 70 | ```kotlin |
| 71 | kotlin { |
| 72 | sourceSets { |
| 73 | androidMain.dependencies { |
| 74 | implementation("androidx.appcompat:appcompat:1.7.0") |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | ``` |
| 79 | 6. **Enable resources** explicitly if the module uses Android or Compose Multiplatform resources: |
| 80 | ```kotlin |
| 81 | kotlin { |
| 82 | android { |
| 83 | androidResources { enable = true } |
| 84 | } |
| 85 | } |
| 86 | ``` |
| 87 | 7. **Enable Java** compilation if module has `.java` source files: |
| 88 | ```kotlin |
| 89 | kotlin { |
| 90 | android { |
| 91 | withJava() |