Kotlin Multiplatform's Swift Package Manager import is in Alpha per the Kotlin docs. If you try it, commit the generated .swiftpm-locks directory with its Package.resolved files, and pick version specifiers on purpose. That keeps the iOS side of a shared module reproducible, as the Gradle side already is.
What the feature does
SwiftPM import lets Kotlin code in iosMain and similar source sets use Objective-C APIs from Swift packages. Dependencies are declared in a swiftPMDependencies block in the Gradle build file, next to the Apple targets. The docs state that the feature needs a Kotlin Multiplatform Gradle plugin version of 2.5.0-Beta1, and that exporting a module that uses it as a Swift package is not yet supported. Check the current status before relying on it, since alpha features change.
kotlin {
iosArm64()
iosSimulatorArm64()
swiftPMDependencies {
swiftPackage(
url = url("https://github.com/firebase/firebase-ios-sdk.git"),
version = from("12.5.0"),
products = listOf(product("FirebaseAnalytics")),
)
}
}
Version specifiers are security decisions
| Specifier | Meaning per the docs | Reproducibility |
|---|---|---|
| from | Starting at the given version, like a Gradle require | Can float upward within the package rules |
| exact | Exactly that version, like a Gradle strict | Fixed |
| branch | A specific Git branch | Moves with the branch |
| revision | A specific Git commit | Fixed |
A branch specifier follows whatever the branch contains today. Prefer exact or revision for anything that ships, and treat from as a floor rather than a pin.
Commit the lock files
The docs say Package.resolved files are generated under .swiftpm-locks to keep builds reproducible, and recommend committing the whole directory. Treat them like any lockfile: review diffs, and expect a pull request that changes a resolved revision to deserve a look. The generic reasons are in what a lockfile stops and what it cannot.
Steps to adopt carefully
- Confirm your Kotlin plugin version supports the feature and read the current status.
- Add dependencies with exact or revision specifiers.
- Run the integration task once as documented, and commit the generated package and the updated Xcode project.
- Commit .swiftpm-locks.
- Add the lock files to dependency scanning, because they list the real resolved revisions.
- Review the known limitations before shipping, for example linker issues with dynamic frameworks.
Where this fits with CocoaPods
Some projects still use the Kotlin CocoaPods plugin, which involves the CocoaPods tool and a podInstall Gradle task. The Kotlin docs link to SwiftPM as an alternative, so it is worth knowing which one a project uses before you scan it. Either way, the iOS packages are separate from the Gradle graph. See how to list every dependency in an iOS app.
Try it yourself
Click through it at your own pace, or open it full screen.
See how a dependency you already scanned can become a finding later. A pinned iOS package is not a safe one forever.
Safeguard's dependency scanning and continuous monitoring watch your inventory as new advisories appear, and the free scan is at gold.safeguard.sh/scan.
Quick check
Is SwiftPM import for Kotlin stable?
The Kotlin docs label it Alpha. Check the current documentation before depending on it in production.
Should I commit the swiftpm-locks directory?
Yes. The docs recommend committing the whole directory so Package.resolved files keep builds reproducible.
Sources
Last reviewed: 19 October 2026.