Sanniv Khare 6 min read

CocoaPods read-only on 2 Dec 2026: an RN iOS dependency audit

CocoaPods read-only on 2 Dec 2026: an RN iOS dependency audit

CocoaPods trunk stops accepting new podspecs on 2 December 2026. Existing builds keep working, so a React Native 0.88 app does not break that morning. What stops is updates: any pod your app pulls from trunk is frozen at whatever version is there. We unpacked eleven common RN iOS libraries from npm on 13 November 2026 and found that only one of them, react-native-mmkv 4.3.2, still pulls a trunk pod (MMKVCore 2.4.0). Firebase already left trunk, and six of the eleven ship a Package.swift.

The takeaway: run pod install, open Podfile.lock, and look at the pods that are not :path => "../node_modules/...". Those are your trunk pods. For each, decide now between a git-pinned podspec, a Swift package, or a different library.

Why we did this: our Beacon-type React Native banking apps are RN CLI projects on CocoaPods, and a security fix that arrives after 2 December has to have a route into the build. This is the audit we ran for them, written up.

What actually freezes on 2 December

From the CocoaPods team’s Trunk Read-only Plan (Orta Therox, November 2024, updated May 2025):

  • “December 2nd 2026: I will switch trunk to not accept new Podspecs permanently.” The post adds that the dates are “not set in stone”.
  • “This will keep all existing builds working.” The Specs repo and its CDN keep serving what is already published.
  • “No new versions or pods will be added to trunk”, so you will not get “any more updates to dependencies which come though CocoaPods trunk”.
  • A test run of not accepting new podspecs was scheduled for 2 to 6 November 2026.

The important word is trunk. A React Native library installed through autolinking is not a trunk pod. use_native_modules! points CocoaPods at the podspec inside node_modules with :path, and a new npm release of that library still reaches you after 2 December. What freezes is everything those podspecs depend on that lives on trunk, plus any pod you list by name in your Podfile.

How we checked

In a Linux container (no Xcode, no Mac, nothing compiled), on 13 November 2026:

  1. npm pack the current release of each library: react-native 0.88.1, react-native-screens 4.30.1, react-native-safe-area-context 5.11.1, react-native-gesture-handler 3.5.0, react-native-reanimated 4.7.1, react-native-worklets 0.13.1, @react-native-firebase/app 27.1.1, react-native-biometrics 3.0.1, react-native-keychain 11.0.0, @react-native-async-storage/async-storage 3.1.1, react-native-svg 15.16.1, react-native-mmkv 4.3.2.
  2. For each tarball: is there a Package.swift? Does package.json declare swiftpmConfig? Which s.dependency lines in the podspec point at a pod that is not React Native’s own (React-Core, Yoga, RCT-Folly and friends, which RN ships as local podspecs)?
  3. Diff @react-native-community/template 0.85.0 against 0.88.1 to see whether the stock Podfile changed.
Terminal card: eleven React Native iOS libraries with version, Package.swift and trunk pod dependencies

Eleven libraries from npm. Six ship a Package.swift; one, react-native-mmkv, depends on a trunk pod.

The results

Library Version Package.swift swiftpmConfig.name Trunk pod deps
react-native-gesture-handler 3.5.0 yes none none
react-native-keychain 11.0.0 yes RNKeychain none
react-native-reanimated 4.7.1 yes none none
react-native-worklets 0.13.1 yes none none
react-native-safe-area-context 5.11.1 yes ReactNativeSafeAreaContext none
react-native-svg 15.16.1 yes RNSVG none
@react-native-firebase/app 27.1.1 CI probe only none none, Firebase comes in through SwiftPM
react-native-screens 4.30.1 no none none
@react-native-async-storage/async-storage 3.1.1 no none none
react-native-biometrics 3.0.1 no none none
react-native-mmkv 4.3.2 no none MMKVCore 2.4.0

The template diff was smaller than expected: between 0.85.0 and 0.88.1 the stock ios/Podfile did not change at all. The iOS changes are in AppDelegate.swift, Info.plist and a new SceneDelegate.swift (the factory moved into the scene delegate, and UIViewControllerBasedStatusBarAppearance flipped to true). So if you upgraded RN and kept your Podfile, you are on the current stock Podfile.

Firebase already left trunk

The library we expected to be the problem turned out to be the one that moved first. @react-native-firebase/app 27.1.1 no longer declares a CocoaPods Firebase dependency. Its podspec calls firebase_dependency, which goes through React Native’s spm_dependency (RN 0.75 and later) and fetches firebase-ios-sdk as a Swift package, inside a CocoaPods build.

Code card: firebase_dependency in firebase_spm.rb raises an error when SPM is disabled, Firebase 13+ is SPM-only

From firebase_spm.rb in @react-native-firebase/app 27.1.1. We only added line breaks.

If your Podfile still sets $RNFirebaseDisableSPM = true, pod install fails with a message that starts “Firebase Apple SDK is no longer distributed through CocoaPods” and asks for use_frameworks! :linkage => :dynamic. The package.json pins Firebase iOS SDK 13.1.1 in sdkVersions.ios.firebase.

What to change, step by step

  1. List your trunk pods. After pod install, every entry under EXTERNAL SOURCES in Podfile.lock with :path is local. Everything under SPEC REPOS: trunk: is from trunk. In our audit set that list held MMKVCore and nothing from the other ten libraries.

  2. Remove the Firebase opt-out. If it is there, delete it:

# Podfile, before
$RNFirebaseDisableSPM = true
use_frameworks! :linkage => :static

# Podfile, after
use_frameworks! :linkage => :dynamic
  1. Give each trunk pod a route that survives 2 December. For MMKVCore the upstream repository has the podspec at its root and a v2.4.0 tag (we checked with git ls-remote and fetched the raw podspec), so a future fix can be taken from git instead of trunk:
# Podfile, before: implicit, from trunk via NitroMmkv.podspec
# (s.dependency 'MMKVCore', '2.4.0')

# Podfile, after: same version, explicitly from git
pod 'MMKVCore', :git => 'https://github.com/Tencent/MMKV.git', :tag => 'v2.4.0'

Bump the tag when a fix ships. This keeps CocoaPods but stops depending on trunk for that pod.

  1. Check swiftpmConfig before you plan a SwiftPM move. React Native 0.88 ships scripts/setup-apple-spm.js (also npx react-native spm). It reads a library’s SwiftPM settings from swiftpmConfig in its package.json:
{ "swiftpmConfig": { "name": "RNSVG" } }

Three of our eleven libraries declare it. For the ones without a Package.swift (screens, async-storage, biometrics, mmkv here), the script has a scaffold action that “Generate[s] Package.swift for community deps that lack SPM support”. npx react-native spm add --deintegrate runs pod deintegrate and strips React Native from the Podfile before it injects the Swift packages. We have not run either on a project yet.

  1. Commit Podfile.lock. With trunk frozen, a lockfile is what keeps two machines on the same versions. Teams that do not commit it should start before 2 December.

What did not break, and what we have not tested

Nothing in this audit needs a code change in the RN libraries themselves: none of the ten others pull a trunk pod. The risk sits in pods you add by name (analytics SDKs, payment SDKs, anything a client asked for) and in their transitive trunk dependencies, which this audit did not cover because they differ per app.

Not run on a Mac yet: no pod install, no Xcode build, no npx react-native spm run. Every claim above comes from the npm tarballs and the CocoaPods post. A build-time comparison of SwiftPM against CocoaPods on the same app is a separate piece of work that needs a Mac.

Sources

Need this built? Let’s talk.

We build and run apps for Mac, TV, mobile and the web, and write about what we learn.