# Swift Package Manager for app developers

> How to use Swift Package Manager for native iOS or macOS dependencies



:::warning
Flutter is migrating to [Swift Package Manager][] to manage iOS and macOS native
dependencies.
Flutter's support of Swift Package Manager is under development.
If you find a bug in Flutter's Swift Package Manager support,
[open an issue][].
Swift Package Manager support is [off by default][].
Flutter continues to support CocoaPods.
:::

Flutter's Swift Package Manager integration has several benefits:

1. **Provides access to the Swift package ecosystem**.
   Flutter plugins can use the growing ecosystem of [Swift packages][].
1. **Simplifies Flutter installation**.
   Xcode includes Swift Package Manager.
   You don't need to install Ruby and CocoaPods if your project uses
   Swift Package Manager.

[Swift Package Manager]: https://www.swift.org/documentation/package-manager/
[off by default]: #how-to-turn-on-swift-package-manager
[Swift packages]: https://swiftpackageindex.com/
[open an issue]: https://github.com/flutter/flutter/issues/new?template=2_bug.yml

## How to turn on Swift Package Manager

Flutter's Swift Package Manager support is turned off by default.
To turn it on:

1. Upgrade to the latest Flutter SDK:

   ```sh
   flutter upgrade
   ```

1. Turn on the Swift Package Manager feature:

   ```sh
   flutter config --enable-swift-package-manager
   ```

Using the Flutter CLI to run an app [migrates the project][addSPM] to add
Swift Package Manager integration.
This makes your project download the Swift packages that
your Flutter plugins depend on.
An app with Swift Package Manager integration requires Flutter version 3.24 or
higher.
To use an older Flutter version,
you will need to [remove Swift Package Manager integration][removeSPM]
from the app.

Flutter falls back to CocoaPods for dependencies that do not support Swift
Package Manager yet.

## How to turn off Swift Package Manager

:::secondary Plugin authors
Plugin authors need to turn on and off Flutter's Swift Package Manager
support for testing.
App developers do not need to disable Swift Package Manager support,
unless they are running into issues.

If you find a bug in Flutter's Swift Package Manager support,
[open an issue][].
:::

Disabling Swift Package Manager causes Flutter to use CocoaPods for all
dependencies.
However, Swift Package Manager remains integrated with your project.
To remove Swift Package Manager integration completely from your project,
follow the [How to remove Swift Package Manager integration][removeSPM]
instructions.

### Turn off for a single project

In the project's `pubspec.yaml` file, under the `flutter` section,
set `enable-swift-package-manager` to `false` in the `config` subsection.

```yaml title="pubspec.yaml"
# The following section is specific to Flutter packages.
flutter:
  config:
    enable-swift-package-manager: false
```

This turns off Swift Package Manager for all contributors to this project.

:::note Migrating from deprecated syntax
If you were previously using `disable-swift-package-manager: true`,
update your `pubspec.yaml` to use the new `config` section format shown above.
The old syntax is deprecated and will produce an error in Flutter 3.38 and later.
:::

### Turn off globally for all projects

Run the following command:

```sh
flutter config --no-enable-swift-package-manager
```

This turns off Swift Package Manager for the current user.

If a project is incompatible with Swift Package Manager, all contributors
need to run this command.

[addSPM]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-add-swift-package-manager-integration
[removeSPM]: /packages-and-plugins/swift-package-manager/for-app-developers#how-to-remove-swift-package-manager-integration
[open an issue]: https://github.com/flutter/flutter/issues/new?template=2_bug.yml


## How to add Swift Package Manager integration

### Add to a Flutter app

<Tabs key="darwin-platform">
<Tab name="iOS project">

Once you [turn on Swift Package Manager][], the Flutter CLI tries to migrate
your project the next time you run your app using the CLI.
This migration updates your Xcode project to use Swift Package Manager to
add Flutter plugin dependencies.

To migrate your project:

1. [Turn on Swift Package Manager][].

1. Run the iOS app using the Flutter CLI.

   If your iOS project doesn't have Swift Package Manager integration yet, the
   Flutter CLI tries to migrate your project and outputs something like:

   ```console
   $ flutter run
   Adding Swift Package Manager integration...
   ```

   The automatic iOS migration modifies the
   `ios/Runner.xcodeproj/project.pbxproj` and
   `ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme` files.

