All Articles
CategoryFlutter
Reading Time
13 min read
Published
2026-10-10
Word Count
3,167words

Grab a coffee — this one is a deep dive!

Flutter's Goodbye to CocoaPods: SwiftPM Migration Guide

Summary

Flutter's Swift Package Manager migration: a step-by-step guide to flutter config, Package.swift, and CI changes on the app and plugin side as CocoaPods enters maintenance mode.

  • 92% of the top 100 iOS plugins have migrated to SwiftPM (up from 61% in April 2026) — CocoaPods' trunk server becomes permanently read-only on December 2, 2026.
  • It's enabled with flutter config --enable-swift-package-manager; on by default since Flutter 3.44, and the CLI auto-updates your Xcode project.
  • Plugin maintainers need to add a Package.swift file, and (if migrated during the 2025 pilot) add FlutterFramework as a new dependency.
  • If something breaks, roll back temporarily via enable-swift-package-manager: false in pubspec.yaml; the team asks for bug reports via the official issue template.
Flutter's Goodbye to CocoaPods: SwiftPM Migration Guide

In its 3.47 announcement published on August 12, 2026, the Flutter team shared a striking number: 92 of the 100 most popular iOS plugins have now migrated to Swift Package Manager (SwiftPM). That figure was 61 percent in April 2026 — the ecosystem has moved away from CocoaPods fast, in just a few months. If you're still wrestling with a Podfile, or you maintain a plugin, this guide walks you through what to do on both the app and plugin side, with sources and step by step.

💡 Pro Tip: Before testing the SwiftPM migration, run flutter clean and manually delete the ios/Pods/ and ios/.symlinks/ directories — leftover CocoaPods artifacts can collide with the new Xcode project configuration and produce misleading build errors.

Table of Contents

Why Now: CocoaPods Is in Maintenance Mode, the Plugin Ecosystem Has Migrated

The Flutter team made SwiftPM the default dependency manager on iOS/macOS starting with Flutter 3.44. That choice wasn't a coincidence: CocoaPods announced on its own blog that the package registry server trunk will become permanently read-only on December 2, 2026 — no new podspec can be published after that date (a test rehearsal runs November 1–7, 2026). Flutter's April 30, 2026 announcement summed it up in one sentence: "CocoaPods is officially in maintenance mode" — new contributions to trunk are closing, while existing builds keep working.

The numbers back this trend up:

Date
SwiftPM share among the top 100 iOS plugins
Source
April 30, 2026
61%
flutter.dev "Saying Goodbye to CocoaPods"
August 12, 2026
92%
flutter.dev "What's new in Flutter 3.47"

The August 12, 2026 Flutter 3.47 announcement puts it verbatim: "plugins that do not migrate to SwiftPM will eventually stop working"; their pub.dev score is kept low in the meantime — technical and ecosystem pressure both point the same way. React Native also added experimental SwiftPM support for iOS in its 0.87 release on August 11, 2026, showing this isn't one framework's preference but a broader cross-platform trend.

Turning It On with flutter config --enable-swift-package-manager

SwiftPM has already been on by default since Flutter 3.44. If it was previously turned off deliberately (opted out) in your project, you can re-enable it with a single-line command:

bash
1flutter config --enable-swift-package-manager
2flutter clean
3flutter run

When you run flutter run or flutter build ios, the Flutter CLI automatically updates the Xcode project to use SwiftPM — no manual .xcodeproj editing needed. This is confirmed verbatim both in the April 30, 2026 "Saying Goodbye to CocoaPods" post and in the app developer documentation: "When you run or build your iOS or macOS app, the CLI automatically updates your Xcode project to use Swift Package Manager."

If even one dependency doesn't yet support SwiftPM, Flutter automatically falls back to CocoaPods and prints a console warning listing which dependencies are unsupported. It's not "all or nothing" — it's a gradual migration path.

How to Verify the Migration Actually Took Effect

