React Native uses CocoaPods for iOS dependency management, but Swift Package Manager (SPM) has been gaining popularity as Apple's official solution. SPM is Apple's first-party dependency manager with native Xcode integration, while CocoaPods is a third-party tool that is expected to become read-only and gradually phased out.
Since React Native 0.75, there's been a solution to integrate SPM packages into React Native applications through the spm_dependency helper. This allows you to add SPM dependencies to your libraries, making it possible to use modern iOS libraries that are distributed exclusively through SPM.
Using SPM packages inside React Native app currently forces the entire iOS project to adopt use_frameworks! :linkage => :dynamic. This can be a drawback for teams that rely on static linking or have performance or binary size sensitivities.In this article, we'll take a look at how you can use SPM packages in React Native for both remote and local packages.
Using remote SPM dependencies
React Native 0.75 introduced the spm_dependency helper method, available in the library podspec. This allows you to declare SPM dependencies alongside your existing CocoaPods configuration:
Pod::Spec.new do |s|
s.name = "MyReactNativeLibrary"
# ... other configuration
spm_dependency(s,
url: 'https://github.com/apple/swift-atomics.git',
requirement: {kind: 'upToNextMajorVersion', minimumVersion: '1.1.0'},
products: ['Atomics']
)
endThis integration enables React Native libraries to consume modern Swift packages that are distributed exclusively through SPM, bridging the gap between the CocoaPods and SPM ecosystems.
Local SPM packages in monorepos
The original spm_dependency helper only worked with remote package URLs. For monorepo setups with local Swift packages, you needed an enhancement:
packages/
├── mobile-app/ # React Native app
├── shared-ui-kit/ # React Native library
└── core-utilities/ # Local Swift SPM packageReferencing core-utilities from shared-ui-kit wasn't possible because the implementation assumed all packages would be fetched from remote Git repositories.
Supporting local SPM packages
We shipped a fix that extends the spm_dependency helper to support local package references alongside remote ones.
This fix is currently in the main branch but not yet released. It will most likely ship in React Native 0.84, since the 0.83 branch was cut before it landed. To use local SPM packages today, you'll need to patch it in yournode_modulesbefore runningpod install. This workaround will no longer be needed once the fix is included in an official React Native release. You can download a ready-to-apply patch from this gist.
Usage in monorepos
With local SPM package support, you can reference Swift packages within your monorepo:
Pod::Spec.new do |s|
s.name = "SharedUIKit"
# ... other configuration
# Reference local SPM package
spm_dependency(s,
url: File.join(__dir__, '../core-utilities'),
requirement: {},
products: ['NetworkingUtils', 'DataModels']
)
endPaths are resolved relative to the podspec file, enabling flexible monorepo structures where React Native libraries can consume local Swift packages.
Under the hood
The SPM integration leverages CocoaPods' Xcodeproj gem to modify Xcode project files. When processing spm_dependency declarations, the system creates different types of package reference objects:
def add_spm_to_target(project, target, url, requirement, products)
if File.exist?(url)
# Create local package reference
package_ref = project.new(Xcodeproj::Project::Object::XCLocalSwiftPackageReference)
package_ref.relative_path = url
else
# Create remote package reference
package_ref = project.new(Xcodeproj::Project::Object::XCRemoteSwiftPackageReference)
package_ref.repositoryURL = url
end
# Link products to target (same for both types)
products.each do |product|
package_product = project.new(Xcodeproj::Project::Object::XCSwiftPackageProductDependency)
package_product.productName = product
target.package_product_dependencies << package_product
end
endThese Xcodeproj::Project::Object classes represent the actual objects stored in Xcode project files. The Xcodeproj gem provides Ruby abstractions for manipulating .xcodeproj files, which are essentially property list files with a specific structure that Xcode understands.
XCLocalSwiftPackageReference: Represents a local Swift package dependency within the project.XCRemoteSwiftPackageReference: Represents a remote Git repository containing a Swift package.XCSwiftPackageProductDependency: Links specific products from a package to build targets.
If you're usinguse_frameworks!in your Podfile with:linkage => :static, you may encounter linker errors when integrating SPM packages. Consider usinguse_frameworks!without explicit linkage (which defaults to dynamic) oruse_frameworks! :linkage => :dynamicfor better SPM compatibility.
Conclusion
While React Native continues to work on migrating to SPM, you can use SPM packages today with your libraries! The spm_dependency helper enables both remote and (soon) local package integration, making it possible to build modern React Native libraries that leverage the Swift ecosystem.

Learn more about iOS
Here's everything we published recently on this topic.
We can help you move
it forward!
At Callstack, we work with companies big and small, pushing React Native everyday.
Release Process Optimization
Ship faster with optimized CI/CD pipelines, automated deployments, and scalable release workflows for React Native apps.
React Native Brownfield
Integrate React Native into existing native application and start sharing code across platforms immediately.
Mobile App Development
Launch on both Android and iOS with single codebase, keeping high-performance and platform-specific UX.
React Native Modules Development
We help teams extend React Native with native modules that meet demanding performance, integration, or device access needs.







