Skip to main content

CocoaPods Read-Only: How to Migrate From CocoaPods to SPM

CocoaPods trunk goes read-only on December 2, 2026. pod install works, but pods stop updating. SPM support for common libraries plus 7 migration steps.

CocoaPods read-only starts on December 2, 2026: trunk then accepts no new pods or versions. Versions already published still install with pod install, so existing projects keep compiling, but their dependencies stop receiving updates. If the project is still in active development, migrate to Swift Package Manager (SPM) one library at a time: check Podfile.lock, remove one pod, add the matching Swift package, build and test on a device, then move to the next. Below are an SPM support table for popular libraries and 7 migration steps.

The CocoaPods Trunk Read-only Plan is the authoritative source for dates and effects. Everything below is as of October 2026.

What changes when CocoaPods goes read-only?

The CocoaPods blog published the plan on November 30, 2024, with this timeline.

When What happens
May 2025 New pods can no longer use the prepare_command field. Existing ones are unaffected
September–October 2026 Another email goes to everyone who has published a Podspec
November 1–7, 2026 A read-only test run
December 2, 2026 Trunk permanently stops accepting new Podspecs

For projects that use CocoaPods, the effect depends on the situation.

Situation After read-only
pod install of versions already published Still works. The blog says the Specs repo and CDN keep running
Upgrading to a new version of a library Library authors can’t publish new versions to trunk, so pod update won’t find them
Libraries from your own spec repo, :path or :git Don’t go through trunk and aren’t affected
All dependencies vendored into the repository Not affected

Many libraries have already moved. Firebase’s migration notice states that it stops publishing new versions to CocoaPods from October 2026, with Firebase 12 as the last major version there. Existing versions can still be installed. Later updates come through SPM or Firebase’s zip distribution, and SPM is the recommended option.

Which projects should migrate to SPM?

Your situation Recommendation
Active development, dependencies need upgrades Migrate to SPM soon, starting with the libraries that update most often
You use Firebase or another SDK that has stopped publishing to CocoaPods Migrate those libraries first
The project rarely changes and only ships occasionally No rush. Keep Podfile.lock pinned and build as usual
A dependency is an older library without SPM support Migrate the others first, keep that one as a pod or switch to an alternative
Only private pods from your own spec repo Not affected by read-only, follow your team’s plan

You don’t have to migrate everything at once. CocoaPods and SPM can coexist in the same project. Migrating one library at a time and building after each one keeps the risk lowest.

Do popular libraries support SPM?

The table shows whether each library’s repository has a Package.swift at its root, and the product name in SPM. Use the URL and product name when you add the package, and check each library’s README for the latest details.

Library SPM URL Product Notes
Alamofire https://github.com/Alamofire/Alamofire.git Alamofire Supported
SDWebImage https://github.com/SDWebImage/SDWebImage.git SDWebImage Supported
Kingfisher https://github.com/onevcat/Kingfisher.git Kingfisher Supported
SnapKit https://github.com/SnapKit/SnapKit.git SnapKit Supported
Firebase https://github.com/firebase/firebase-ios-sdk.git FirebaseAnalytics, FirebaseMessaging, FirebaseCrashlytics, FirebaseAuth and more Supported. Pick a product for each module you use
Lottie https://github.com/airbnb/lottie-spm.git Lottie Supported. The maintainers recommend the small lottie-spm repository
Realm https://github.com/realm/realm-swift.git RealmSwift (Realm for Objective-C) Supported
RxSwift https://github.com/ReactiveX/RxSwift.git RxSwift, RxCocoa, RxRelay Supported
Moya https://github.com/Moya/Moya.git Moya, RxMoya, CombineMoya Supported. Depends on Alamofire, so migrate both together
SwiftyJSON https://github.com/SwiftyJSON/SwiftyJSON.git SwiftyJSON Supported
IQKeyboardManager https://github.com/hackiftekhar/IQKeyboardManager.git IQKeyboardManagerSwift Supported
MJRefresh https://github.com/CoderMJLee/MJRefresh.git MJRefresh Supported
MBProgressHUD https://github.com/jdg/MBProgressHUD.git MBProgressHUD Supported
SVProgressHUD https://github.com/SVProgressHUD/SVProgressHUD.git SVProgressHUD Supported
MMKV https://github.com/Tencent/MMKV.git MMKV Supported
KeychainAccess https://github.com/kishikawakatsumi/KeychainAccess.git KeychainAccess Supported
Google Sign-In https://github.com/google/GoogleSignIn-iOS.git GoogleSignIn, GoogleSignInSwift Supported
Facebook SDK https://github.com/facebook/facebook-ios-sdk.git FacebookCore, FacebookLogin, FacebookShare and more Supported
Masonry — — No Package.swift in the repository. Swift projects can switch to SnapKit, or keep the pod
AFNetworking — — Unmaintained since January 2023. Switch to Alamofire or URLSession
YYModel — — No Package.swift in the repository. Switch to Codable, or keep the pod

