DEV Community

Cover image for Flutter Is Leaving CocoaPods. Our CI Isn’t Ready
Paul-S
Paul-S

Posted on

Flutter Is Leaving CocoaPods. Our CI Isn’t Ready

Our iOS pipeline was green.

That was the problem.

After upgrading to Flutter 3.50, every local build printed a warning about Swift Package Manager. The CI job printed no warning, installed pods from cache and produced a valid archive.

Nothing had failed, but the pipeline had not tested the dependency path Flutter was moving toward.

It had tested the fallback.

The Build That Hid the Migration

The relevant part of the CI workflow looked familiar:

- name: Install CocoaPods
  run: sudo gem install cocoapods

- name: Restore Pods cache
  uses: actions/cache@v4
  with:
    path: |
      ios/Pods
      ~/.cocoapods
    key: pods-${{ hashFiles('ios/Podfile.lock') }}

- name: Install pods
  run: |
    cd ios
    pod install

- name: Build iOS
  run: flutter build ios --release --no-codesign
Enter fullscreen mode Exit fullscreen mode

This pipeline was dependable because it made CocoaPods available before Flutter needed it.

It also meant we could not answer a more important question:

Can this application build when Swift Package Manager is the primary dependency path?

A successful CocoaPods build provided no evidence.

What Flutter Actually Changed

Flutter 3.44 made Swift Package Manager the default dependency manager for iOS and macOS projects.

When a project runs or builds, the Flutter CLI can update its Xcode configuration automatically. Plugins that support SwiftPM are resolved as Swift packages. Plugins without support can temporarily fall back to CocoaPods.

Flutter 3.50 makes the transition harder to ignore. Disabling SwiftPM now produces a warning on every Flutter CLI command. Flutter plans to remove the opt-out option and eventually remove its CocoaPods fallback.

There is also a deadline behind that warning. The CocoaPods registry becomes permanently read-only on December 2, 2026.

That does not mean every existing CocoaPods application stops building on December 2. Existing packages remain available. However, new pod versions will no longer be added to the trunk, while Flutter continues moving toward Apple’s supported package manager.

Waiting for the first failed release is a poor migration test.

Why Local Builds Can Mislead You

Flutter’s automatic migration can modify files inside the Xcode project, including:

ios/Runner.xcodeproj/project.pbxproj
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
Enter fullscreen mode Exit fullscreen mode

A developer may run the application locally, accept those changes and get a successful SwiftPM build.

CI can behave differently when:

  • the updated Xcode files were not committed
  • SwiftPM was disabled globally on the runner
  • cached Pods hide an unsupported plugin
  • the pipeline opens or builds the old workspace configuration
  • only the default flavor received the required scheme pre-action
  • a script still runs pod install before every build

That final case is easy to miss. Keeping pod install in the pipeline does not prove it is still required.

Make CI Prove SwiftPM Readiness

Start by enabling SwiftPM explicitly in the migration branch:

flutter config --enable-swift-package-manager
flutter clean
flutter pub get
flutter build ios --release --no-codesign
Enter fullscreen mode Exit fullscreen mode

Do this in a clean job without restoring the Pods cache.

The Flutter build output may identify plugins that lack SwiftPM support and trigger the CocoaPods fallback. Capture that output so the job can expose the fallback rather than quietly accepting it.

set -o pipefail

flutter build ios \
  --release \
  --no-codesign 2>&1 | tee flutter-ios-build.log

if grep -Eqi \
  "falling back to CocoaPods|does not support Swift Package Manager" \
  flutter-ios-build.log; then
  echo "The iOS build still depends on CocoaPods fallback."
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Flutter’s exact warning text can change, so match the patterns produced by the SDK version pinned in the project.

This job should be separate from the existing release pipeline at first. Its purpose is to reveal the real migration gap without blocking urgent releases immediately.

Check the Xcode Configuration Too

A successful command-line build is useful, but the generated Xcode integration still needs review.

According to Flutter’s Swift Package Manager migration guide, the project should include:

  • FlutterGeneratedPluginSwiftPackage as a package and target dependency
  • Run Prepare Flutter Framework Script as a build pre-action
  • the preparation command using Flutter’s xcode_backend.sh prepare

Check every shared scheme used by CI. A project with development, staging and production flavors may have separate schemes, and an automatically migrated default scheme does not guarantee the others are correct.

Run at least one clean build for each release flavor.

flutter build ios \
  --flavor staging \
  --release \
  --no-codesign

flutter build ios \
  --flavor production \
  --release \
  --no-codesign
Enter fullscreen mode Exit fullscreen mode

Do Not Delete the Podfile First

Removing CocoaPods should be the final cleanup step, not the first migration step.

Flutter still falls back to CocoaPods when a dependency lacks SwiftPM support. Deleting the Podfile before auditing plugins can turn a manageable compatibility warning into a broken build.

First, classify the dependencies:

  • plugins that support SwiftPM
  • plugins waiting for maintainer updates
  • internal plugins the team must migrate
  • manually added pods that need Swift package replacements
  • dependencies that should be replaced or removed

Only remove CocoaPods integration after all required dependencies build through SwiftPM.

At that point, the official migration process includes running pod deintegrate, deleting CocoaPods files and removing Pod-related .xcconfig includes.

A Green Build Needs a Better Definition

The old definition was simple:

The iOS archive was produced.
Enter fullscreen mode Exit fullscreen mode

The new definition needs one more condition:

The archive was produced through the intended dependency manager.
Enter fullscreen mode Exit fullscreen mode

For teams working with a hybrid app development company, this is a useful delivery question: does the CI pipeline prove SwiftPM compatibility, or does it still succeed because CocoaPods fallback is available?

Flutter is giving teams time to migrate.

The warning is not the failure. It is the chance to discover the failure before the fallback disappears.

Top comments (0)