---
description: Learn how to use Swift Package Manager (SPM) package traits in Capacitor 8 to conditionally enable optional plugin dependencies like SQLCipher.
title: How to Use SPM Package Traits in Capacitor 8 - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-use-spm-package-traits-in-capacitor.png
---

<!doctype html> 

[Skip to content ](#how-to-use-spm-package-traits-in-capacitor-8) 

[🖥️ Introducing the **Capacitor Electron Platform** — build desktop apps for macOS, Windows, and Linux. Free & open source. ](/blog/announcing-the-capacitor-electron-platform/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ Related Posts ](#related-posts)
* [ Try Capawesome Cloud ](#try-capawesome-cloud)
* [ Conclusion ](#conclusion)

* Related links

# How to Use SPM Package Traits in Capacitor 8[¶](#how-to-use-spm-package-traits-in-capacitor-8 "Permanent link")

Capacitor 8 now supports Swift Package Manager (SPM) package traits, bringing feature-flag-like capabilities to your iOS plugin dependencies. If you've ever needed to toggle an optional dependency — like enabling SQLCipher encryption for a SQLite plugin — you can now do it directly from your Capacitor config. This was previously only possible with CocoaPods subspecs, and since SPM is the default package manager in Capacitor, this fills an important gap.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1) ](/) 

## What Are SPM Package Traits?[¶](#what-are-spm-package-traits "Permanent link")

Package traits were introduced in [SE-0450](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md), a Swift Evolution proposal that shipped with Swift 6.1\. In short, traits act as feature flags for Swift packages. They let package authors:

* **Conditionally compile code** using `#if TraitName` directives
* **Toggle optional dependencies** so consumers only pull in what they need
* **Define default traits** that activate automatically unless explicitly disabled

If you're familiar with CocoaPods subspecs or Cargo features in Rust, traits serve a similar purpose. A plugin can declare a set of traits, and the consumer picks which ones to enable.

For example, a SQLite package might define a default `SQLite` trait that uses the system-provided SQLite, and an optional `SQLCipher` trait that swaps in an encrypted variant. The consumer decides at build time which variant they want — without the plugin author needing to maintain separate packages.

## Why This Matters for Capacitor[¶](#why-this-matters-for-capacitor "Permanent link")

When Capacitor moved to SPM as the default package manager (starting with Capacitor 8), plugin authors lost the ability to offer optional dependency variants. CocoaPods had subspecs for this, but SPM had no equivalent — until now.

Without trait support, a plugin author who wanted to offer an optional feature like SQLCipher encryption had two choices: bundle the dependency unconditionally (increasing binary size and adding compliance concerns), or maintain a separate plugin package entirely. Neither option was great.

With Capacitor CLI 8.3.0+, the generated `Package.swift` can now include trait information, letting you opt in to exactly the features you need.

## How It Works[¶](#how-it-works "Permanent link")

Capacitor introduces two new configuration options under the `experimental` namespace in your `capacitor.config.json`:

1. **`experimental.ios.spm.swiftToolsVersion`** — Sets the `swift-tools-version` in the generated `Package.swift`. Must be `"6.1"` or higher for traits to work.
2. **`experimental.ios.spm.packageTraits`** — Maps plugin package names to arrays of trait names you want to enable.

Here's what the configuration looks like in practice:

capacitor.config.json

`[](#%5F%5Fcodelineno-0-1){
[](#%5F%5Fcodelineno-0-2)  "appId": "com.example.app",
[](#%5F%5Fcodelineno-0-3)  "appName": "MyApp",
[](#%5F%5Fcodelineno-0-4)  "experimental": {
[](#%5F%5Fcodelineno-0-5)    "ios": {
[](#%5F%5Fcodelineno-0-6)      "spm": {
[](#%5F%5Fcodelineno-0-7)        "swiftToolsVersion": "6.1",
[](#%5F%5Fcodelineno-0-8)        "packageTraits": {
[](#%5F%5Fcodelineno-0-9)          "@capawesome-team/capacitor-sqlite": ["SQLCipher"]
[](#%5F%5Fcodelineno-0-10)        }
[](#%5F%5Fcodelineno-0-11)      }
[](#%5F%5Fcodelineno-0-12)    }
[](#%5F%5Fcodelineno-0-13)  }
[](#%5F%5Fcodelineno-0-14)}
`

After running `npx cap sync`, the Capacitor CLI generates a `CapApp-SPM/Package.swift` that includes `traits: ["SQLCipher"]` in the dependency line for the SQLite plugin and uses `swift-tools-version: 6.1` at the top of the file.

## Real-World Example: The SQLite Plugin[¶](#real-world-example-the-sqlite-plugin "Permanent link")

The [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) is one of the first Capacitor plugins to use SPM package traits. It offers optional [SQLCipher](https://www.zetetic.net/sqlcipher/) encryption support that you can enable via a trait.

The plugin's `Package.swift` defines two traits:

Package.swift

`[](#%5F%5Fcodelineno-1-1)traits: [
[](#%5F%5Fcodelineno-1-2)    .default(enabledTraits: ["SQLite"]),
[](#%5F%5Fcodelineno-1-3)    .trait(
[](#%5F%5Fcodelineno-1-4)        name: "SQLite",
[](#%5F%5Fcodelineno-1-5)        description: "Uses the system-provided SQLite."
[](#%5F%5Fcodelineno-1-6)    ),
[](#%5F%5Fcodelineno-1-7)    .trait(
[](#%5F%5Fcodelineno-1-8)        name: "SQLCipher",
[](#%5F%5Fcodelineno-1-9)        description: "Enables SQLCipher encryption support."
[](#%5F%5Fcodelineno-1-10)    )
[](#%5F%5Fcodelineno-1-11)]
`

When the `SQLCipher` trait is enabled, the plugin conditionally includes the SQLCipher dependency and sets a compile-time flag:

Package.swift

`[](#%5F%5Fcodelineno-2-1)targets: [
[](#%5F%5Fcodelineno-2-2)    .target(
[](#%5F%5Fcodelineno-2-3)        name: "SqlitePlugin",
[](#%5F%5Fcodelineno-2-4)        dependencies: [
[](#%5F%5Fcodelineno-2-5)            // ...
[](#%5F%5Fcodelineno-2-6)            .product(name: "SQLCipher", package: "SQLCipher.swift",
[](#%5F%5Fcodelineno-2-7)                     condition: .when(traits: ["SQLCipher"]))
[](#%5F%5Fcodelineno-2-8)        ],
[](#%5F%5Fcodelineno-2-9)        swiftSettings: [
[](#%5F%5Fcodelineno-2-10)            .define("CAPAWESOME_INCLUDE_SQLCIPHER",
[](#%5F%5Fcodelineno-2-11)                    .when(traits: ["SQLCipher"]))
[](#%5F%5Fcodelineno-2-12)        ])
[](#%5F%5Fcodelineno-2-13)]
`

In the Swift source code, the plugin uses `#if` directives to guard encryption-specific functionality:

`[](#%5F%5Fcodelineno-3-1)#if CAPAWESOME_INCLUDE_SQLCIPHER
[](#%5F%5Fcodelineno-3-2)try connection.key(encryptionKey)
[](#%5F%5Fcodelineno-3-3)#else
[](#%5F%5Fcodelineno-3-4)throw CustomError.unavailable
[](#%5F%5Fcodelineno-3-5)#endif
`

This way, apps that don't need encryption get a smaller binary without the SQLCipher dependency, while apps that do need it simply enable the trait in their Capacitor config.

## For Plugin Authors[¶](#for-plugin-authors "Permanent link")

If you maintain a Capacitor plugin and want to add trait support, here's what you need to do in your `Package.swift`:

**1\. Set the Swift tools version to 6.1:**

`[](#%5F%5Fcodelineno-4-1)// swift-tools-version: 6.1
`

**2\. Define your traits:**

`[](#%5F%5Fcodelineno-5-1)traits: [
[](#%5F%5Fcodelineno-5-2)    .default(enabledTraits: ["Default"]),
[](#%5F%5Fcodelineno-5-3)    .trait(name: "Default", description: "Standard behavior."),
[](#%5F%5Fcodelineno-5-4)    .trait(name: "OptionalFeature", description: "Enables an optional feature.")
[](#%5F%5Fcodelineno-5-5)]
`

**3\. Add conditional dependencies:**

`[](#%5F%5Fcodelineno-6-1)dependencies: [
[](#%5F%5Fcodelineno-6-2)    .package(
[](#%5F%5Fcodelineno-6-3)        url: "https://github.com/example/optional-lib.git",
[](#%5F%5Fcodelineno-6-4)        from: "1.0.0"
[](#%5F%5Fcodelineno-6-5)    )
[](#%5F%5Fcodelineno-6-6)],
[](#%5F%5Fcodelineno-6-7)targets: [
[](#%5F%5Fcodelineno-6-8)    .target(
[](#%5F%5Fcodelineno-6-9)        name: "MyPlugin",
[](#%5F%5Fcodelineno-6-10)        dependencies: [
[](#%5F%5Fcodelineno-6-11)            .product(name: "OptionalLib", package: "optional-lib",
[](#%5F%5Fcodelineno-6-12)                     condition: .when(traits: ["OptionalFeature"]))
[](#%5F%5Fcodelineno-6-13)        ],
[](#%5F%5Fcodelineno-6-14)        swiftSettings: [
[](#%5F%5Fcodelineno-6-15)            .define("INCLUDE_OPTIONAL_FEATURE",
[](#%5F%5Fcodelineno-6-16)                    .when(traits: ["OptionalFeature"]))
[](#%5F%5Fcodelineno-6-17)        ])
[](#%5F%5Fcodelineno-6-18)]
`

**4\. Guard your code with conditional compilation:**

`[](#%5F%5Fcodelineno-7-1)#if INCLUDE_OPTIONAL_FEATURE
[](#%5F%5Fcodelineno-7-2)import OptionalLib
[](#%5F%5Fcodelineno-7-3)#endif
`

Keep in mind that traits should be additive — enabling a trait should add functionality, not remove it. This aligns with semantic versioning expectations and avoids surprises for consumers.

## Requirements and Limitations[¶](#requirements-and-limitations "Permanent link")

This feature is currently marked as **experimental** because Capacitor does not yet officially support Swift 6\. Here's what you need:

| Requirement   | Minimum Version |
| ------------- | --------------- |
| Capacitor CLI | 8.3.0+          |
| Xcode         | 16.3+           |
| Swift         | 6.1+            |

A few things to keep in mind:

* **Compatibility**: Setting `swift-tools-version` to `6.1` can cause issues with dependencies that were built with older Swift versions, particularly those using XCFrameworks. Test your app thoroughly after enabling this setting.
* **Experimental namespace**: Both config options live under the `experimental` block, signaling that the API may change in future Capacitor versions.
* **Swift 6 timeline**: The Capacitor team has indicated that full Swift 6 support is planned for a future major version (likely Capacitor 9), at which point these settings may move out of the experimental namespace.

## FAQ[¶](#faq "Permanent link")

### Why is this feature marked experimental if it already works in Capacitor 8.3.0+?[¶](#why-is-this-feature-marked-experimental-if-it-already-works-in-capacitor-830 "Permanent link")

Because it depends on Swift 6, which Capacitor doesn't officially support yet. The feature works today, but both config options live under the `experimental` namespace specifically to signal that the API may change once Capacitor adds full Swift 6 support — likely in Capacitor 9\. Treat it as usable but not yet a stable, permanent API surface.

### Will setting `swiftToolsVersion` to `6.1` break other CocoaPods or SPM dependencies in my project?[¶](#will-setting-swifttoolsversion-to-61-break-other-cocoapods-or-spm-dependencies-in-my-project "Permanent link")

It can, particularly with dependencies distributed as XCFrameworks built against older Swift versions. This is the main compatibility risk called out in the guide — test your app thoroughly after enabling this setting rather than assuming every existing dependency tolerates the newer tools version.

### Do I need to enable a trait to use the SQLite plugin at all, or only for encryption?[¶](#do-i-need-to-enable-a-trait-to-use-the-sqlite-plugin-at-all-or-only-for-encryption "Permanent link")

Only for encryption. The plugin ships a `SQLite` trait as the default, enabled automatically — the `SQLCipher` trait is what you opt into specifically to add encrypted database support. Skipping the trait config entirely still gives you a working, unencrypted SQLite plugin.

### As a plugin author, can enabling a trait remove functionality that's present by default?[¶](#as-a-plugin-author-can-enabling-a-trait-remove-functionality-thats-present-by-default "Permanent link")

That would go against how traits are meant to be designed. The guide's own guidance is that traits should be additive — enabling one should add functionality, not take it away — since that matches semantic versioning expectations and avoids surprising consumers who enable a trait expecting only new capabilities, not different default behavior.

### Is there a CocoaPods equivalent if I don't want to touch the experimental SPM namespace yet?[¶](#is-there-a-cocoapods-equivalent-if-i-dont-want-to-touch-the-experimental-spm-namespace-yet "Permanent link")

Yes — subspecs served this same purpose before SPM traits existed, and are what this feature is explicitly filling the gap for. See [How to Use CocoaPods Instead of SPM with Capacitor](/blog/how-to-use-cocoapods-with-capacitor/) if you'd rather stay off the experimental trait config for now.

## Related Posts[¶](#related-posts "Permanent link")

* [How to Migrate a Capacitor App to Swift Package Manager](/blog/how-to-migrate-a-capacitor-app-to-spm/)
* [How to Migrate a Capacitor Plugin to SPM](/blog/how-to-migrate-a-capacitor-plugin-to-spm/)
* [How to Use CocoaPods Instead of SPM with Capacitor](/blog/how-to-use-cocoapods-with-capacitor/)

## Try Capawesome Cloud[¶](#try-capawesome-cloud "Permanent link")

Build, deploy, and update your Capacitor apps with ease using Capawesome Cloud — with native builds, live updates, and app store publishing all in one platform.

[Try Capawesome Cloud Free](/)

## Conclusion[¶](#conclusion "Permanent link")

SPM package traits bring much-needed parity with CocoaPods for managing optional dependencies in Capacitor plugins. For app developers, it means you can now opt in to features like SQLCipher encryption with a simple config change. For plugin authors, it opens the door to offering flexible, modular plugins without maintaining separate packages.

If you want to learn more about encrypting SQLite databases with the SQLCipher trait, check out the guide on [Encrypting SQLite databases in Capacitor](/blog/encrypting-capacitor-sqlite-database/).

If you have questions or want to share how you're using traits in your plugins, join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW). And subscribe to the [Capawesome newsletter](/newsletter/) to stay up to date on the latest Capacitor news and plugin releases.

July 17, 2026 

Back to top

```json
{
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": "How to Use SPM Package Traits in Capacitor 8",
      "description": "Learn how to use Swift Package Manager (SPM) package traits in Capacitor 8 to conditionally enable optional plugin dependencies like SQLCipher.",
      "image": "https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png",
      "datePublished": "2026-03-25T00:00:00+00:00",
      "dateModified": "2026-07-17T00:00:00+00:00",
      "author": [
        {
          "@type": "Person",
          "name": "Robin Genz",
          "url": "https://github.com/robingenz"
        }
      ],
      "publisher": {
        "@type": "Organization",
        "name": "Capawesome",
        "url": "https://capawesome.io",
        "logo": {
          "@type": "ImageObject",
          "url": "https://capawesome.io/assets/images/logo.svg"
        }
      },
      "articleSection": "Capacitor",
      "keywords": ["Capacitor", "Guides", "SDKs"],
      "isPartOf": {
        "@type": "Blog",
        "@id": "https://capawesome.io/blog/#blog"
      },
      "mainEntityOfPage": "https://capawesome.io/blog/how-to-use-spm-package-traits-in-capacitor/",
      "url": "https://capawesome.io/blog/how-to-use-spm-package-traits-in-capacitor/"
    }
{
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://capawesome.io/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Blog",
          "item": "https://capawesome.io/blog/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "How to Use SPM Package Traits in Capacitor 8",
          "item": "https://capawesome.io/blog/how-to-use-spm-package-traits-in-capacitor/"
        }
      ]
    }
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What Are SPM Package Traits?", "acceptedAnswer": {"@type": "Answer", "text": "Package traits were introduced in SE-0450, a Swift Evolution proposal that shipped with Swift 6.1. In short, traits act as feature flags for Swift packages. They let package authors: Conditionally compile code using #if TraitName directives Toggle optional dependencies so consumers only pull in what they need Define default traits that activate automatically unless explicitly disabled If you're familiar with CocoaPods subspecs or Cargo features in Rust, traits serve a similar purpose. A plugin can declare a set of traits, and the consumer picks which ones to enable. For example, a SQLite package might define a default SQLite trait that uses the system-provided SQLite, and an optional SQLCipher trait that swaps in an encrypted variant. The consumer decides at build time which variant they want — without the plugin author needing to maintain separate packages."}}, {"@type": "Question", "name": "Why is this feature marked experimental if it already works in Capacitor 8.3.0+?", "acceptedAnswer": {"@type": "Answer", "text": "Because it depends on Swift 6, which Capacitor doesn't officially support yet. The feature works today, but both config options live under the experimental namespace specifically to signal that the API may change once Capacitor adds full Swift 6 support — likely in Capacitor 9. Treat it as usable but not yet a stable, permanent API surface."}}, {"@type": "Question", "name": "Will setting swiftToolsVersion to 6.1 break other CocoaPods or SPM dependencies in my project?", "acceptedAnswer": {"@type": "Answer", "text": "It can, particularly with dependencies distributed as XCFrameworks built against older Swift versions. This is the main compatibility risk called out in the guide — test your app thoroughly after enabling this setting rather than assuming every existing dependency tolerates the newer tools version."}}, {"@type": "Question", "name": "Do I need to enable a trait to use the SQLite plugin at all, or only for encryption?", "acceptedAnswer": {"@type": "Answer", "text": "Only for encryption. The plugin ships a SQLite trait as the default, enabled automatically — the SQLCipher trait is what you opt into specifically to add encrypted database support. Skipping the trait config entirely still gives you a working, unencrypted SQLite plugin."}}, {"@type": "Question", "name": "As a plugin author, can enabling a trait remove functionality that's present by default?", "acceptedAnswer": {"@type": "Answer", "text": "That would go against how traits are meant to be designed. The guide's own guidance is that traits should be additive — enabling one should add functionality, not take it away — since that matches semantic versioning expectations and avoids surprising consumers who enable a trait expecting only new capabilities, not different default behavior."}}, {"@type": "Question", "name": "Is there a CocoaPods equivalent if I don't want to touch the experimental SPM namespace yet?", "acceptedAnswer": {"@type": "Answer", "text": "Yes — subspecs served this same purpose before SPM traits existed, and are what this feature is explicitly filling the gap for. See How to Use CocoaPods Instead of SPM with Capacitor if you'd rather stay off the experimental trait config for now."}}], "url": "https://capawesome.io/blog/how-to-use-spm-package-traits-in-capacitor/"}
```