For a library not in the table, open its GitHub repository and look for a Package.swift at the root. The README usually describes SPM installation too. Some closed-source SDKs ship only as a pod or for manual integration, so check the vendor’s documentation.

How do you migrate from CocoaPods to SPM?

The example below is a MyApp project built through a .xcworkspace, moving Alamofire from a pod to a Swift package. Before you start, create a branch and confirm the project builds as it is.

1. Take stock of dependencies

Open Podfile.lock, list every pod and its locked version, and mark which ones support SPM using the table above. Watch for dependencies between pods. Moya depends on Alamofire, for example, so migrate them together or you’ll end up with two copies of the same library.

Translate the Podfile version requirements into SPM version rules as follows.

Podfile Meaning SPM version rule
pod 'Alamofire', '~> 5.9' 5.9 or later, below 6.0 From 5.9.0 up to next major version
pod 'Alamofire', '~> 5.9.1' 5.9.1 or later, below 5.10 From 5.9.1 up to next minor version
pod 'Alamofire', '5.9.1' Exactly this version Exactly 5.9.1

Use the version locked in Podfile.lock while you migrate. Upgrade separately once the migration builds, so it’s easy to tell what caused any problem.

2. Remove one pod

Delete or comment out the line in the Podfile, then reinstall in the folder that contains the Podfile.

1target 'MyApp' do
2  use_frameworks!
3  # pod 'Alamofire', '~> 5.9'
4  pod 'SDWebImage'
5end
1pod install

3. Add the Swift package

When you use KXBuild on Windows, Linux or macOS, pick either approach.

  • VS Code extension. Run KXBuild: Add Swift Package Dependency… from the Command Palette, or right-click the MyApp target in the KXBuild view and choose it. Enter the package’s Git URL, then choose the version rule and the Alamofire product.
  • Command line. Run the command below in the project folder. Pass the .xcodeproj to -P, not the .xcworkspace.
1kxbuild project add-package -P .\MyApp.xcodeproj -t MyApp --url https://github.com/Alamofire/Alamofire.git --from 5.9.0 --product Alamofire

Use --exact 5.9.1 for an exact version and --up-to-next-minor 5.9.1 for up to the next minor version. For other options, see project add-package. Adding a package needs a network connection. If the product name is wrong or resolution fails, the project is left unchanged.

4. Update imports and code

For most libraries the module name is the same as the pod, so import Alamofire and import Kingfisher stay as they are. Check these cases.

  • SDKs split into modules. Firebase and similar SDKs ship several products in SPM. Import the products you use, such as import FirebaseCore and import FirebaseAnalytics.
  • Libraries with a different product name. IQKeyboardManager’s product is IQKeyboardManagerSwift, and Realm’s Swift API is RealmSwift. Import the module that matches the product.
  • Objective-C headers. #import <SDWebImage/SDWebImage.h> usually still works, or you can switch to @import SDWebImage;.

Build once after the changes. While the Pods folder is still there, keep building the .xcworkspace.

1kxbuild build .\MyApp.xcworkspace -D CODE_SIGNING_ALLOWED=NO

5. Handle resource bundles

With pods, some code looks up a library’s resource bundle in the app by name, for example Bundle.main.path(forResource: "XXX", ofType: "bundle"). With SPM the bundle’s name and location change, so this code returns nil. Icons or localized text disappear from the UI, or the app crashes at runtime.

  • Search the project for forResource: and .bundle to find code that reads third-party resources.
  • Prefer the library’s public API over building bundle paths yourself.
  • In your own local packages, read package resources with Bundle.module. This property is only available in the package’s own code.