1. If the Flutter CLI's automatic migration fails, follow the steps in
   [add Swift Package Manager integration manually][manualIntegration].

[Optional] To check if your project is migrated:

1. Run the app in Xcode.
1. Ensure that  **Run Prepare Flutter Framework Script** runs as a pre-action
   and that `FlutterGeneratedPluginSwiftPackage` is a target dependency.

   <DashImage image="development/packages-and-plugins/swift-package-manager/flutter-pre-action-build-log.png" caption="Ensure **Run Prepare Flutter Framework Script** runs as a pre-action" />

[Turn on Swift Package Manager]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-turn-on-swift-package-manager
[manualIntegration]: /packages-and-plugins/swift-package-manager/for-app-developers/#add-to-a-flutter-app-manually


</Tab>
<Tab name="macOS project">

Once you [turn on Swift Package Manager][], the Flutter CLI tries to migrate
your project the next time you run your app using the CLI.
This migration updates your Xcode project to use Swift Package Manager to
add Flutter plugin dependencies.

To migrate your project:

1. [Turn on Swift Package Manager][].

1. Run the macOS app using the Flutter CLI.

   If your macOS project doesn't have Swift Package Manager integration yet, the
   Flutter CLI tries to migrate your project and outputs something like:

   ```console
   $ flutter run -d macos
   Adding Swift Package Manager integration...
   ```

   The automatic iOS migration modifies the
   `macos/Runner.xcodeproj/project.pbxproj` and
   `macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme` files.

1. If the Flutter CLI's automatic migration fails, follow the steps in
   [add Swift Package Manager integration manually][manualIntegration].

[Optional] To check if your project is migrated:

1. Run the app in Xcode.
1. Ensure that  **Run Prepare Flutter Framework Script** runs as a pre-action
   and that `FlutterGeneratedPluginSwiftPackage` is a target dependency.

   <DashImage image="development/packages-and-plugins/swift-package-manager/flutter-pre-action-build-log.png" caption="Ensure **Run Prepare Flutter Framework Script** runs as a pre-action" />

[Turn on Swift Package Manager]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-turn-on-swift-package-manager
[manualIntegration]: /packages-and-plugins/swift-package-manager/for-app-developers/#add-to-a-flutter-app-manually


</Tab>
</Tabs>

### Add to a Flutter app _manually_

<Tabs key="darwin-platform">
<Tab name="iOS project">

Once you [turn on Swift Package Manager][], the Flutter CLI tries to migrate
your project to use Swift Package Manager the next time you run your app
using the CLI.

However, the Flutter CLI tool might be unable to migrate your project
automatically if there are unexpected modifications.

If the automatic migration fails, use the steps below to add Swift Package
Manager integration to a project manually.

Before migrating manually, [file an issue][]; this helps the Flutter team
improve the automatic migration process.
Include the error message and, if possible, include a copy of
the following files in your issue:

* `ios/Runner.xcodeproj/project.pbxproj`
* `ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme`
   (or the xcsheme for the flavor used)

### Step 1: Add FlutterGeneratedPluginSwiftPackage Package Dependency {:.no_toc}

1. Open your app (`ios/Runner.xcworkspace`) in Xcode.
1. Navigate to **Package Dependencies** for the project.

   <DashImage image="development/packages-and-plugins/swift-package-manager/package-dependencies.png" caption="The project's package dependencies" />

1. Click the <Icon id="add" label="add/plus"></Icon> button.
1. In the dialog that opens, click **Add Local...**.
1. Navigate to `ios/Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage`
   and click **Add Package**.
1. Ensure that it's added to the `Runner` target and click **Add Package**.

   <DashImage image="development/packages-and-plugins/swift-package-manager/choose-package-products.png" caption="Ensure that the package is added to the `Runner` target" />

1. Ensure that `FlutterGeneratedPluginSwiftPackage` was added to **Frameworks,
   Libraries, and Embedded Content**.

   <DashImage image="development/packages-and-plugins/swift-package-manager/add-generated-framework.png" caption="Ensure that `FlutterGeneratedPluginSwiftPackage` was added to **Frameworks, Libraries, and Embedded Content**" />

### Step 2: Add Run Prepare Flutter Framework Script Pre-Action {:.no_toc}

**The following steps must be completed for each flavor.**

