Cocoapods
Downgrade Cocoapods
Install Older Version
Ruby Gems
Software Version Control

How to downgrade or install an older version of Cocoapods

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To install an older version of CocoaPods, run sudo gem install cocoapods -v 1.11.3 (replacing the version number with whatever you need). For team-reproducible builds, the better approach is to pin CocoaPods in a Gemfile and always run it through bundle exec pod. This article covers both the quick global approach and the production-grade Bundler workflow, along with the environment pitfalls that make CocoaPods version management tricky.

Check What Is Currently Installed

Before changing anything, identify what binary is actually running and where it came from. Many macOS machines end up with CocoaPods installed from both Homebrew and RubyGems, and the one that wins depends on shell path ordering.

bash
1which pod
2pod --version
3gem list cocoapods
4brew list --versions cocoapods 2>/dev/null

If which pod points to /opt/homebrew/bin/pod but your team expects a gem-based install, that mismatch is the first thing to fix. Homebrew and gem CocoaPods have separate upgrade paths, and you want exactly one source of truth.

Quick Global Install via RubyGems

For a straightforward downgrade on a single machine:

bash
1# Uninstall the current version
2sudo gem uninstall cocoapods -v 1.15.2
3
4# Install the target version
5sudo gem install cocoapods -v 1.11.3
6
7# Verify
8pod --version

You can also install the target version without uninstalling the current one. RubyGems keeps multiple versions side by side, and the latest one wins by default. To run a specific version explicitly:

bash
pod _1.11.3_ --version

The underscore syntax tells RubyGems to activate that exact gem version. This is useful for quick checks but is not a sustainable workflow for teams.

Global gem installs break the moment you work on two projects that need different CocoaPods versions. The standard solution is Bundler, which manages gem versions per project through a Gemfile.

Create a Gemfile in your project root:

ruby
source "https://rubygems.org"

gem "cocoapods", "1.11.3"

Then install and use CocoaPods through Bundler:

bash
bundle install
bundle exec pod --version   # 1.11.3
bundle exec pod install

Commit both Gemfile and Gemfile.lock to version control. Now every developer on the team, plus CI, uses exactly the same CocoaPods version without relying on machine-wide state.

Why bundle exec Matters

Running plain pod install after setting up Bundler is a common mistake. The bare pod command resolves to whatever version the system path finds first, which is usually the latest global install. bundle exec pod install forces the invocation through the pinned version in Gemfile.lock. Make this a team rule and enforce it in CI.

Isolate Ruby Environments with rbenv or rvm

CocoaPods is a Ruby gem, so it inherits all of Ruby's version management complexities. Different CocoaPods releases support different Ruby versions, and the system Ruby on macOS is often outdated. A Ruby version manager solves this.

Using rbenv:

bash
1# Install and set a project-local Ruby version
2rbenv install 3.1.4
3rbenv local 3.1.4
4
5# Install Bundler under that Ruby
6gem install bundler
7
8# Install project gems including CocoaPods
9bundle install
10bundle exec pod install

This creates a .ruby-version file in the project directory. Combined with Gemfile.lock, you now have both the Ruby version and the CocoaPods version locked per project. New team members get a reproducible environment after two commands.

Using rvm:

bash
1rvm install 3.1.4
2rvm use 3.1.4
3gem install bundler
4bundle install
5bundle exec pod install

Either tool works. The goal is isolation: one project's gem environment does not leak into another.

Remove Homebrew CocoaPods to Eliminate Path Conflicts

If Homebrew CocoaPods is not part of your workflow, remove it to prevent ambiguity:

bash
brew uninstall cocoapods
hash -r           # Clear the shell's command cache
which pod         # Should now point to the gem-based install
Installation MethodPathManaged By
Homebrew/opt/homebrew/bin/podbrew upgrade
System RubyGems/usr/bin/pod or /usr/local/bin/podgem update
rbenv gem~/.rbenv/shims/podgem update under rbenv
Bundler (project-local)vendor/bundle/... or gem pathbundle update

When multiple installations exist, shell path order determines which one runs. This is the root cause of most "it works on my machine" CocoaPods issues.

CI Setup for Deterministic Pod Installs

CI runners should always use Bundler, even if CocoaPods is pre-installed on the runner image.

bash
1# Cache gems in the project directory for CI caching
2bundle config set --local path vendor/bundle
3bundle install --jobs 4 --retry 3
4
5# Always use bundle exec
6bundle exec pod install --repo-update

For GitHub Actions, a typical setup looks like:

yaml
1- name: Install Ruby
2  uses: ruby/setup-ruby@v1
3  with:
4    ruby-version: '3.1'
5    bundler-cache: true
6
7- name: Pod Install
8  run: bundle exec pod install --repo-update

The bundler-cache: true flag automatically caches the gem bundle between runs, which speeds up the pipeline significantly.

Full Downgrade Workflow

When you need to switch an existing project to an older CocoaPods version, follow this sequence:

  1. Add or update Gemfile with the target CocoaPods version.
  2. Run bundle install to lock the version.
  3. Run bundle exec pod --version to confirm.
  4. Run bundle exec pod deintegrate to remove existing pod integration.
  5. Delete Pods/ directory and Podfile.lock.
  6. Run bundle exec pod install to reintegrate from scratch.
  7. Build and run tests to verify.

The deintegration step is important. Different CocoaPods versions can produce different project file structures, and a clean reintegration catches hidden drift that a plain pod install might miss.

Troubleshooting Common Errors

ErrorCauseFix
activesupport requires Ruby >= 3.1CocoaPods dependency needs newer RubyInstall matching Ruby version via rbenv
Could not find cocoapods-1.11.3 in any of the sourcesVersion does not exist or gem source unreachableCheck gem search cocoapods --remote --all
You don't have write permissions for the /Library/Ruby/GemsTrying to install into system Ruby without sudoUse rbenv/rvm or add sudo
CDN: trunk URL couldn't be downloadedCocoaPods CDN issueRun pod repo remove trunk then pod setup
Errno::EPERM on Apple SiliconArchitecture mismatch in native gemsPrefix with arch -x86_64 or rebuild native extensions

For persistent permission issues:

bash
gem update --system
gem install bundler
xcode-select --install

Common Pitfalls

Downgrading the global install and assuming every project should use that version is the most frequent mistake. Each project should pin its own CocoaPods version through Bundler.

Running plain pod install after pinning a version in Bundler defeats the purpose. The global pod binary is not the pinned version. Always use bundle exec pod.

Keeping both Homebrew and gem-based CocoaPods installed creates path precedence conflicts that produce inconsistent behavior between machines. Remove whichever installation method you are not using.

Editing Podfile.lock with one CocoaPods version and running pod install with another version causes lockfile churn and spurious diffs in pull requests. The lockfile records which CocoaPods version generated it, and mismatches trigger unnecessary rewrites.

Skipping pod deintegrate during a major version change can leave stale build settings in the Xcode project that cause confusing compilation errors unrelated to your code.

Summary

  • Install a specific version globally with gem install cocoapods -v X.Y.Z for quick single-machine needs.
  • For team and CI consistency, pin CocoaPods in a Gemfile and always run through bundle exec pod.
  • Use a Ruby version manager (rbenv or rvm) to isolate gem environments across projects.
  • Remove duplicate CocoaPods installations (Homebrew vs gem) to eliminate path conflicts.
  • Run pod deintegrate followed by a clean pod install when switching between major CocoaPods versions.
  • Commit both Gemfile and Gemfile.lock to version control for fully reproducible builds.

Course illustration
Course illustration

All Rights Reserved.