Supporting React Native on moving on from CocoaPods

Despite CocoaPods entering maintenance mode, the React Native community continues to rely heavily on it to integrate dependencies distributed as NPM packages and managed by tools like npm, yarn, or pnpm.

Although React Native isn’t the primary focus of our work, I can’t help but consider how we could support this ecosystem in transitioning from CocoaPods, enhancing the developer experience (DX) of building Apple apps with React Native.

Over the years, we’ve developed robust logic that transforms an Xcode project graph into an Xcode workspace, which essentially mirrors the role CocoaPods plays for React Native today. React Native and Expo currently generate a set of CocoaPods specs, which then create an Xcode workspace. Imagine if the React Native community could leverage this functionality that Tuist has refined over the years. This is the beauty of open source—we could collaborate with other invested groups, like Expo, to ensure this generation logic is fast, reliable, and beneficial for everyone.

Switching away from CocoaPods would also streamline React Native’s developer experience. CocoaPods brings a dependency on Ruby, which needs to be installed and consistent across environments for determinism. This setup often requires Bundler, bundle install, and a version manager for Ruby, which adds complexity. Wouldn’t it be ideal if all you needed was Node and a package manager like NPM, Yarn, or PNPM? I certainly think so.

It might be tempting to consider SPM (Swift Package Manager) for this role, but let’s be realistic—it’s unlikely. React Native needs a solution that can dynamically construct a dependency graph from the content in node_modules and integrate it into an Xcode project. You can’t just drop a Package.swift in each NPM package, as Swift packages can’t leverage Node’s module resolution. Even a single Package.swift for the whole graph might hit limitations, lacking critical APIs for certain React Native packages. Getting SPM to align with these needs would require significant influence on its direction—an improbable scenario.

Tuist’s generation logic seems like a perfect fit to address this gap. However, our resources are limited, and our priority is to grow the business. But this could be a fantastic opportunity for Expo, Software Mansion or other collaborators to support the effort. We’re currently working to decouple the generation logic from Tuist, so it would soon be a standalone function, simply taking a standard XcodeGraph instance and outputting an Xcode workspace—completely independent of Tuist.

Moreover, this approach could shift Xcode projects from being a central part of React Native app development to becoming an implementation detail. Imagine not needing an .xcodeproj or .xcworkspace in your repo. Just run expo run ios, and an Xcode project would be generated behind the scenes solely for building and running. That simplicity would be transformative.

If this vision excites you, please help us spread the word. Our presence in the React Native ecosystem is limited, but we want to share that we have the tools, expertise, and passion to contribute. With the right support, we believe the impact could be enormous.

2 Likes

I saw this was written back in November. What do you think still needs to be decoupled from Tuist? Or is this already done?

Hi @omkar.sabade,

The decoupling hasn’t happened yet, but we’ve taken steps to make that easier. Is this something you’d be interested in contributing to?

Hey @pepicrft,

Thanks for your response!

I recall we had a similar conversation on the Tuist Slack before, where I asked about the possibility of remote caching with pod dependencies. You mentioned that it’s technically feasible to use the podspec to create a Tuist target, and from there it should work.

That said, my main goal is to facilitate a gradual transition to SPM in my project. To achieve this, I’m considering using podspec files to create Tuist targets and then migrate to a few SPMs at a time.

I’m a bit unsure where to start with this, though. I was reading up on XcodeProj / XcodeGraph before I came across this discussion. I’d love to contribute to the decoupling effort. It seems like a good investment for my use case.

The idea that I had in mind was to extend tuist generate so that it can take a base64 JSON-encoded version of XcodeGraph. Something like:

tuist generate --graph A245BCR....

Then build a NodeJS wrapper that turns the RN graph (from node_modules) into an XcodeGraph that can then be used to create the project. I believe the React Native CLI is extensible, so it could be built into that, though I believe Expo is the go-to CLI these days?

Why would you go through podspecs?

Looking forward to Tuist’s support for RN!

@rakuyoMo are you using React Native? Would you be interested in taking something like this on?

I wonder what the state of adopting SwiftPM is. There has been no update in the issue since I posted the last message.

I am a cross-platform spectator, and I am still hesitating between RN and Flutter.

My project is currently developed in Swift natively, and I am using Tuist to migrate from CocoaPods to SPM.

As far as I know, RN’s support for SPM is not as good as Flutter, but I am migrating to spm now.

If Tuist can support rn one day, then I think I will prefer RN instead of Flutter. At least now I prefer Flutter.

Sorry, but I’m afraid I can’t be of much help. I’m not familiar with either.

Thanks for the insights @rakuyoMo. RN support might come. The technical path is clear, but we are trying to figure out how to do it sustainably by reconciling all the pieces from the ecosystem (e.g. Expo CLI).