1. Go to **Product > Scheme > Edit Scheme**.
1. Expand the **Build** section in the left side bar.
1. Click **Pre-actions**.
1. Click the <Icon id="add" label="add/plus"></Icon> button and
   select **New Run Script Action** from the menu.
1. Click the **Run Script** title and change it to:

   ```plaintext
   Run Prepare Flutter Framework Script
   ```

1. Change the **Provide build settings from** to the `Runner` app.
1. Input the following in the text box:

   ```sh
   "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" prepare
   ```

   <DashImage image="development/packages-and-plugins/swift-package-manager/add-flutter-pre-action.png" caption="Add **Run Prepare Flutter Framework Script** build pre-action" />

### Step 3: Run app {:.no_toc}

1. Run the app in Xcode.
1. Ensure that  **Run Prepare Flutter Framework Script** runs as a pre-action
   and that `FlutterGeneratedPluginSwiftPackage` is a target dependency.

   <DashImage image="development/packages-and-plugins/swift-package-manager/flutter-pre-action-build-log.png" caption="Ensure **Run Prepare Flutter Framework Script** runs as a pre-action" />

1. Ensure that the app runs on the command line with `flutter run`.

[turn on Swift Package Manager]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-turn-on-swift-package-manager
[file an issue]: https://github.com/flutter/flutter/issues/new?template=2_bug.yml


</Tab>
<Tab name="macOS project">

Once you [turn on Swift Package Manager][], the Flutter CLI tries to migrate
your project to use Swift Package Manager the next time you run your app
using the CLI.

However, the Flutter CLI tool might be unable to migrate your project
automatically if there are unexpected modifications.

If the automatic migration fails, use the steps below to add Swift Package
Manager integration to a project manually.

Before migrating manually, [file an issue][]; this helps the Flutter team
improve the automatic migration process.
Include the error message and, if possible, include a copy of
the following files in your issue:

* `macos/Runner.xcodeproj/project.pbxproj`
* `macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme`
  (or the xcscheme for the flavor used)

### Step 1: Add FlutterGeneratedPluginSwiftPackage Package Dependency {:.no_toc}

1. Open your app (`macos/Runner.xcworkspace`) in Xcode.
1. Navigate to **Package Dependencies** for the project.

   <DashImage image="development/packages-and-plugins/swift-package-manager/package-dependencies.png" caption="The project's package dependencies" />

1. Click the <Icon id="add" label="add/plus"></Icon> button.
1. In the dialog that opens, click the **Add Local...**.
1. Navigate to `macos/Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage`
   and click the **Add Package**.
1. Ensure that it's added to the Runner Target and click **Add Package**.

   <DashImage image="development/packages-and-plugins/swift-package-manager/choose-package-products.png" caption="Ensure that the package is added to the `Runner` target" />

1. Ensure that `FlutterGeneratedPluginSwiftPackage` was added to **Frameworks,
   Libraries, and Embedded Content**.

   <DashImage image="development/packages-and-plugins/swift-package-manager/add-generated-framework.png" caption="Ensure that `FlutterGeneratedPluginSwiftPackage` was added to **Frameworks, Libraries, and Embedded Content**" />

### Step 2: Add Run Prepare Flutter Framework Script Pre-Action {:.no_toc}

**The following steps must be completed for each flavor.**

1. Go to **Product > Scheme > Edit Scheme**.
1. Expand the **Build** section in the left side bar.
1. Click **Pre-actions**.
1. Click the <Icon id="add" label="add/plus"></Icon> button
   and select **New Run Script Action** from the menu.
1. Click the **Run Script** title and change it to:

   ```plaintext
   Run Prepare Flutter Framework Script
   ```

1. Change the **Provide build settings from** to the `Runner` target.
1. Input the following in the text box:

   ```sh
   "$FLUTTER_ROOT"/packages/flutter_tools/bin/macos_assemble.sh prepare
   ```

   <DashImage image="development/packages-and-plugins/swift-package-manager/add-flutter-pre-action.png" caption="Add **Run Prepare Flutter Framework Script** build pre-action" />

### Step 3: Run app {:.no_toc}

1. Run the app in Xcode.
1. Ensure that  **Run Prepare Flutter Framework Script** runs as a pre-action
   and that `FlutterGeneratedPluginSwiftPackage` is a target dependency.

   <DashImage image="development/packages-and-plugins/swift-package-manager/flutter-pre-action-build-log.png" caption="Ensure `Run Prepare Flutter Framework Script` runs as a pre-action" />

