As with anything in engineering, picking the right package manager for a project can be highly situational. Even in the webdev space: we have the mainstream appeal of
npm, the feature-rich
yarn, and others. Even moderately sized web applications need to face this question at some point in their development — The answer isn't always straightforward. However, React Native applications have the added complexity of needing to manage native dependencies as well as web dependencies.
While React Native ships with Cocoapods support out-of-the-box, it's not immediately clear how to add Carthage packages to your project.
Let's start with a caveat to adding Carthage to your projects: You cannot migrate your entire app's dependencies to use it. This is because React Native's dependencies have not been packaged for usage in Carthage.
As such, you will always have an additional package manager to consider with your native dependencies.
Now that we have that disclaimer out-of-the-way let's look into how to install Carthage so that you can use it in your projects.
There are three main methods you may use to install Carthage:
- Downloading the Installer directly from GitHub releases. Once you download the
.pkgfile, run it to start the installer
- If you have Homebrew installed, you can run
brew install carthage
- Lastly, if you use MacPorts, you can run
sudo port install carthage
Now that you have Carthage installed, you can start using it in your projects.
Just as npm has the
package.json file, Carthage has the
Cartfile. You'll want to create a file named
Cartfile next to your
.xcworkspace file. If your project was configured with the React Native CLI, this folder would be your
Once this file is created, you want to store your dependencies in the
ios/Cartfile file. For my React Native Git Client, we wanted to add a dependency called Objective-Git to our project. As such, our
Cartfile looks like the following:
Once you've added your dependency, you'll want to
cd into the
ios directory run
carthage update to install the dependency:
cd ios carthage update
Once this is done, you'll be left with a new folder and file:
What is the
Cartfile.resolvedfile? What does the
You can think of
Cartfile.resolved as the
package-lock.json file - it tells the package manager which version of the dependencies to use when running the package installation command (
carthage update). As such, just like the
package-lock.json, you'll want to commit this to your project's Git repo.
Carthage folder, on the other hand, is similar to your
node_modules. It's the downloaded dependencies that are resolved from the
Cartfile.resolved file. As such, you may choose to
Carthage folder. However, the Carthage official documentation leaves a note regarding this decision:
You are not required to commit this folder to your repository, but you may wish to if you want to guarantee that the built versions of each dependency will always be accessible at a later date.
For my company, we ultimately decided to follow the web's standard and not commit our
Carthage folders. As such, we needed to add the following line to our project's
However, just as npm suggests you commit the
package-lock.json file, you should commit the
Cartfile.resolved file as well, to ensure consistency in package version resolution.
There are some final steps that're needed when utilizing Carthage for your package manager. All of these changes will be made in XCode to support building your project with your new dependencies.
- Go into your
ios/Carthage/Buildfolder. You should see a collection of folders for your dependencies that have built
.frameworkfiles. I have dedicated
iOSfolders for my dependency, but yours may not.
- First, go to your app's "target." Then, go to the "General" tab and find the "Frameworks, Libraries, and Embedded Content" section. Drag and drop the
.frameworkfile from your dependency into the said section.
- Next, navigate to the "Build Phases" tab. In the top left corner, click the “+” icon and choose “New Run Script Phase”
Leave the "shell" as
/bin/sh, but set the contents of the run script to:
Finally, add the path to your dependencies'
.frameworkfiles, like this:
Please keep in mind that there may be additional steps that some dependencies want you to move forward with to integrate with your projects. Refer to the documentation for the dep for more information.
As with any decision made in engineering, the choice to add Carthage as a secondary native dependency for your React Native projects is a high contextual one. However, I hope that with the information on utilizing it properly, it alleviates some of the stress in integrating it.
If you run into any problems integrating Carthage, you can always ask for help in the comments down below or join our Discord and ask for help there as well.