6. Build, test on a device, commit

Once it builds, press F5 to install on your phone and try every feature that uses the library. If you get unrecognized selector after launch, an Objective-C library’s categories probably weren’t linked. CocoaPods adds -ObjC to the project by default, so after migrating add it to the target’s Other Linker Flags, either in the Project Settings Editor or with the command below.

1kxbuild project add-setting -k OTHER_LDFLAGS -v '$(inherited),-ObjC' -a -t MyApp -P .\MyApp.xcodeproj

If everything works, commit the change, including the Podfile, Podfile.lock, project.pbxproj and the Package.resolved that SPM generates. Then go back to step 2 for the next library.

7. After the last pod

Remove CocoaPods completely only after every pod has become a Swift package. Don’t delete Pods or the workspace earlier, because other libraries still use them.

  1. Run pod deintegrate in the folder with the Podfile. It removes the build phases and settings CocoaPods added to the project.
  2. Delete the Podfile, Podfile.lock and the Pods folder.
  3. If the workspace contains only MyApp.xcodeproj and Pods, delete MyApp.xcworkspace. Keep it if it contains other projects.
  4. In the KXBuild view, switch the startup project to MyApp.xcodeproj, and change .xcworkspace to .xcodeproj in your build and CI scripts.
1kxbuild build .\MyApp.xcodeproj -c Release

In CI, add --only-use-versions-from-resolved-file so the build uses exactly the versions in Package.resolved. See Build and configure for the options.

Can CocoaPods and SPM be mixed?

  • Keep one source per library. If a library is both in the Podfile and added as a Swift package, you get duplicate symbols or two instances at runtime. Indirect dependencies count too, for example Moya as a pod brings in Alamofire.
  • Build the .xcworkspace while you mix them. Swift packages are added to the .xcodeproj and resolved together when you build from the workspace.
  • Run pod install after every Podfile change, then build.
  • Migrate one library at a time. If something breaks, revert a single commit instead of digging through a pile of changes.

What about Flutter and React Native projects?

Flutter. According to Flutter’s Swift Package Manager guide for app developers, SPM support is on by default from 3.44, and running the app after upgrading Flutter adds SPM integration automatically. If some plugins in the project don’t support SPM yet, Flutter falls back to CocoaPods for those plugins, so run pod install in the ios folder as usual. See Flutter iOS builds. The Flutter docs also note that turning SPM off won’t be allowed in the future, so leave it on and upgrade plugins to versions that support SPM over time.

React Native and Expo. On iOS, native dependencies are still installed through the Podfile in the ios folder. Follow the official React Native and Expo updates for how to move off CocoaPods after read-only, and don’t swap Pods for Swift packages yourself before they publish a plan. For everyday builds, see the React Native stack page.

FAQ

Does pod install still work after CocoaPods goes read-only?

Yes. Versions already published to trunk still install, and existing projects that build from Podfile.lock aren’t affected. What changes is that library authors can’t publish new versions to trunk, so you won’t get later updates.

When does CocoaPods trunk become read-only?

According to the plan on the CocoaPods blog, trunk permanently stops accepting new Podspecs on December 2, 2026, after a read-only test run from November 1 to 7.

Do I have to replace every pod with a Swift package?

No. Migrate libraries you still develop against and need to upgrade. Older projects that no longer change can keep a pinned Podfile.lock. Libraries without SPM support can stay as pods, since both can coexist in one project.

What do I do about “no such module” after migrating?

Check that the package was added to the target you’re building, that you picked the right product, and that the import uses the product’s module name, such as IQKeyboardManagerSwift or FirebaseAnalytics. While you still use Pods, build the .xcworkspace. If the error persists, run kxbuild project resolve .\MyApp.xcworkspace --force to resolve dependencies again.

Do I need to migrate a Flutter project to SPM myself?

Not by hand. SPM is on by default from Flutter 3.44, running the app after upgrading Flutter adds it automatically, and plugins without SPM support fall back to CocoaPods. Your part is upgrading plugins to versions that support SPM.