1. Ensure that the app runs on the command line with `flutter run`.

[turn on Swift Package Manager]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-turn-on-swift-package-manager
[file an issue]: https://github.com/flutter/flutter/issues/new?template=2_bug.yml


</Tab>
</Tabs>

### Add to an existing app (add-to-app)

Flutter's Swift Package Manager support doesn't work with add-to-app scenarios.

To keep current on status updates, consult [flutter#146957][].

[flutter#146957]: https://github.com/flutter/flutter/issues/146957

### Add to a custom Xcode target

Your Flutter Xcode project can have custom [Xcode targets][] to build additional
products, like frameworks or unit tests.
You can add Swift Package Manager integration to these custom Xcode targets.

Follow the steps in
[How to add Swift Package Manager integration to a project _manually_][manualIntegration].

In [Step 1][manualIntegrationStep1], list item 6 use your custom target instead
of the `Flutter` target.

In [Step 2][manualIntegrationStep2], list item 6 use your custom target instead
of the `Flutter` target.

[Xcode targets]: https://developer.apple.com/documentation/xcode/configuring-a-new-target-in-your-project
[manualIntegration]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-add-swift-package-manager-integration-to-a-flutter-app-manually
[manualIntegrationStep1]: /packages-and-plugins/swift-package-manager/for-app-developers/#step-1-add-fluttergeneratedpluginswiftpackage-package-dependency
[manualIntegrationStep2]: /packages-and-plugins/swift-package-manager/for-app-developers/#step-2-add-run-prepare-flutter-framework-script-pre-action

## How to remove Swift Package Manager integration

To add Swift Package Manager integration, the Flutter CLI migrates your project.
This migration updates your Xcode project to add Flutter plugin dependencies.

To undo this migration:

1. [Turn off Swift Package Manager][].

1. Clean your project:

   ```sh
   flutter clean
   ```

1. Open your app (`ios/Runner.xcworkspace` or `macos/Runner.xcworkspace`) in
   Xcode.

1. Navigate to **Package Dependencies** for the project.

1. Click the `FlutterGeneratedPluginSwiftPackage` package, then click
   the <Icon id="remove" label="remove/minus"></Icon> button.

   <DashImage image="development/packages-and-plugins/swift-package-manager/remove-generated-package.png" caption="The `FlutterGeneratedPluginSwiftPackage` to remove" />

1. Navigate to **Frameworks, Libraries, and Embedded Content** for the `Runner`
   target.

1. Click `FlutterGeneratedPluginSwiftPackage`, then click
   the <Icon id="remove" label="remove/minus"></Icon> button.

   <DashImage image="development/packages-and-plugins/swift-package-manager/remove-generated-framework.png" caption="The `FlutterGeneratedPluginSwiftPackage` to remove" />

1. Go to **Product > Scheme > Edit Scheme**.

1. Expand the **Build** section in the left side bar.

1. Click **Pre-actions**.

1. Expand **Run Prepare Flutter Framework Script**.

1. Click the <Icon id="delete" label="delete/trash"></Icon> button.

   <DashImage image="development/packages-and-plugins/swift-package-manager/remove-flutter-pre-action.png" caption="The build pre-action to remove" />

[Turn off Swift Package Manager]: /packages-and-plugins/swift-package-manager/for-app-developers/#how-to-turn-off-swift-package-manager

## How to use a Swift Package Manager Flutter plugin that requires a higher OS version

If a Swift Package Flutter Manager plugin requires a higher OS version than
the project, you might get an error like this:

```plaintext
Target Integrity (Xcode): The package product 'plugin_name_ios' requires minimum platform version 14.0 for the iOS platform, but this target supports 12.0
```

To use the plugin:

1. Open your app (`ios/Runner.xcworkspace` or `macos/Runner.xcworkspace`) in
   Xcode.

1. Increase your app's target **Minimum Deployments**.

   <DashImage image="development/packages-and-plugins/swift-package-manager/minimum-deployments.png" caption="The target's **Minimum Deployments** setting" />

1. If you updated your iOS app's **Minimum Deployments**,
   regenerate the iOS project's configuration files:

   ```sh
   flutter build ios --config-only
   ```

1. If you updated your macOS app's **Minimum Deployments**,
   regenerate the macOS project's configuration files:

   ```sh
   flutter build macos --config-only
   ```

