/kotlin-tooling-cocoapods-spm-migration
Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.
$ npx -y skills add kotlin/kotlin-agent-skills --skill kotlin-tooling-cocoapods-spm-migration --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/kotlin-tooling-cocoapods-spm-migration
Context preview
The summary Claude sees to decide when to auto-load this skill.
Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.
SKILL.md
kotlin-tooling-cocoapods-spm-migration.SKILL.mdname: kotlin-tooling-cocoapods-spm-migration
description: Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.
license: Apache-2.0
metadata:
author: JetBrains
version: "1.0.0"CocoaPods to SwiftPM Migration for KMP
Migrate Kotlin Multiplatform projects from `kotlin("native.cocoapods")` to `swiftPMDependencies {}` DSL.
Requirements
- **Kotlin**: 2.4.0-Beta2 or later (first public release with `swiftPMDependencies` support, available on Maven Central)
- **Xcode**: 16.4 or 26.0+
- **iOS Deployment Target**: 16.0+ recommended
Migration Overview
**IMPORTANT**: Keep the `cocoapods {}` block and plugin active until Phase 6. The migration adds `swiftPMDependencies {}` alongside the existing CocoaPods setup first, reconfigures Xcode, and only then removes CocoaPods.
| Phase | Action | |-------|--------| | 1 | Analyze existing CocoaPods configuration | | 2 | Update Gradle configuration (repos, Kotlin version) | | 3 | Add `swiftPMDependencies {}` alongside existing `cocoapods {}` | | 4 | Transform Kotlin imports | | 5 | Reconfigure iOS project and deintegrate CocoaPods | | 6 | Remove CocoaPods plugin from Gradle | | 7 | Verify Gradle build and Xcode project build | | 8 | Write MIGRATION_REPORT.md |
---
Phase 1: Pre-Migration Analysis
1.0 Verify the project builds
Before starting migration, identify the module to migrate and confirm it compiles successfully.
1. **Find the module that uses CocoaPods** — look for `build.gradle.kts` files containing `cocoapods`:
grep -rl "cocoapods" --include="build.gradle.kts" .
Extract the module name from the path (e.g., `./shared/build.gradle.kts` → module name is `shared`). Note: multiple modules may use CocoaPods — record all of them. Typically only the module that produces the framework linked into the iOS app needs `swiftPMDependencies`; the others only need CocoaPods removed (Phase 6).
2. **Compile Kotlin code** — run the Kotlin compilation task for that module to verify the Kotlin source compiles:
./gradlew :moduleName:compileKotlinIosSimulatorArm64
Replace `moduleName` with the directory name of the module (e.g., `:shared:compileKotlinIosSimulatorArm64`). This is faster than a full `build` (which also runs release linkage) and sufficient to verify Kotlin code correctness.
3. **Build the iOS app (optional)** — try to locate the Xcode project and build it to confirm the full app compiles:
# Find the Xcode project
find . -name "*.xcworkspace" -not -path "*/Pods/*" -maxdepth 2
# Build (replace scheme name with the actual app scheme)
cd /path/to/iosApp
xcodebuild -workspace *.xcworkspace -scheme "<AppScheme>" -destination 'generic/platform=iOS Simulator' ARCHS=arm64
If the user wants to skip the Xcode build or no Xcode project is found, proceed without it — the Kotlin compilation from step 2 is sufficient to continue.
4. **If the Kotlin compilation fails**, ask the user to either:
- Provide the correct Gradle command to verify the module builds, or
- Confirm the module is in a working state and it's safe to proceed
If the user confirms without providing a build command, **record that the pre-migration build could not be verified** and warn about this at the end of migration (Phase 7).
1.0a Confirm Kotlin version with Swift Import support
Read the current Kotlin version from `gradle/libs.versions.toml` (or `build.gradle.kts`).
**If the project already uses Kotlin 2.4.0-Beta2 or later** → record the version and skip Phase 2.1 (no version change needed).
**If the project uses an older Kotlin version** → Phase 2.1 will upgrade it to `2.4.0-Beta2` (the first public release with `swiftPMDependencies` support, available on Maven Central — no custom repository needed). Warn the user: "⚠️ Kotlin version jump — upgrading across minor versions can introduce breaking changes unrelated to this migration. Recommended: update first, verify it builds, then re-run this migration." If the user confirms, proceed.
1.1 Check for deprecated CocoaPods workaround property
Search `gradle.properties` for the deprecated property:
kotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true
This property was a workaround (see [KT-64096](https://youtrack.jetbrains.com/issue/KT-64096)) for projects using `embedAndSign` alongside CocoaPods dependencies. It suppresses an error about unsupported configurations that can cause runtime crashes or symbol duplication. After migrating to SwiftPM import, this property is no longer needed and **must be removed** in Phase 6. Record its presence if found.
1.2 Check for EmbedAndSign disablers
Search all `build.gradle.kts` files for code that disables `EmbedAndSign` tasks (e.g., `TaskGraph.whenReady` filters, `tasks.matching` blocks). This is a CocoaPods-era workaround that **breaks the migration** because `integrateEmbedAndSign` (needed in Phase 5) gets disabled too. Record any such code — it **must be removed** in Phase 6, and may need to be removed earlier. See [troubleshooting.md](references/troubleshooting.md) § "`integrateEmbedAndSign` Skipped" for patterns.
1.3 Check for third-party KMP libraries with bundled cinterop klibs
Some KMP libraries ship pre-built cinterop klibs with `cocoapods.*` package namespaces. After migration, the swiftPMDependencies cinterop generator detects these existing bindings and **skips generating new bindings** for those Clang modules to avoid duplicates. This means `cocoapods.*` imports for those modules must be **kept as-is** — they resolve to the third-party library's bundled klib, not to actual CocoaPods.
**Known libraries with bundled `cocoapods.*` klibs:**
| Library | Maven artifact | Bundled klib namespace | Classes provided | |--------
Read more
name: kotlin-tooling-cocoapods-spm-migration
description: Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods.* imports to swiftPMImport.*, and reconfigures the Xcode project.
license: Apache-2.0
metadata:
author: JetBrains
version: "1.0.0"CocoaPods to SwiftPM Migration for KMP
Migrate Kotlin Multiplatform projects from `kotlin("native.cocoapods")` to `swiftPMDependencies {}` DSL.
Requirements
- **Kotlin**: 2.4.0-Beta2 or later (first public release with `swiftPMDependencies` support, available on Maven Central)
- **Xcode**: 16.4 or 26.0+
- **iOS Deployment Target**: 16.0+ recommended
Migration Overview
**IMPORTANT**: Keep the `cocoapods {}` block and plugin active until Phase 6. The migration adds `swiftPMDependencies {}` alongside the existing CocoaPods setup first, reconfigures Xcode, and only then removes CocoaPods.
| Phase | Action | |-------|--------| | 1 | Analyze existing CocoaPods configuration | | 2 | Update Gradle configuration (repos, Kotlin version) | | 3 | Add `swiftPMDependencies {}` alongside existing `cocoapods {}` | | 4 | Transform Kotlin imports | | 5 | Reconfigure iOS project and deintegrate CocoaPods | | 6 | Remove CocoaPods plugin from Gradle | | 7 | Verify Gradle build and Xcode project build | | 8 | Write MIGRATION_REPORT.md |
---
Phase 1: Pre-Migration Analysis
1.0 Verify the project builds
Before starting migration, identify the module to migrate and confirm it compiles successfully.
1. **Find the module that uses CocoaPods** — look for `build.gradle.kts` files containing `cocoapods`:
grep -rl "cocoapods" --include="build.gradle.kts" .
Extract the module name from the path (e.g., `./shared/build.gradle.kts` → module name is `shared`). Note: multiple modules may use CocoaPods — record all of them. Typically only the module that produces the framework linked into the iOS app needs `swiftPMDependencies`; the others only need CocoaPods removed (Phase 6).
2. **Compile Kotlin code** — run the Kotlin compilation task for that module to verify the Kotlin source compiles:
./gradlew :moduleName:compileKotlinIosSimulatorArm64
Replace `moduleName` with the directory name of the module (e.g., `:shared:compileKotlinIosSimulatorArm64`). This is faster than a full `build` (which also runs release linkage) and sufficient to verify Kotlin code correctness.
3. **Build the iOS app (optional)** — try to locate the Xcode project and build it to confirm the full app compiles:
# Find the Xcode project find . -name "*.xcworkspace" -not -path "*/Pods/*" -maxdepth 2 # Build (replace scheme name with the actual app scheme) cd /path/to/iosApp xcodebuild -workspace *.xcworkspace -scheme "<AppScheme>" -destination 'generic/platform=iOS Simulator' ARCHS=arm64
If the user wants to skip the Xcode build or no Xcode project is found, proceed without it — the Kotlin compilation from step 2 is sufficient to continue.
4. **If the Kotlin compilation fails**, ask the user to either:
- Provide the correct Gradle command to verify the module builds, or
- Confirm the module is in a working state and it's safe to proceed
If the user confirms without providing a build command, **record that the pre-migration build could not be verified** and warn about this at the end of migration (Phase 7).
1.0a Confirm Kotlin version with Swift Import support
Read the current Kotlin version from `gradle/libs.versions.toml` (or `build.gradle.kts`).
**If the project already uses Kotlin 2.4.0-Beta2 or later** → record the version and skip Phase 2.1 (no version change needed).
**If the project uses an older Kotlin version** → Phase 2.1 will upgrade it to `2.4.0-Beta2` (the first public release with `swiftPMDependencies` support, available on Maven Central — no custom repository needed). Warn the user: "⚠️ Kotlin version jump — upgrading across minor versions can introduce breaking changes unrelated to this migration. Recommended: update first, verify it builds, then re-run this migration." If the user confirms, proceed.
1.1 Check for deprecated CocoaPods workaround property
Search `gradle.properties` for the deprecated property:
kotlin.apple.deprecated.allowUsingEmbedAndSignWithCocoaPodsDependencies=true
This property was a workaround (see [KT-64096](https://youtrack.jetbrains.com/issue/KT-64096)) for projects using `embedAndSign` alongside CocoaPods dependencies. It suppresses an error about unsupported configurations that can cause runtime crashes or symbol duplication. After migrating to SwiftPM import, this property is no longer needed and **must be removed** in Phase 6. Record its presence if found.
1.2 Check for EmbedAndSign disablers
Search all `build.gradle.kts` files for code that disables `EmbedAndSign` tasks (e.g., `TaskGraph.whenReady` filters, `tasks.matching` blocks). This is a CocoaPods-era workaround that **breaks the migration** because `integrateEmbedAndSign` (needed in Phase 5) gets disabled too. Record any such code — it **must be removed** in Phase 6, and may need to be removed earlier. See [troubleshooting.md](references/troubleshooting.md) § "`integrateEmbedAndSign` Skipped" for patterns.
1.3 Check for third-party KMP libraries with bundled cinterop klibs
Some KMP libraries ship pre-built cinterop klibs with `cocoapods.*` package namespaces. After migration, the swiftPMDependencies cinterop generator detects these existing bindings and **skips generating new bindings** for those Clang modules to avoid duplicates. This means `cocoapods.*` imports for those modules must be **kept as-is** — they resolve to the third-party library's bundled klib, not to actual CocoaPods.
**Known libraries with bundled `cocoapods.*` klibs:**
| Library | Maven artifact | Bundled klib namespace | Classes provided | |--------
A collection of AI agent skills useful for projects using the Kotlin language. Skills are following the Agent Skills standard, see agentskills.io for more information.
Other skills on kotlin-agent-skills.
- /kotlin-backend-jpa-entity-mapping
Model Kotlin persistence code correctly for Spring Data JPA and Hibernate. Covers entity design, identity and equality, uniqueness constraints, relationships, fetch plans, and common ORM (Object-Relational Mapping) traps specific to Kotlin. Use when creating or reviewing JPA
Open skill - /kotlin-tooling-agp9-migration
Migrates 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
Open skill - /kotlin-tooling-immutable-collections-0-5-x-migration
Migrate Kotlin (and Java) code from kotlinx.collections.immutable 0.3.x / 0.4.x to the latest 0.5.x. The 0.5.x line renames every copy-returning method on PersistentList / PersistentMap / PersistentSet / PersistentCollection to a participial form per KEEP-0459 (add→adding,
Open skill - /kotlin-tooling-java-to-kotlin
Use when converting Java source files to idiomatic Kotlin, when user mentions "java to kotlin", "j2k", "convert java", "migrate java to kotlin", or when working with .java files that need to become .kt files. Handles framework-aware conversion for Spring, Lombok, Hibernate,
Open skill - /kotlin-tooling-native-build-performance
Diagnoses and fixes slow Kotlin/Native compilation and linking in Kotlin Multiplatform projects that target iOS. Use when the user reports slow iOS or shared-framework builds, long linkDebug*/linkRelease* or XCFramework tasks, cold CI builds that re-download the Kotlin/Native
Open skill

