Skip to main content
This guide describes how to migrate the iOS side of an existing React Native application from CocoaPods to Swift Package Manager (SPM). SPM support starts in react-native-moengage 13.0.0. It is experimental and uses React Native’s own SPM support, which requires React Native 0.87 or later. For more information, refer to Experimental Swift Package Manager support for iOS in the React Native 0.87 release announcement. The JavaScript code, SDK initialization, and dashboard configuration remain unchanged.

Migration Scope

Migration is optional for now. CocoaPods is the default for this release, and MoEngage publishes new SDK versions to CocoaPods until December 2, 2026. After that date, new MoEngage SDK versions are available only through Swift Package Manager. SPM support in React Native is experimental in this release, so plan the migration before that date.Migrate only after your application meets the SPM requirements and every other native library in the application supports SPM.

Before You Begin

  • Review the SPM requirements and limitations on the iOS Installation page.
  • Confirm that every other native library in the application supports SPM, either through its own Package.swift or through npx react-native spm scaffold.
  • Identify which extension targets use MoEngage, and whether the application uses the extension integrator tool.
  • Commit or back up the project, including the ios directory.

Step 1: Upgrade React Native and the MoEngage Packages

  1. Upgrade react-native to 0.87 or later.
  2. Upgrade react-native-moengage to 13.0.0 or later, and upgrade any other MoEngage packages in use to the versions from the same release.
  3. Run the following command:
    Bash

Step 2: Remove Manually Declared Pods

Remove every pod declared manually in ios/Podfile, including the MoEngage pods that extension targets usually declare. Pods that are autolinked from npm packages need no change: the next step removes them.
Podfile
In ios/Podfile, delete every line that starts with pod 'MoEngage-iOS-SDK, and remove any MoEngage settings from post_install.
After the migration, no target in the Xcode project can reference a Pods-*.xcconfig file. Both npx react-native spm add and npx react-native spm update scan project.pbxproj for one and stop with an error if they find it, so a single remaining pod breaks every later SPM run.Do not run pod install after migrating. Running it re-adds those references and breaks every subsequent npx react-native spm run, including the runs required after each dependency change.

Step 3: Switch the Project to SPM

From the ios directory, run the following command:
Bash
Use add --deintegrate for this first run. A bare npx react-native spm converts a CocoaPods-integrated project only when the Podfile declares no pods of its own and both Podfile and project.pbxproj are committed without local changes. An application that declares MoEngage pods for its extensions fails that check, and the command stops with an error telling you to re-run it with spm add --deintegrate.
This command replaces pod install. It runs pod deintegrate, removes use_react_native! and use_native_modules! from the Podfile, and sets up SPM in the existing .xcodeproj. It requires CocoaPods on your PATH, and it leaves the .xcworkspace untouched. The initial run takes longer because it downloads and caches React Native’s prebuilt frameworks.
Keep ios/Podfile. The React Native CLI uses it to detect the iOS project, so the migration does not delete it.
From this point onward, open ios/<YourApp>.xcodeproj and use plain npx react-native spm for every later run, as described in Step 5.

Step 4: Update the Push Notification Extensions

If the application uses the extension integrator tool, the only change is the Run Script. react-native-moengage already includes MoEngageRichNotification, so don’t add the apple-sdk package in Xcode.
  1. Replace the CocoaPods Run Script:
    Bash
    with the following script, which works for both regular and archive builds:
    Bash
If the application has its own Notification Service Extension or Content Extension code that imports MoEngageRichNotification:
  1. In Xcode, expand Package Dependencies and note the apple-sdk version.
  2. Go to File > Add Package Dependencies, enter https://github.com/moengage/apple-sdk.git, and set Dependency Rule to Exact Version with that version.
  3. Add the MoEngageRichNotification product to those extension targets only.
  4. After every upgrade of the MoEngage React Native packages, update the Exact Version to match.

Step 5: Update Build Scripts and CI

  • In CI and local scripts, replace pod install with npx react-native spm, run from the ios directory.
  • Run the command after a fresh clone, a node_modules reset, or any dependency change. npx react-native run-ios does not invoke it automatically.
  • Build the .xcodeproj, not the .xcworkspace.

Step 6: Verify the Migration

  1. In Xcode, select Product > Clean Build Folder.
  2. Check that Package Dependencies lists the MoEngage packages, and that ios/Podfile.lock, if present, has no MoEngage entries.
  3. Build and run the application. Confirm that the SDK initialization logs report the expected version.
  4. Select Product > Archive and confirm that it succeeds. This tests the extension targets and the integrator script in a release build.
  5. Send a test push notification. Confirm that the device receives it, that the SDK tracks its impression, and that rich content renders. Verify the cards, inbox, geofence, and personalize modules if the application uses them.

Troubleshooting

For general SPM issues, refer to the SPM section of Troubleshooting and FAQs - React Native.