The official canonical check: run the app in Xcode and look for two things — the Run Prepare Flutter Framework Script step running as a pre-action in the build log, and the FlutterGeneratedPluginSwiftPackage package appearing among the target's dependencies. As a secondary check, open ios/Runner.xcworkspace and look at the "Package Dependencies" section in the left-hand project navigator — SwiftPM-resolved dependencies are listed there. If there's an unsupported dependency, read Flutter's warning line carefully — it names the culprit package; the CocoaPods fallback stays active until you update it or find an alternative.

What Changes on the App Side: Podfile, Workspace, CI

Migrating to SwiftPM changes the file structure inside the ios/ directory. If you want to remove CocoaPods entirely, the official guide recommends these steps:

bash
1cd ios
2pod deintegrate
3cd ..
4rm -f ios/Podfile ios/Podfile.lock
5rm -rf ios/Pods/ ios/.symlinks/
6# If ios/Flutter/Debug.xcconfig and ios/Flutter/Release.xcconfig
7# still have #include lines referencing "Pods/Target Support Files", remove them
8flutter clean
9flutter pub get
10flutter run

These steps ensure the workspace no longer carries any CocoaPods references. The most important CI change: you can remove the pod install step (dependencies are resolved by SwiftPM as part of Xcode's own build process) — but in a mixed project (some dependencies still on CocoaPods) keep that step; see "mixed state" below.

Note: apply this cleanup only after confirming that all dependencies support SwiftPM. Otherwise flutter build ios can't fall back to CocoaPods, and the build breaks.

Configuring the Transition Period in Your CI Pipeline

During a mixed period, it's safer to set up a conditional step than to change CI outright. A GitHub Actions step like this runs pod install only if a Podfile still exists, otherwise leaves resolution to SwiftPM:

yaml
1- name: Resolve iOS dependencies
2 run: |
3 cd ios
4 if [ -f Podfile ]; then
5 pod install --repo-update
6 fi
7 cd ..
8 flutter build ios --release --no-codesign

This approach lets you move forward without breaking the pipeline while different developers on your team are at different stages of the migration.

If You Maintain a Plugin: Package.swift and the Official Migration Guide

If you publish a Flutter plugin on pub.dev, first make sure you're on Flutter 3.44 or later — the version where SwiftPM is on by default. Next, create a directory named after the plugin under ios/ (or macos/, darwin/), set up ios/plugin_name/Package.swift plus ios/plugin_name/Sources/plugin_name/, and move the sources in ios/Classes there. The official plugin author template looks like this (TODO comments simplified):

swift
1// swift-tools-version: 5.9
2import PackageDescription
3 
4let package = Package(
5 name: "plugin_name",
6 platforms: [
7 .iOS("13.0"),
8 .macOS("10.15")
9 ],
10 products: [
11 // If the plugin name contains "_", use "-" in the library name.
12 .library(name: "plugin-name", targets: ["plugin_name"])
13 ],
14 dependencies: [
15 .package(name: "FlutterFramework", path: "../FlutterFramework")
16 ],
17 targets: [
18 .target(
19 name: "plugin_name",
20 dependencies: [
21 .product(name: "FlutterFramework", package: "FlutterFramework")
22 ],
23 resources: [
24 // Uncomment this line if you need PrivacyInfo.xcprivacy:
25 // .process("PrivacyInfo.xcprivacy"),
26 ]
27 )
28 ]
29)

The .iOS("13.0") and .macOS("10.15") values in the template are still what the plugin author docs give; meanwhile, the Flutter 3.47 announcement raised Flutter's own minimum supported versions from iOS 13 to 15 and macOS 10.15 to 12. Depending on your plugin's audience, you may need to raise these.

If you already migrated your plugin during the 2025 pilot, there's a new step: you must add FlutterFramework as a dependency in your Package.swift file. This appears verbatim in the April 30, 2026 announcement: "If you already migrated your plugin during the 2025 pilot, you need to complete one new step: you must add FlutterFramework as a dependency in your Package.swift file."

For now, the Flutter team wants plugins to support both CocoaPods and SwiftPM "until further notice" — fully dropping CocoaPods isn't mandatory yet, but the direction is clear.

The dependency is defined with a local path, not a version constraint. The docs' "Add the FlutterFramework as a dependency" step adds exactly these two entries — a package-level dependencies entry and a product reference in the target's own dependencies:

swift
1dependencies: [
2 .package(name: "FlutterFramework", path: "../FlutterFramework")
3],
4targets: [
5 .target(
6 name: "plugin_name",
7 dependencies: [
8 .product(name: "FlutterFramework", package: "FlutterFramework")
9 ]
10 )
11]

Mixed State: A Project with Both CocoaPods and SwiftPM Dependencies

Most real-world projects aren't in a full transition right now — they're in a mixed state. The official docs explicitly define this as a supported intermediate state: if even one dependency doesn't support SwiftPM, Flutter falls back to CocoaPods automatically. So you need to wait until all dependencies have migrated before deleting your Podfile.

There's also a constraint in the opposite direction: as of Flutter 3.44, plugins that don't support CocoaPods (SwiftPM-only) can't be used in projects that haven't migrated yet. This creates pressure both ways — pushing app developers and plugin authors toward migration at once.

In practice: review your dependency tree with flutter pub deps, read the unsupported-dependency warnings in flutter run or flutter build ios output, then keep both the pod install and SwiftPM resolve steps running in parallel in CI for a while. Remove CocoaPods once every dependency turns green.

The table below summarizes the behavior Flutter's official documentation describes for different dependency scenarios:

Scenario
Flutter's behavior
All dependencies support SwiftPM
SwiftPM is used, CocoaPods stays disabled
At least one dependency supports only CocoaPods
Automatic fallback to CocoaPods, console warning printed
Project hasn't migrated to SwiftPM at all, plugin supports only SwiftPM
Plugin can't be used in this project (as of 3.44)
enable-swift-package-manager: false is set
SwiftPM fully disabled, classic CocoaPods flow

You can use the standard Dart command below to quickly list your dependency tree and see which packages need review:

bash
1flutter pub deps --style=compact

But the definitive way to pin down which dependency ties you to CocoaPods isn't this list — it's Flutter's own warning. As the April 30, 2026 announcement puts it, for an app relying on non-SwiftPM plugins, "Flutter will print a warning listing exactly which of your dependencies are unsupported." As a secondary check, look for a Package.swift file in the plugin's repository.

pub.dev Score and Ecosystem Pressure

Don't view the SwiftPM migration as purely technical — there's direct economic pressure on the pub.dev side too. As the Flutter team's April 30, 2026 announcement states, packages without SwiftPM support now get a lower pub.dev score until they migrate. This was reaffirmed in the August 12, 2026 3.47 announcement — not a temporary rule, an ongoing policy.

For a maintainer, this is a visibility issue: iOS/macOS plugins without SwiftPM support can't get full marks on the pub points "platform support / modern toolchain" item, and that score is shown both in search results and on the package page. For users it's a signal too: if a plugin's score is low, checking its SwiftPM support is a reasonable first step.

Personally, before adding a dependency I like to open the score breakdown on its pub.dev page and see which component it's dropping from: SwiftPM migration, or some other quality issue? Making that distinction early saves you from later being stuck with a dependency caught between two package managers.

Build Time Win: Scheme Filtering Optimization

Another 3.47 improvement targets build performance directly. The Flutter team optimized the build pipeline to filter out unnecessary SwiftPM package schemes early — this change came from a community contribution (GitHub PR #186006). The result, in the announcement's words, is "optimized build times" — shorter Xcode builds; no measurement is given in the source.

This also highlights another SwiftPM advantage over CocoaPods: since package resolution is integrated into Xcode's own build system, a separate "pod install" step and its extra IO/network cost disappear entirely. In a large monorepo or a plugin-heavy project, this can be noticeable in CI time.

Rollback Plan and Known Issues

If the SwiftPM migration causes problems, there's no need to panic — a temporary way to disable it is officially supported. You can add the following under the config block in your pubspec.yaml:

yaml
1flutter:
2 config:
3 enable-swift-package-manager: false

Setting this flag to false reverts the project to the previous CocoaPods-based flow. The Flutter team asks developers who opt out this way to report the bug using the official GitHub issue template — the report is expected to include the bug details, the list and versions of plugins you're using, and, if possible, your Xcode project files. This is an officially defined process for the team to collect known issues.

Practical advice: think of rollback as a "last resort." After temporarily disabling it and reporting the bug, wait until the source plugin is updated; staying permanently on CocoaPods will become an increasingly fragile position after trunk shuts down on December 2, 2026.

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

To turn this article into action, I put together a list you can check off in order, on both the app and plugin side. Move to the next item only after checking off the current one; skip the order and your build can end up stuck halfway between CocoaPods and SwiftPM.

FAQ

How do I turn on SwiftPM in Flutter?

SwiftPM has been on by default since Flutter 3.44. If you previously turned it off deliberately, it's enough to run flutter config --enable-swift-package-manager in your terminal and then flutter run or flutter build ios — the Flutter CLI automatically updates your Xcode project.

When will CocoaPods be removed from Flutter entirely?

CocoaPods hasn't been fully removed from Flutter; it still works as an automatic fallback for dependencies that don't support SwiftPM. However, CocoaPods' own trunk (package registry) server will become permanently read-only on December 2, 2026 — after that date no new pod version can be published, though existing builds will keep working. A test rehearsal is planned for November 1–7, 2026 beforehand.

How do I migrate my Flutter plugin to SwiftPM?

You need to create a directory named after the plugin under ios/ (or macos/, darwin/), set up ios/plugin_name/Package.swift plus ios/plugin_name/Sources/plugin_name/, and move your sources there from ios/Classes. If you already migrated during the 2025 pilot period, adding FlutterFramework as a dependency in your Package.swift file is an additional new requirement. See the official plugin author guide for detailed steps.

When can I remove the pod install step from CI?

Once all plugins in your project support SwiftPM. The official app developer documentation ties this to an explicit precondition: make sure all plugins in your project support Swift Package Manager before removing CocoaPods. If even a single dependency doesn't support it, Flutter falls back to CocoaPods; if you remove the pod install step too early, that fallback can't work and your CI build will break.

Will plugins that don't migrate to SwiftPM stop working?

In Flutter's own words, yes — plugins that don't migrate will eventually stop working, and in the meantime their pub.dev score is kept low. For now, the fallback to CocoaPods still works, but it isn't offered as a permanent solution.

Conclusion

Migrating to SwiftPM is no longer a choice — it's the overall direction of the Flutter ecosystem. CocoaPods' trunk server becoming permanently read-only on December 2, 2026, 92% of the top 100 plugins having already migrated, and pub.dev penalizing non-migrated packages with a lower score all point to the same signal: projects that move early go through the transition with less friction. Starting with flutter config --enable-swift-package-manager and setting up your Package.swift file correctly is the safest path forward, on both the app and plugin side.

For other changes brought by Flutter 3.47, you can check out Flutter 3.47: Migrating to material_ui and cupertino_ui. If you're working with native modules on the iOS integration side, Flutter iOS integration: platform channels and native modules will be useful. If you want to see SwiftPM's place in modular architecture on the native iOS side, Modular iOS architecture and Swift Package Manager is a good complement. If you want to improve build performance in general, I'd recommend Flutter performance optimization: the 60fps guide, and for another mandatory migration on the iOS 27 side, The UIScene Mandate in Flutter: iOS 27 Migration.

Sources

Tags

#Flutter#SwiftPM#CocoaPods#iOS#Migration#CI/CD#Package.swift
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

Lead Mobile Engineer with 12+ years of experience. Expert in iOS, Android and cross-platform architectures with Swift, SwiftUI, Kotlin and Flutter. I build performant, user-friendly mobile apps.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy

Share