Migrate Your iOS Project From Carthage To Swift Package Manager

Since Swift 5 and Xcode 11 were released, SPM became a viable dependency manager for many iOS projects. It's also been heavily improved upon in Xcode 12 with the support of binary frameworks and resource files such as storyboards, nibs, localization folders, asset catalogs, and core data models. It's now possible to use it in most if not all iOS projects. And most actively maintained dependencies such as Stream Chat support it.

A Twitter poll showed that, while CocoaPods is number one at 46.5%, 11.4% of iOS developers still use Carthage as their preferred dependency manager. Swift Package Manager, though released most recently, is just behind with 42.1%.

It's clear that SPM, with all its recent updates and deep integration with the official iOS toolchain, will soon take over the other options. In this article, I'll present a process that you can use to fully migrate your projects from Carthage to Swift Package Manager. If you're also interested in migrating from CocoaPods, here's a CocoaPods version of this article: Migrate Your iOS Project From CocoaPods To Swift Package Manager.

Remove Carthage

Unlike CocoaPods, removing Carthage is an entirely manual process. You'll delete files and remove settings in your Xcode projects that reference Carthage. Most of these, you or someone on your team created manually, so what you must change can vary slightly.

Before you remove Carthage, it's important to note each dependency in your project and their versions. In my case, I was only using Stream Chat in version 2.5.0.

Now, let's remove Carthage from your project. After you took note of the contents of your Cartfile, you can remove it alongside Cartfile.resolved and the Carthage folder using the rm -rf command. In my case, I also had an Xcode 12 workaround script called carthage-build.sh that I won't be needing anymore.

Those commands removed all the Carthage-related folders and files but didn't remove the Carthage-related settings in your .xcodeproj.

Now, let's open the Xcode project and remove all frameworks in "Frameworks, Libraries, and Embedded Content" in your targets.

Your .xcodeproj likely contains an additional Build Phase for Carthage to copy the frameworks. You should remove it as well.

After you're done with these steps, you likely removed all Carthage references from your project. There could be more since the usage of Carthage can vary per project. Thank you, Carthage; you've been a good friend. 😢


After you've mourned the loss of Carthage, let's replace it with Swift Package Manager. Hopefully, you've taken notes of all the dependencies you had before.

Open your .xcodeproj, choose the option "Add Package Dependency" in File > Swift Packages, and paste the URL of your dependency's git repository. For example: "https://github.com/getstream/stream-chat-swift".

After pressing next, Xcode will look for the repository and automatically select the latest version tagged. If this version is compatible with the one you were using, you can press next. Otherwise, type the version you were using. After that, Xcode will download the dependency.

A repository may contain multiple targets. If that's the case, you should select only the ones you use.

After you press finish, it's done! Though, you must repeat this process for each dependency you had.

It's possible that a dependency doesn't provide a Package.swift. In that case, it can't be used with Swift Package Manager. However, you can clone the repository and add Package.swift yourself or request the maintainers to do so. For example, see the commit adding SPM support to the Stream Chat iOS SDK.


I hope you were successful in transitioning your project to the future. It's only getting better from now on. If you need any help converting your project from Carthage to Swift Package Manager, feel free to reach out to me on Twitter: @cardosodev.