You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cocoapods is slated to be EOL in December 2026. Creating this issue as a reminder to investigate what's needed to transition fully to Swift Package Manager.
@mateuuszzzzz would you be interested in helping to supervise this? With your experience in the cocoapods/prebuilt binaries, I think you'd be a good fit.
There's no single umbrella tracking issue in the React Native repo itself. Upstream tracking lives in react-native-community/discussions-and-proposals, and the plan of record is RFC0994: Swift Package Manager Support for React Native iOS Projects — open since 2026-04-21, authored by chrfalch (Callstack), explicitly framed around the December 2026 CocoaPods deprecation.
The RFC / plan of record. Covers core packaging (prebuilt XCFrameworks + headers-only SPM products), autolinking, Codegen, an npx react-native spm CLI with add --deintegrate for existing Podfile apps, and the adoption strategy.
The long-running community discussion (open since Jan 2023, 80+ comments). This is where the vendor CocoaPods-EOL notices land — Firebase (no new CocoaPods releases after Oct 2026), Google Maps, reCAPTCHA.
Implementation is already landing, not just proposed. Note the repo moved: it's now react/react-native, not facebook/react-native.
Current upstream status
SwiftPM commits are landing on main right now, e.g. Derive an SPM library's Swift name from its podspec (#58290), landed 2026-09-09. RN closes these PRs via the Meta importer, so GitHub shows them as "closed" rather than "merged" — check main's commit log for the real state.
An experimental SwiftPM path exists as of 0.87 — see #57917 (Hermes bytecode mismatch on 0.87 SwiftPM release builds, since closed) and #58359 (SPM setup generates set -euo pipefail scripts but runs them with /bin/sh, still open).
Open workstreams: #52909 (build from source with SwiftPM), #53529 (build HelloWorld from source), #58084 (docs).
Adoption strategy from the RFC: opt-in first, CocoaPods and SPM supported in parallel for several releases, SPM becomes the default for new apps only "after ecosystem readiness is high enough," and existing apps are not expected to migrate immediately. There is no committed date beyond the Dec 2026 CocoaPods read-only deadline — a direct timeline question to cipolleschi on Update version to 1.0.1-92 #587 (2026-06-22) is still unanswered.
So the heavy lifting you were hoping for is in progress. The practical read for us: subscribe to #994 and #587, and the thing that will actually gate us is third-party library readiness — every native dep we use needs a Package.swift or SPM metadata, and the RFC pushes that onto library authors during the transition.
Next Steps: Reply with @MelvinBot <your feedback> to refine this.
No update from me on our side, but I see RN 0.87 introduced experimental SwiftPM support and recent release notes show a lot of development around SwiftPM support in React Native
CocoaPods → SwiftPM: dependency and migration scope
Bottom line: This is a migration of two iOS projects and the React Native/Expo build machinery, not just a replacement of the explicit pod lines. The production mobile build is the HybridApp. Its legacy native dependencies and notification extension are additional to the autolinked NewDot native modules. A realistic first milestone is an experimental, non-production hybrid build on RN/Expo versions with SwiftPM support, not a production cutover on December 2.
Upgrade our RN 0.86 / Expo 57 stack to a compatible RN/Expo SPM-preview combination, and replicate our patched prebuilt RN/Hermes artifacts and source-build fallback.
Finish/consume the still-open Nitro, RN Firebase, permissions and other RN bridge work; native SDK manifests alone don't migrate those bridges. Several apparently finished upstream PRs are not yet in a published npm version we can use.
Address HybridApp-specific native gaps: AFNetworking's pinned SPM package omits UIKit categories we use, Material Components is archived, and several legacy/forked pods need packaging or replacement. Preserve the notification extension and proprietary SDK tooling.
Port CocoaPods-specific build phases/CI and validate release parity. Some legacy dependencies can be investigated or migrated independently, but full removal depends on the complete graph and duplicate-free linkage.
“Direct” below means every literal entry under either lockfile's DEPENDENCIES, including autolinked Expo/RN modules and generated RN pods, not just manually written pod calls. There are 157 standalone entries, 190 hybrid entries, 191 distinct entries: 76 RN core/generated entries, 22 Expo entries, 37 explicitly declared native/extension entries, and 56 other RN/first-party entries. All are accounted for below. Transitive pods are discussed where they affect a direct package, not counted as direct packages.
B = in both locks, S = standalone only, H = hybrid only; versions are lockfile versions. Appduct is an additional conditional debug native dependency in current package.json/autolinking config but absent from both locks, so it is included separately rather than counted in 191. The two locks disagree on callstack-repack and AirshipServiceExtension; the hybrid lock also includes three Expo entries excluded in App's current expo.autolinking config. Re-resolve both configurations before relying on the exact graph; a lockfile entry is not proof of runtime use.
Upgrade to SPM?true means a stable, published version of the actual package (including the pinned version, when no upgrade is needed) offers SPM for the product we use. Expo preview-plugin source generation/binaries and RN preview support count. It does not promise a drop-in build for our app. false includes unverified support, unreleased/preview-only library versions, or cases requiring an owned fork/patch to retain our changes.
Deprecated/archived/abandoned?true means the consumed repository is archived/explicitly deprecated, or its default branch has had no commit since 2023-11-10 (a staleness proxy, not proof a maintainer abandoned it); links on true show the archive or last commit. For forks this evaluates the source we consume, even where the parent is active. false means no such evidence was found, not that maintenance is guaranteed; the proprietary Group-IB vendor status is unverified.
A manifest in a repo or npm tarball is not proof it builds with our configuration. “Pinned manifest” means I checked the locked version; “merged” is not the same as published or present in our pin. “No tracker found” means my upstream search found none, not that no issue exists. This is a source/lockfile/npm/upstream review, not a successful SwiftPM build.
Explicit native and extension pods
Direct pod (locked; scope)
Upstream status and next step
Upgrade to SPM?
Deprecated/archived/abandoned?
ActionSheetPicker-3.0 2.3.0; H
2.8.0 has a manifest, but our tag does not. Evaluate upgrading; test picker presentation and appearance.
true
false
AFNetworking 4.0.1; H
Pinned manifest covers core only; our app also imports UIImageView+AFNetworking and AFNetworkActivityIndicatorManager. UIKit SPM PR is open in the archived repo. Fork/package the UIKit categories or replace their uses; validate networking, uploads, reachability, and TrustKit.
Both locked releases have an AirshipNotificationServiceExtension product (19.10, 20.0). Link it to each notification extension, and reconcile its version with the app's Airship 20.8.1 dependency.
true
false
AppLogs 0.1.0; B
No SPM tracker found in react-native-app-logs. Package the AppLogsPod sources as an independent product linked to the extension; coordinate with the RN wrapper below and verify extension-safe logging.
false
false
CropViewController 2.5.2; H
Pinned tag has no manifest; 2.8.0 has one. Evaluate upgrading and upstream SPM issues, including localized resources and crop behavior.
true
false
CryptoSwift 1.3.2; H
Pinned manifest. Link the product and test existing encrypted data. Beware the SwiftLint SPM graph's newer CryptoSwift requirement.
true
false
DTCoreText 1.6.25; H
Our fork's tag lacks a manifest; upstream 1.6.26 supports SPM, but our fork has a custom image fix. Port/reconcile it; the consumed fork is stale although upstream is active. Preserve DTFoundation and default.css resources.
Pinned Gzip product; link it to the notification extension, preserve zlib linkage and test decompression.
true
false
INTULocationManager 4.3.0; H
No tracker/manifest found in upstream. Package the Objective-C sources or replace with CLLocationManager; preserve one-shot, continuous, cancellation, and permission behavior.
MaterialComponents/TextFields+Extensions 54.13.0; H
Same archived Material Components dependency; separately preserve text-field behavior and its MDFInternationalization/resource dependencies, or replace the controls.
No tracker/manifest found in upstream. Package the pinned commit or replace the legacy indeterminate overlay with UIKit; test dismissal and accessibility.
No tracker/manifest found in upstream. Package the category or use CommonCrypto while preserving exact existing digest/encoding semantics; do not introduce MD5 for new security uses.
Pinned PusherSwift manifest includes TweetNacl and NWWebSocket. Unify it with the RN wrapper's Pusher dependency; verify encrypted channels and avoid duplicate frameworks.
Our AtomicSLLC fork's tag lacks a manifest; its parent merged SPM support. Port that manifest into our fork without losing its changes, or replace the menu.
Upstream is archived; no SPM tracker found. Package the Obj-C sources or replace with Security.framework, preserving service/account/accessibility and existing persisted credentials.
Our fork has a manifest on its default branch, not at v1.7.0 (fork). Port/tag it or replace; account for the SwiftGif product/module name and test GIF decoding.
Pinned plugin/executable manifest. This is a build tool, not app runtime code: replace the ${PODS_ROOT}/SwiftLint/swiftlint phase with a pinned plugin/binary. Its SPM graph asks for CryptoSwift ≥1.7.2, which can conflict with our 1.3.2 pin; a separately installed binary avoids that graph conflict.
true
false
SwiftMessages 9.0.4; H
Pinned manifest processes resources; test banners, bundle copying and signing.
true
false
TagListView 1.4.0; H
Our fork's tag lacks a manifest; archived upstream's 1.4.1 has one, but our fork includes custom image support. Reconcile or port it rather than dropping those changes.
No manifest in pinned tag; SPM request open. Package its sources/dependencies or evaluate an SPM ZIP library; test existing archive formats, compression and extraction.
These are direct CocoaPods entries generated by RN autolinking. The native vendor SDK supporting SPM is not by itself SPM support for the RN bridge. “Scaffold” means try RN's podspec-to-manifest generator, inspect/patch the result, and upstream it; mixed Swift/Obj-C++ targets, scripts, binary dependencies and codegen often need manual work.
Direct pod (locked; scope)
Upstream status and next step
Upgrade to SPM?
Deprecated/archived/abandoned?
callstack-repack S 5.4.1 / H 5.3.0; B
No SPM tracker found in Re.Pack. Align lockfiles; scaffold/port the native bridge, JWTDecode/SwiftyRSA dependencies and codegen; verify bundle loading.
false
false
expensify-react-native-background-task 0.0.0; B
Our local module; no upstream tracker. Author a local SPM target and codegen/autolinking metadata; test background tasks.
false
false
ExpensifyNitroUtils 0.0.1; B
Our podspec mixes Swift/Obj-C++/C++ and Nitrogen output. Depends on Nitro SPM; generate or author separate targets, preserving Folly flags and registration.
false
false
fullstory_react-native 1.10.2; B
RN SPM PR merged, but the checked 1.10.2 and latest 1.10.3 npm tarballs do not contain a manifest. Await a published version or backport; coordinate with the FullStory SDK/uploader above.
false
false
group-ib-fp 2.6.0; B
Our podspec vendors three XCFrameworks. No public SPM tracker found: ask Group-IB about SPM distribution/licensing, or wrap local binary targets plus our mixed-language bridge; verify device/simulator slices and fraud signals.
false
false
lottie-react-native 7.3.8; B
SPM PR merged; 7.5.0 ships a manifest, but it declares lottie-spm while its target names the package lottie-ios. Verify/patch that identity, link native Lottie 4.6.0 and retain privacy resources.
No RN-bridge SPM tracker found in Onfido; the vendor expects support through June 2027. Native Onfido has SPM; vendor's Entrust migration guide describes a newer, SPM-only native SDK and a breaking RN migration. Verify bridge support and run security review: the guide lists SDK certificate pinning as not yet released.
false
false
pusher-websocket-react-native 1.3.1; B
No bridge SPM tracker found in upstream. Split/package the mixed Swift/Obj-C bridge against the same Pusher product used by OldDot; test encrypted and normal channels.
false
false
QuickCrypto 1.1.6; B
OpenSSL SPM build fix addresses an earlier integration, not evidence this pinned RN/Nitro bridge supports a pod-free build. Port it with Nitro and a supported OpenSSL XCFramework/package; test signing/encryption and device embedding.
false
false
react-native-advanced-input-mask 1.4.6; B
No SPM tracker found in upstream. Split Swift/Obj-C, explicitly package ForkInputMask 7.3.3 and new-architecture flags; test masks and editing.
false
false
react-native-airship 26.7.0; B
SPM PR merged; npm 27.0.0 includes a manifest, 26.7.0 does not. Evaluate upgrade and align extension/native SDK versions; Airship notes RN 0.87's iOS-floor limitation is fixed in 0.88.
true
false
react-native-app-logs 0.3.1; B
No tracker found in upstream. Package the mixed-language RN bridge and share the AppLogs native product with the extension; test logging from both processes.
false
false
react-native-blob-util 0.24.12; B
SPM name fix merged; npm 1.1.1 includes a manifest, our pin does not. Evaluate major-version compatibility or backport; test file transfers and privacy resource.
true
false
react-native-cameraroll 7.4.0; B
No SPM tracker found in upstream. Scaffold/port its native sources and codegen; test photo permissions, selection and saving.
false
false
react-native-config 1.5.3; B
SPM autolinking plugin PR open. Preserve our per-configuration ENVFILE and generated config; test Debug/AdHoc/Release and incremental env changes.
false
false
react-native-document-picker 10.1.3; B
Mixed-language SPM PR merged; checked npm 12.0.3 still lacked a manifest. Await a release or backport its separate targets/shims; test pick and copy.
No tracker found in our upstream. Scaffold/author the native target and codegen integration; test iPad/hardware shortcuts.
false
false
react-native-keyboard-controller 1.22.4; B
SPM issue and PR open. Adopt/backport and test keyboard layout/animation with our navigation.
false
false
react-native-netinfo 11.4.1; B
SPM PR open. Adopt or scaffold/backport; test connectivity transitions.
false
false
react-native-pager-view 9.0.4; B
SPM PR merged; npm 10.0.0 contains ios/Package.swift, our pin does not. Evaluate major upgrade and SwiftUIIntrospect dependency; test paging/gestures.
true
false
react-native-pdf 7.0.2; B
SPM PR open. Adopt/backport; test PDF rendering and blob/file dependencies.
false
false
react-native-plaid-link-sdk 12.5.3; B
No RN-bridge SPM tracker found in upstream. Native Plaid has an SPM distribution; split the mixed bridge and link a compatible Plaid product once, then test bank-link flows.
false
false
react-native-quick-base64 3.0.1; B
Scaffold PR closed unmerged. Use it as a starting point for an owned/upstream manifest; test byte-for-byte encoding.
false
false
react-native-safe-area-context 5.9.1; B
SPM PR merged; npm 5.11.1 has a manifest, ours does not. Upgrade/backport and verify insets/navigation.
true
false
react-native-skia 2.11.2; B
SPM PR merged; npm 2.14.0 has a manifest, ours does not. Align Skia XCFrameworks, header flags and renderer mode; test canvas/charts and release archives.
true
false
react-native-view-shot 5.1.0; B
SPM PR merged; npm 6.2.1 has a manifest, ours does not. Upgrade/backport and retain privacy bundle; test image capture.
true
false
react-native-wallet 0.1.41; B
No tracker found in our upstream. Author mixed Swift/Obj-C++ targets with codegen and PassKit linkage; test card provisioning.
false
false
react-native-webview 16.0.0; B
SPM PR open, tested against our 16.0.0 sources upstream. Adopt/backport, including Folly flags; test WebViews and native messaging.
false
false
ReactNativeBiometrics 0.15.0; B
No SPM tracker found in upstream. Scaffold/port native sources and LocalAuthentication/Security linkage; test biometrics and cancellation.
false
false
ReactNativeHybridApp 0.0.0; B
Our podspec. Preserve the hybrid Podfile's special removal of the module implementation because Mobile-Expensify compiles its own implementation; avoid duplicate symbols and test transitions/auth handoff.
false
false
RNAppleAuthentication 2.5.0; B
No SPM tracker found in upstream. Scaffold/port the Obj-C bridge and AuthenticationServices linkage; test Apple sign-in and callbacks.
false
false
RNCClipboard 1.16.3; B
SPM PR open. Adopt/backport and test pasteboard and extension/framework linkage.
false
false
RNCPicker 2.11.3; B
SPM PR open. Adopt/backport, preserving generated component metadata; test selection.
false
false
RNDeviceInfo 10.3.1; B
SPM PR open. Adopt/backport and verify device info/privacy declarations.
false
false
RNFBAnalytics 22.2.1; B
Pod-free RN SwiftPM plugin PR open. Native Firebase already has SPM, but the plugin must map Analytics products/options and generated script phases; test event collection.
SPM PR merged; npm 3.5.0 has a manifest, ours does not. Upgrade/backport and test navigation gestures.
true
false
RNGoogleSignin 10.0.1; B
SPM PR merged; npm 17.0.0 has a manifest, ours does not. Evaluate major upgrade, native GoogleSignIn product and redirect handling; also reconcile the hybrid Expo adapter.
true
false
RNLiveMarkdown 0.1.371; B
No SPM tracker found in our upstream. Package C++/Obj-C++ with RNWorklets, RN headers and version flags; test rich-text editing and selection.
false
false
RNLocalize 3.5.4; B
SPM PR open. Adopt/backport and test locale/time-zone changes.
false
false
rnmapbox-maps 10.3.10; B
Mapbox SPM integration PR still builds the RN wrapper as a pod; it does not prove pod-free RN support. Port the mixed bridge and Mapbox/Turf products; preserve authentication, pre/post-install effects and exactly-once framework embedding/signing.
false
false
RNNitroSQLite 10.2.0; B
SPM PR open, dependent on Nitro V1. Preserve threadSafe/performanceMode and SQLite flags; test database migration, writes and offline behavior.
false
false
RNPermissions 5.4.0; B
SPM plugin PR open. Replace setup_permissions with equivalent config for Camera, Contacts, LocationAccuracy, LocationAlways, LocationWhenInUse; Contacts requires a separate Swift target. Test prompts and privacy manifest.
false
false
RNReactNativeHapticFeedback 2.3.3; B
SPM PR open. Adopt/backport and test haptic feedback.
false
false
RNReanimated 4.7.0; B
SPM support merged; our npm tarball already has a manifest. Validate feature flags, C++/Hermes ABI and RNWorklets together on the new RN version.
true
false
RNScreens 4.28.0; B
SPM PR merged, but stable npm 4.30.1 still lacks a manifest; 5.0.0-beta.1 has one. Await a stable version or evaluate the beta/backport; preserve our gamma flag and test navigation.
false
false
RNSentry 8.32.0; B
SPM support merged; our npm tarball contains a manifest for RN 0.87+. Validate prebuilt Sentry, debug-symbol upload and static/header linkage in both builds.
true
false
RNShare 11.0.2; B
SPM PR merged, but checked npm 12.3.1 lacks a manifest. Await release/backport; test share sheets and generated headers.
SPM support merged; our npm tarball has a manifest. Validate feature flags and compatibility with Reanimated, Expo worklets and LiveMarkdown.
true
false
VisionCamera 5.2.3; B
No module-specific tracker found in upstream. Depends on Nitro and NitroImage; package generated Swift/C++ targets and AVFoundation, then test capture, permissions and our processor configuration.
false
false
Appduct 0.16.0; conditional S/H, not in either lock
The native core has SPM, but the checked RN 0.16.0 npm tarball has no bridge manifest. Ask upstream or package its Swift/Obj-C bridge; preserve our debug-configuration autolinking and verify it is not inadvertently included in release.
false
false
Expo autolinked pods
We are on Expo SDK 57 / RN 0.86. Expo SDK 58 pairs RN 0.88 with a preview SwiftPM plugin: plugin, 28 source manifests. Upgrade the SDK as a coherent set, then validate every module below; don't assume the current 57 packages are already consumable pod-free.
Direct pod (locked; scope)
Upstream status and next step
Upgrade to SPM?
Deprecated/archived/abandoned?
EXConstants 57.0.7; B
Expo plugin; preserve the app.config generation phase and privacy bundle. Resolution fix open.
true
false
Expo 57.0.8; B
Adopt the Expo SPM plugin; regenerate module provider and project script phases.
true
false
ExpoAdapterGoogleSignIn 10.0.1; H
Reconcile this hybrid-only lock entry with App's Expo exclusion. The Google sign-in SPM work exports the RN bridge, not this Expo adapter; upgrade-only support for the adapter is unverified.
false
false
ExpoAsset 57.0.7; B
Included in Expo manifest work; upgrade and test bundled/downloaded assets.
true
false
ExpoAudio 57.0.3; B
Expo plugin; npm 58.0.11 still has mixed sources and no shipped manifest/prebuilt artifact, so upgrade-only support is unverified. Verify AVFoundation, recording/playback and background audio.
false
false
ExpoDomWebView 57.0.1; B
Expo plugin; verify its DOM/WebView registration and resources.
true
false
ExpoFileSystem 57.0.1; H
Hybrid lock only despite current App exclusion; re-resolve. npm 58.0.13 ships prebuilt SPM artifacts; the source manifest PR is open. Preserve privacy manifest and test file access.
Expo plugin; separately resolve SDWebImage and AVIF/SVG/WebP codec products, then test image formats.
true
false
ExpoImageManipulator 57.0.6; B
Expo plugin; retain SDWebImageWebPCoder and test image transformations.
true
false
ExpoKeepAwake 57.0.1; H
Hybrid lock only despite current App exclusion; re-resolve. Included in Expo manifest work; verify awake behavior if retained.
true
false
ExpoLocation 57.0.6; B
Expo plugin; npm 58.0.20 still has mixed sources and no shipped manifest/prebuilt artifact, so upgrade-only support is unverified. Preserve CoreLocation and foreground/background permissions.
false
false
ExpoLogBox 57.0.1; B
Expo plugin; verify development diagnostics and configuration-specific linking.
Its checked-in build manifest still reads PODS_ROOT and builds an XCFramework via a pod phase; Expo plugin must replace this integration. Test Hermes/JSI headers and build flavors.
true
false
ExpoModulesWorklets 57.0.15; B
Expo plugin; preserve C++/Swift and RN worklets linkage/registration.
true
false
ExpoModulesWorkletsAdapter 57.0.15; S
Standalone-only in current locks; Expo plugin. SDK 58 marks this adapter source-only but ships no adapter artifact or manifest; verify plugin support and RNWorklets compatibility.
Expo plugin; npm 58.0.13 still has mixed sources and no shipped manifest/prebuilt artifact, so upgrade-only support is unverified. Preserve UMAppLoader, background registration and privacy bundle; test background launch.
false
false
ExpoVideo 57.0.2; B
npm 58.0.13 ships prebuilt Debug/Release SPM artifacts for the Expo plugin; source-manifest work was deferred. Test playback/background audio.
true
false
ExpoWebBrowser 57.0.2; B
Included in Expo manifest work; test auth/browser dismissal and redirects.
true
false
UMAppLoader 57.0.1; B
Expo plugin; npm 58.0.2 is Obj-C with no shipped manifest/prebuilt artifact, so upgrade-only support is unverified. Check it remains wired to TaskManager under SPM.
false
false
React Native core and generated pods
All 76 entries below appear in both locks and are part of the same RN/Hermes/codegen migration, rather than 76 independent third-party libraries. RN RFC / community tracker: upgrade from RN 0.86 to a supported SPM-preview version, regenerate headers/codegen/autolinking and validate prebuilt React, dependencies and Hermes. RN 0.87 explicitly says its SPM path is experimental and not for production. The following table names every direct entry so none are hidden by the grouping.
Baseline and risk containment: regenerate each pod graph after a clean npm install; decide how to keep receiving vendor updates while trunk is read-only. Keep CocoaPods and an independently buildable release path until the SPM build is proven; avoid resolving/linking the same vendor SDK through both managers in one target. The current RN spm_dependency bridge can help a particular native SDK, but still leaves CocoaPods and can conflict with our static-framework setup.
Upgrade/platform prototype: first evaluate RN 0.88 + Expo 58 together, including Strict TypeScript/API migration. Use a disposable branch and explicitly target the hybrid iOS/Expensify.xcodeproj and standalone ios/NewExpensify.xcodeproj; validate npx rock config -p ios/custom config command, codegen, Expo module-provider generation, new-architecture flags and permissions. Prototype without assuming --deintegrate handles our custom targets/hooks automatically.
Prebuilt RN artifacts are a separate high-risk workstream:our CocoaPods hook selects authenticated, patch-hash-matched debug/release RN artifacts, dSYMs and a source-build fallback. Replicate that for SPM's React/Hermes/dependency binaries and header companions, caching, authentication, flavor selection and symbolication. The RFC says its current prototype is prebuilt-only, so our source fallback needs a separate plan.
Port build behavior, not just packages: replace Podfile pre/post-install hooks, PODS_ROOT header paths, static-framework overrides, Expo configure phase, react-native-config generation, FullStory uploader, RNFB plist phase, SwiftLint path, resource-copy/embed/sign phases and the hybrid duplicate-implementation workaround. Preserve per-target extension dependencies and avoid incompatible package versions/duplicate binaries. Update iOS CI pod caches/install, prebuilt-lock checks, local scripts and Package.resolved/artifact caching.
Release gate: clean checkout and incremental builds for both projects, Debug/AdHoc/Release, simulator and real device, signed archive/install, app + notification service extension, privacy/resource bundles, dSYMs/FullStory upload, push, camera, payments/identity, map, offline database, permissions, auth and legacy/new navigation. Verify rollback and compare binary size, build time and startup. Owners should pursue the linked open PRs/requests; for rows without a tracker, either open one upstream or own a narrowly scoped manifest/fork/replacement after confirming usage.
Activity
roryabraham commentedon Aug 13, 2026
no update for now. Hoping that someone else will do the heavy lifting to figure this out in the React Native upstream.
roryabraham commentedon Sep 10, 2026
@mateuuszzzzz would you be interested in helping to supervise this? With your experience in the cocoapods/prebuilt binaries, I think you'd be a good fit.
roryabraham commentedon Sep 10, 2026
@MelvinBot is there any upstream tracking issue in the React Native repo to migrate from Cocoapods to SPM?
MelvinBot commentedon Sep 10, 2026
There's no single umbrella tracking issue in the React Native repo itself. Upstream tracking lives in
react-native-community/discussions-and-proposals, and the plan of record is RFC0994: Swift Package Manager Support for React Native iOS Projects — open since 2026-04-21, authored bychrfalch(Callstack), explicitly framed around the December 2026 CocoaPods deprecation.The two places to watch:
npx react-native spmCLI withadd --deintegratefor existing Podfile apps, and the adoption strategy.Implementation is already landing, not just proposed. Note the repo moved: it's now
react/react-native, notfacebook/react-native.Current upstream status
mainright now, e.g. Derive an SPM library's Swift name from its podspec (#58290), landed 2026-09-09. RN closes these PRs via the Meta importer, so GitHub shows them as "closed" rather than "merged" — checkmain's commit log for the real state.set -euo pipefailscripts but runs them with/bin/sh, still open).cipolleschion Update version to 1.0.1-92 #587 (2026-06-22) is still unanswered.So the heavy lifting you were hoping for is in progress. The practical read for us: subscribe to #994 and #587, and the thing that will actually gate us is third-party library readiness — every native dep we use needs a
Package.swiftor SPM metadata, and the RFC pushes that onto library authors during the transition.Next Steps: Reply with
@MelvinBot <your feedback>to refine this.view run · no recording available
roryabraham commentedon Sep 10, 2026
seems like @mrousavy also likely has good context on the Nitro side of things
mrousavy commentedon Sep 10, 2026
Yup, we can do that @ margelo
roryabraham commentedon Oct 22, 2026
No update from me on our side, but I see RN 0.87 introduced experimental SwiftPM support and recent release notes show a lot of development around SwiftPM support in React Native
roryabraham commentedon Nov 10, 2026
Bumping to weekly since the deadline is coming up
roryabraham commentedon Nov 10, 2026
CocoaPods → SwiftPM: dependency and migration scope
Bottom line: This is a migration of two iOS projects and the React Native/Expo build machinery, not just a replacement of the explicit
podlines. The production mobile build is the HybridApp. Its legacy native dependencies and notification extension are additional to the autolinked NewDot native modules. A realistic first milestone is an experimental, non-production hybrid build on RN/Expo versions with SwiftPM support, not a production cutover on December 2.Deadline clarification: CocoaPods plans to make trunk read-only on December 2, 2026, not delete the client or existing specs. Locked builds should continue resolving; new trunk versions stop. Git/npm/path pods and private spec repos are different, although their own vendors can stop releasing. For example, Firebase stopped publishing new CocoaPods versions in October; our locked native Firebase is 11.13.0. Staying on CocoaPods buys time but can freeze security/SDK updates.
Likely critical path:
How I counted / caveats
Snapshot: App
3159209Podfile, lock, package.json; the submodule pinned there is Mobile-Expensify6d2f769Podfile and lock (private repo). Checked upstream and npm on 2026-11-10.DEPENDENCIES, including autolinked Expo/RN modules and generated RN pods, not just manually writtenpodcalls. There are 157 standalone entries, 190 hybrid entries, 191 distinct entries: 76 RN core/generated entries, 22 Expo entries, 37 explicitly declared native/extension entries, and 56 other RN/first-party entries. All are accounted for below. Transitive pods are discussed where they affect a direct package, not counted as direct packages.Appductis an additional conditional debug native dependency in currentpackage.json/autolinking config but absent from both locks, so it is included separately rather than counted in 191. The two locks disagree oncallstack-repackandAirshipServiceExtension; the hybrid lock also includes three Expo entries excluded in App's currentexpo.autolinkingconfig. Re-resolve both configurations before relying on the exact graph; a lockfile entry is not proof of runtime use.truemeans a stable, published version of the actual package (including the pinned version, when no upgrade is needed) offers SPM for the product we use. Expo preview-plugin source generation/binaries and RN preview support count. It does not promise a drop-in build for our app.falseincludes unverified support, unreleased/preview-only library versions, or cases requiring an owned fork/patch to retain our changes.truemeans the consumed repository is archived/explicitly deprecated, or its default branch has had no commit since 2023-11-10 (a staleness proxy, not proof a maintainer abandoned it); links ontrueshow the archive or last commit. For forks this evaluates the source we consume, even where the parent is active.falsemeans no such evidence was found, not that maintenance is guaranteed; the proprietary Group-IB vendor status is unverified.Explicit native and extension pods
ActionSheetPicker-3.02.3.0; HAFNetworking4.0.1; HUIImageView+AFNetworkingandAFNetworkActivityIndicatorManager. UIKit SPM PR is open in the archived repo. Fork/package the UIKit categories or replace their uses; validate networking, uploads, reachability, and TrustKit.AirshipServiceExtensionS 20.0.0 / H 19.10.0; BAirshipNotificationServiceExtensionproduct (19.10, 20.0). Link it to each notification extension, and reconcile its version with the app's Airship 20.8.1 dependency.AppLogs0.1.0; BAppLogsPodsources as an independent product linked to the extension; coordinate with the RN wrapper below and verify extension-safe logging.CropViewController2.5.2; HCryptoSwift1.3.2; HDTCoreText1.6.25; HDTFoundationanddefault.cssresources.DynamicButton6.2.1; HFlexibleSteppedProgressBar0.6.1; HFloaty4.2.0; HFullStory1.76.0; B${PODS_ROOT}uploader phase with FullStory's SPM uploader path.GBDeviceInfo6.6.0; HGzipSwift5.1.1; BGzipproduct; link it to the notification extension, preserve zlib linkage and test decompression.INTULocationManager4.3.0; HCLLocationManager; preserve one-shot, continuous, cancellation, and permission behavior.JTNumberScrollAnimatedView1.0.0; HMaterialComponents/Tabs54.13.0; HMaterialComponents/TextFields+Extensions54.13.0; HMDFInternationalization/resource dependencies, or replace the controls.MRProgress0.8.3; HNSData+Base641.0.0; HNSData+MD5Digest1.0.0; HNWWebSocket0.5.10; BPureLayout3.1.4; HPusherSwiftWithEncryption10.1.6; HPusherSwiftmanifest includesTweetNaclandNWWebSocket. Unify it with the RN wrapper's Pusher dependency; verify encrypted channels and avoid duplicate frameworks.ReachabilitySwift5.0.0; HReachabilitymanifest; link and test online/offline transitions.RMDateSelectionViewController2.3.1; HRMActionControlleror replace withUIDatePicker; test date/time behavior.SDCAlertView12.0.4; HSlideMenuControllerSwift5.0.0; HSSKeychain1.2.2; HSecurity.framework, preserving service/account/accessibility and existing persisted credentials.SwiftGifOrigin1.7.0; Hv1.7.0(fork). Port/tag it or replace; account for theSwiftGifproduct/module name and test GIF decoding.SwiftLint0.53.0; H${PODS_ROOT}/SwiftLint/swiftlintphase with a pinned plugin/binary. Its SPM graph asks for CryptoSwift ≥1.7.2, which can conflict with our 1.3.2 pin; a separately installed binary avoids that graph conflict.SwiftMessages9.0.4; HTagListView1.4.0; HTrustKit3.0.7; BTTGSnackbar1.10.2; HUIImage-Resize1.0.1; HUIGraphicsImageRenderer; test output size, scale and aspect ratio.UIImageViewAlignedSwift0.3.0; Hzipzap8.0.3; HReact Native bridges and first-party modules
These are direct CocoaPods entries generated by RN autolinking. The native vendor SDK supporting SPM is not by itself SPM support for the RN bridge. “Scaffold” means try RN's podspec-to-manifest generator, inspect/patch the result, and upstream it; mixed Swift/Obj-C++ targets, scripts, binary dependencies and codegen often need manual work.
callstack-repackS 5.4.1 / H 5.3.0; BJWTDecode/SwiftyRSAdependencies and codegen; verify bundle loading.expensify-react-native-background-task0.0.0; BExpensifyNitroUtils0.0.1; Bfullstory_react-native1.10.2; Bgroup-ib-fp2.6.0; Blottie-react-native7.3.8; Blottie-spmwhile its target names the packagelottie-ios. Verify/patch that identity, link native Lottie 4.6.0 and retain privacy resources.NitroFetch1.6.2; BNitroImage0.15.2; BNitroModules0.37.1; Bonfido-react-native-sdk15.1.0; Bpusher-websocket-react-native1.3.1; BQuickCrypto1.1.6; Breact-native-advanced-input-mask1.4.6; BForkInputMask7.3.3 and new-architecture flags; test masks and editing.react-native-airship26.7.0; Breact-native-app-logs0.3.1; BAppLogsnative product with the extension; test logging from both processes.react-native-blob-util0.24.12; Breact-native-cameraroll7.4.0; Breact-native-config1.5.3; BENVFILEand generated config; test Debug/AdHoc/Release and incremental env changes.react-native-document-picker10.1.3; Breact-native-image-picker7.1.2; Breact-native-key-command1.0.14; Breact-native-keyboard-controller1.22.4; Breact-native-netinfo11.4.1; Breact-native-pager-view9.0.4; Bios/Package.swift, our pin does not. Evaluate major upgrade andSwiftUIIntrospectdependency; test paging/gestures.react-native-pdf7.0.2; Breact-native-plaid-link-sdk12.5.3; Breact-native-quick-base643.0.1; Breact-native-safe-area-context5.9.1; Breact-native-skia2.11.2; Breact-native-view-shot5.1.0; Breact-native-wallet0.1.41; Breact-native-webview16.0.0; BReactNativeBiometrics0.15.0; BReactNativeHybridApp0.0.0; BRNAppleAuthentication2.5.0; BRNCClipboard1.16.3; BRNCPicker2.11.3; BRNDeviceInfo10.3.1; BRNFBAnalytics22.2.1; BRNFBApp22.2.1; Bfirebase.json/plist configuration and align all Firebase products. The existing mixed CocoaPods+SPM path has static/dynamic linkage conflicts.RNFS2.20.0; BRNGestureHandler3.3.0; BRNGoogleSignin10.0.1; BRNLiveMarkdown0.1.371; BRNWorklets, RN headers and version flags; test rich-text editing and selection.RNLocalize3.5.4; Brnmapbox-maps10.3.10; BRNNitroSQLite10.2.0; BthreadSafe/performanceModeand SQLite flags; test database migration, writes and offline behavior.RNPermissions5.4.0; Bsetup_permissionswith equivalent config for Camera, Contacts, LocationAccuracy, LocationAlways, LocationWhenInUse; Contacts requires a separate Swift target. Test prompts and privacy manifest.RNReactNativeHapticFeedback2.3.3; BRNReanimated4.7.0; BRNWorkletstogether on the new RN version.RNScreens4.28.0; BRNSentry8.32.0; BRNShare11.0.2; BRNSVG15.15.5; BRNWorklets0.13.0; BVisionCamera5.2.3; BAppduct0.16.0; conditional S/H, not in either lockExpo autolinked pods
We are on Expo SDK 57 / RN 0.86. Expo SDK 58 pairs RN 0.88 with a preview SwiftPM plugin: plugin, 28 source manifests. Upgrade the SDK as a coherent set, then validate every module below; don't assume the current 57 packages are already consumable pod-free.
EXConstants57.0.7; BExpo57.0.8; BExpoAdapterGoogleSignIn10.0.1; HExpoAsset57.0.7; BExpoAudio57.0.3; BExpoDomWebView57.0.1; BExpoFileSystem57.0.1; HExpoFont57.0.1; BExpoImage57.0.1; BSDWebImageand AVIF/SVG/WebP codec products, then test image formats.ExpoImageManipulator57.0.6; BSDWebImageWebPCoderand test image transformations.ExpoKeepAwake57.0.1; HExpoLocation57.0.6; BExpoLogBox57.0.1; BExpoModulesCore57.0.15; BExpoModulesJSI57.0.8; BPODS_ROOTand builds an XCFramework via a pod phase; Expo plugin must replace this integration. Test Hermes/JSI headers and build flavors.ExpoModulesWorklets57.0.15; BExpoModulesWorkletsAdapter57.0.15; SRNWorkletscompatibility.ExpoStoreReview57.0.1; BExpoTaskManager57.0.6; BUMAppLoader, background registration and privacy bundle; test background launch.ExpoVideo57.0.2; BExpoWebBrowser57.0.2; BUMAppLoader57.0.1; BReact Native core and generated pods
All 76 entries below appear in both locks and are part of the same RN/Hermes/codegen migration, rather than 76 independent third-party libraries. RN RFC / community tracker: upgrade from RN 0.86 to a supported SPM-preview version, regenerate headers/codegen/autolinking and validate prebuilt React, dependencies and Hermes. RN 0.87 explicitly says its SPM path is experimental and not for production. The following table names every direct entry so none are hidden by the grouping.
All 76 direct React Native/Hermes/codegen entries
FBLazyVectorhermes-engineRCTDeprecationRCTRequiredRCTSwiftUIRCTSwiftUIWrapperRCTTypeSafetyReactReact-callinvokerReact-CoreReact-Core-prebuiltReact-Core/RCTWebSocketReact-CoreModulesReact-cxxreactReact-debugReact-defaultsnativemoduleReact-domnativemoduleReact-FabricReact-FabricComponentsReact-FabricImageReact-featureflagsReact-featureflagsnativemoduleReact-graphicsReact-hermesReact-idlecallbacksnativemoduleReact-ImageManagerReact-intersectionobservernativemoduleReact-jserrorhandlerReact-jsiReact-jsiexecutorReact-jsinspectorReact-jsinspectorcdpReact-jsinspectornetworkReact-jsinspectortracingReact-jsitoolingReact-jsitracingReact-loggerReact-MapbufferReact-microtasksnativemoduleReact-mutationobservernativemoduleReact-NativeModulesAppleReact-networkingReact-oscompatReact-perfloggerReact-performancecdpmetricsReact-performancetimelineReact-RCTActionSheetReact-RCTAnimationReact-RCTAppDelegateReact-RCTBlobReact-RCTFabricReact-RCTFBReactNativeSpecReact-RCTImageReact-RCTLinkingReact-RCTNetworkReact-RCTRuntimeReact-RCTSettingsReact-RCTTextReact-RCTVibrationReact-rendererconsistencyReact-renderercssReact-rendererdebugReact-RuntimeAppleReact-RuntimeCoreReact-runtimeexecutorReact-RuntimeHermesReact-runtimeschedulerReact-timingReact-utilsReact-viewtransitionnativemoduleReact-webperformancenativemoduleReactAppDependencyProviderReactCodegenReactCommon/turbomodule/coreReactNativeDependenciesYogaCross-cutting work / suggested sequence
spm_dependencybridge can help a particular native SDK, but still leaves CocoaPods and can conflict with our static-framework setup.iOS/Expensify.xcodeprojand standaloneios/NewExpensify.xcodeproj; validatenpx rock config -p ios/custom config command, codegen, Expo module-provider generation, new-architecture flags and permissions. Prototype without assuming--deintegratehandles our custom targets/hooks automatically.PODS_ROOTheader paths, static-framework overrides, Expo configure phase,react-native-configgeneration, FullStory uploader, RNFB plist phase, SwiftLint path, resource-copy/embed/sign phases and the hybrid duplicate-implementation workaround. Preserve per-target extension dependencies and avoid incompatible package versions/duplicate binaries. Update iOS CI pod caches/install, prebuilt-lock checks, local scripts andPackage.resolved/artifact caching.