К основному содержанию
скилл CX Codex

cocoapods-to-spm — скилл для Claude Code: миграция Capacitor iOS

Переводит iOS-проект Capacitor с CocoaPods на Swift Package Manager и подсказывает, что делать с плагинами без Package.swift.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add Cap-go/capgo-skills --skill cocoapods-to-spm -a claude-code
Открыть на GitHub

Что делает cocoapods-to-spm

Скилл ведёт миграцию по шагам: сначала читает package.json, ios/App/Podfile, Podfile.lock и project.pbxproj, потом ищет плагины без Package.swift и разбирается с каждым. Отдельно проверяет, какие поды вообще не относятся к Capacitor — Firebase, аналитику, вручную добавленные SDK. Их придётся заменять на SPM-пакеты вендора уже после миграции.

Дальше два пути. Для большинства приложений — npx cap spm-migration-assistant, он сохраняет существующий Xcode-проект вместе с кастомными настройками. Второй вариант — свежий каркас, если папка ios/ почти не отличается от шаблона. Скилл советует не оставлять гибридную схему, где Podfile живёт рядом с CapApp-SPM: CLI считает проект SPM только при наличии ios/App/CapApp-SPM/, и удаление этой папки молча возвращает npx cap sync к CocoaPods.

Есть нюансы, о которых лучше знать заранее. ios/App/CapApp-SPM/Package.swift перегенерируется на каждом npx cap sync ios, поэтому правки в нём теряются — настройки уходят в capacitor.config.*. Плагин попадает в сборку только если в корне его npm-пакета лежит Package.swift; остальные пропускаются с предупреждением, а их нативный код тихо отсутствует в рантайме. Обычные .framework не годятся как SPM binary target, нужен .xcframework. Скилл рассчитан на Capacitor 8.x и 9.x; на 6.x и 7.x он советует сначала обновить Capacitor.

Какие задачи решает

  • перевести существующий iOS-проект Capacitor с CocoaPods на SPM
  • найти плагины без Package.swift и решить, что с ними делать
  • восстановить прерванный npx cap spm-migration-assistant
  • разобраться с предупреждением о несовместимых с SPM плагинах при npx cap sync
  • подготовить проект к Capacitor 9, где SPM идёт по умолчанию

Примеры запросов агенту

  • прогони миграцию моего Capacitor-приложения с CocoaPods на SPM
  • почему npx cap sync пишет, что плагин несовместим с SPM?
  • подготовь ios-проект к Capacitor 9 и убери Podfile

Как установить cocoapods-to-spm

1Через Skills CLI (Vercel)

npx skills add Cap-go/capgo-skills --skill cocoapods-to-spm -a claude-code

2Вручную: положить файлы

~/.claude/skills/cocoapods-to-spm/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/cocoapods-to-spm/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о cocoapods-to-spm

Как установить cocoapods-to-spm в Claude?

Одной командой: npx skills add Cap-go/capgo-skills --skill cocoapods-to-spm -a claude-code. После этого скилл лежит в ~/.claude/skills/cocoapods-to-spm/SKILL.md.

Что делает cocoapods-to-spm?

Проводит миграцию iOS-части приложения Capacitor с CocoaPods на Swift Package Manager: инспектирует поды и плагины, находит блокеры, выбирает путь через npx cap spm-migration-assistant или свежий каркас.

С какими версиями Capacitor он работает?

Поддерживаются 8.x и 9.x. На 6.x и 7.x скилл советует сначала обновить Capacitor, а уже потом переходить на SPM.

Исходный текст

SKILL.md · MIT
---
name: cocoapods-to-spm
description: Migrates an existing Capacitor iOS app from CocoaPods to Swift Package Manager (SPM) before CocoaPods Trunk goes read-only (expected December 2, 2026). Use when the app still has ios/App/Podfile, Pods/, Podfile.lock or App.xcworkspace and the user wants CapApp-SPM, runs or recovers from `npx cap spm-migration-assistant`, needs debug.xcconfig / CAPACITOR_DEBUG wired up, sees "Some installed Capacitor plugins are not compatible with SPM" or "<plugin> does not have a Package.swift", or plans the Capacitor 9 upgrade where SPM is the default. Do not use for adding SPM support inside a plugin repository (use capacitor-plugin-spm-support), the UIScene lifecycle migration (use capacitor-uiscene-migration), full version upgrades (use capacitor-app-upgrades), or generic iOS build debugging (use debugging-capacitor).
---

# CocoaPods to Swift Package Manager Migration

Move a Capacitor iOS app from CocoaPods to SPM without losing native project customizations.

## When to Use

TRIGGER when:
- `ios/App/Podfile`, `Pods/`, `Podfile.lock`, or `App.xcworkspace` exists and the user wants SPM.
- User asks about `npx cap spm-migration-assistant`, `CapApp-SPM`, `debug.xcconfig`, or `--packagemanager SPM`.
- User worries about CocoaPods Trunk becoming read-only (expected December 2, 2026), or about pods that can no longer be published/updated.
- `npx cap sync` warns `Some installed Capacitor plugins are not compatible with SPM` or `<plugin id> does not have a Package.swift`.
- Upgrading to Capacitor 9 and wanting to drop CocoaPods at the same time.

Do not use:
- Adding `Package.swift` / `CAPBridgedPlugin` to a plugin you maintain -> `capacitor-plugin-spm-support`.
- SceneDelegate / UIScene adoption (Capacitor 8.5+, required by Xcode 27) -> `capacitor-uiscene-migration`.
- The Capacitor major upgrade itself -> `capacitor-app-upgrades`, `capacitor-app-upgrade-v8-to-v9`.
- Build or runtime failures unrelated to dependency management -> `debugging-capacitor`.

## Why Now

- CocoaPods Trunk is expected to become read-only on **December 2, 2026**. Existing pods keep resolving, but no new pod versions get published, so plugin fixes will increasingly ship SPM-only.
- Capacitor 8+ scaffolds new iOS projects with SPM by default. Upgrading Capacitor does **not** convert an existing CocoaPods app.
- Capacitor 9 (currently `next` / alpha) only adds the `Cordova` product / `CapacitorCordova` pod when a Cordova plugin is installed. Native code that imports `Cordova` without a Cordova plugin breaks in either setup.

## How the CLI Decides

- The CLI treats the project as SPM if and only if `ios/App/CapApp-SPM/` exists. Deleting or renaming it silently flips `npx cap sync` back to CocoaPods behavior.
- `ios/App/CapApp-SPM/Package.swift` is regenerated on every `npx cap sync ios` (`// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands`). Put customizations in `capacitor.config.*`, never in that file.
- A plugin is included only if its npm package root has a `Package.swift`. Others are skipped with a warning; their native code is silently missing at runtime (`"X" plugin is not implemented on ios`).
- During sync, if a plugin's `Package.swift` pins `capacitor-swift-pm` to a different major, the CLI rewrites that file inside `node_modules` and warns `<id> is built for Capacitor <N>, it might cause issues`. Treat this as "upgrade the plugin", not as success.
- Cordova plugins get a generated package under `ios/capacitor-cordova-ios-plugins/sources/<Name>`. Plain `.framework` files are not supported as SPM binary targets (warning: `custom .framework files are not supported as binaryTarget in SPM`); they need an `.xcframework`.

## Command Policy

- Use the repo's package manager for installs and scripts; keep Capacitor CLI calls as `npx cap ...` so the project-local CLI runs.
- Run commands from the directory containing `capacitor.config.*`.

## Live Project Snapshot

Detected Capacitor, iOS, Cordova, and plugin dependencies:
!`node -e "const fs=require('fs');if(!fs.existsSync('package.json'))process.exit(0);const pkg=JSON.parse(fs.readFileSync('package.json','utf8'));const out=[];for(const section of ['dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(name.startsWith('@capacitor/')||name.startsWith('@capgo/')||name.startsWith('@capacitor-community/')||name.startsWith('@awesome-cordova-plugins/')||name.startsWith('cordova-')||name.includes('capacitor'))out.push(section+'.'+name+'='+version)}}console.log(out.sort().join('\n'))"`

Relevant iOS dependency files:
!`find ios -maxdepth 5 \( -name 'Podfile' -o -name 'Podfile.lock' -o -name 'Pods' -o -name 'App.xcworkspace' -o -name 'Package.swift' -o -name 'Package.resolved' -o -name 'CapApp-SPM' -o -name 'debug.xcconfig' -o -name 'project.pbxproj' -o -name 'Info.plist' -o -name '*.entitlements' -o -name 'GoogleService-Info.plist' \) 2>/dev/null`

## Procedure

### 1. Inspect (read-only)

1. Capacitor version in `package.json` (`@capacitor/ios`). 8.x and 9.x are supported; on 6.x/7.x, prefer upgrading first.
2. `ios/App/Podfile` and `Podfile.lock`: list every pod, and which ones are not Capacitor plugins (Firebase, analytics SDKs, custom pods added by hand).
3. For each Capacitor/Cordova plugin: does `node_modules/<pkg>/Package.swift` exist? Cordova plugins get a generated package, so only `NO` entries block:
   ```bash
   node -e "const fs=require('fs');const p=require('./package.json');for(const n of Object.keys({...p.dependencies,...p.devDependencies})){const d='node_modules/'+n;if(!fs.existsSync(d+'/ios')&&!fs.existsSync(d+'/plugin.xml'))continue;console.log((fs.existsSync(d+'/Package.swift')?'SPM     ':fs.existsSync(d+'/plugin.xml')?'CORDOVA ':'NO      ')+n)}"
   ```
4. `ios/App/App.xcodeproj/project.pbxproj`: signing, custom build settings, extra targets (widgets, notification service extensions), build phases, schemes.
5. `ios/App/App/`: `AppDelegate.swift`, `SceneDelegate.swift`, `Info.plist`, entitlements, `GoogleService-Info.plist`, custom Swift/ObjC files.

Report findings before editing: plugins without SPM, non-plugin pods that need an SPM replacement, and native customizations at risk.

### 2. Resolve blockers

For every `NO` plugin or non-plugin pod:
- Upgrade the plugin (most maintained plugins, including `@capacitor/*` and `@capgo/*`, ship `Package.swift`).
- Replace it with a maintained SPM-capable alternative.
- If the project owns the plugin, convert it with `capacitor-plugin-spm-support`.
- For third-party SDK pods added directly in the Podfile, add the vendor's SPM package to the App target in Xcode after migration.

Ask the user before proceeding if a critical plugin has no SPM path. Do not keep a hybrid Podfile + CapApp-SPM setup.

### 3. Choose a path

| Path | Use when |
|------|----------|
| `npx cap spm-migration-assistant` | Most apps; keeps the existing Xcode project and its customizations. |
| Fresh scaffold | `ios/` is close to the template (no extensions, few native edits). |
| Manual repair | The assistant ran partially or the project is heavily customized. |

### 4a. Run the migration assistant

Commit first. Requires CocoaPods (or Bundler) still installed because it runs `pod deintegrate`.

```bash
npx cap spm-migration-assistant
```

It runs `pod deintegrate`, deletes `Podfile`, `Podfile.lock`, and `App.xcworkspace`, extracts `ios/App/CapApp-SPM/`, writes `ios/debug.xcconfig` (`CAPACITOR_DEBUG = true`), adds `CAPACITOR_DEBUG = $(CAPACITOR_DEBUG)` to `Info.plist` if missing, then runs an iOS update that generates `Package.swift`. It ends with `To complete migration follow the manual steps at https://capacitorjs.com/docs/ios/spm#using-our-migration-tool`.

Two manual Xcode steps remain (`npx cap open ios`, which now opens `App.xcodeproj`):
1. Project `App` -> Package Dependencies -> `+` -> Add Local... -> select `ios/App/CapApp-SPM` -> Add Package, and link the `CapApp-SPM` library to the `App` target.
2. Project `App` -> Info -> Configurations -> Debug -> set the configuration file to `debug.xcconfig`.

Then `npx cap sync ios`.

### 4b. Fresh scaffold

Back up everything listed in step 1.5 first.

```bash
rm -rf ios
npx cap add ios --packagemanager SPM
npx cap sync ios
```

On Capacitor 8.5+ the new template already includes `SceneDelegate.swift` and `UIApplicationSceneManifest`. Restore icons, `Info.plist` keys, entitlements, signing, Firebase plist, custom sources, and extension targets by merging, not overwriting template files.

### 5. Optional SPM config in `capacitor.config.*`

Only when needed (all under `experimental.ios.spm`, verify the installed CLI version supports them):
- `swiftToolsVersion` (8.3+, default `'5.9'`): header of the generated `Package.swift`.
- `packageTraits` (8.3+): `{ "<plugin id>": ["TraitName", ".defaults"] }`; requires `swiftToolsVersion` >= `'6.1'`.
- `packageOptions` (8.4+): `{ "<plugin id>": { symlink: true, moduleAliases: { "Target": "Alias" } } }` for package name or module collisions.

### 6. UIScene check

The assistant changes dependency management only. If `Info.plist` lacks `UIApplicationSceneManifest`, the app is not on the scene lifecycle that Capacitor 8.5+ and Xcode 27 expect; run `npx cap migrate` or follow `capacitor-uiscene-migration`.

## Verification

```bash
# No CocoaPods leftovers
ls ios/App | grep -E 'Podfile|Pods|xcworkspace' && echo "LEFTOVERS" || echo "clean"
# CLI sees SPM and every plugin is included
npx cap sync ios 2>&1 | grep -Ei 'Package.swift|not compatible|built for Capacitor'
grep -c '.package(name:' ios/App/CapApp-SPM/Package.swift
# Plugin classes registered for runtime
node -e "console.log(require('./ios/App/App/capacitor.config.json').packageClassList)"
# Build without Xcode UI (project, not workspace)
xcodebuild -project ios/App/App.xcodeproj -scheme App -destination 'generic/platform=iOS Simulator' build
```

Also confirm in Xcode: `CapApp-SPM` linked to the App target, Debug uses `debug.xcconfig`, signing/bundle id/capabilities unchanged. On device, exercise each native plugin once (camera, push, purchases, etc.).

Commit `ios/App/CapApp-SPM/` and `ios/debug.xcconfig`. Follow `CapApp-SPM/.gitignore` for `Package.resolved` (newer templates ignore it).

## Error Handling

Load `references/troubleshooting.md` for the full table. Most common:

| Message / symptom | Fix |
|---|---|
| `Capacitor project is already using SPM, exiting.` | `CapApp-SPM/` already exists. Do manual repair, not the assistant. |
| `CocoaPods is not installed.` (assistant) | Install CocoaPods temporarily or use the fresh scaffold path. |
| `<id> does not have a Package.swift` / `Some installed Capacitor plugins are not compatible with SPM` | Upgrade, replace, or convert that plugin (step 2). |
| `"X" plugin is not implemented on ios` at runtime | Plugin skipped from `Package.swift`, or `packageClassList` missing it. Fix the plugin, re-sync, clean build. |
| `No such module 'Capacitor'` / `Missing package product 'CapApp-SPM'` | Local package not added/linked; redo manual step 1, then File -> Packages -> Reset Package Caches. |
| Debug-only features off (no WebView inspection, no debug logs) | `debug.xcconfig` not set on Debug configuration. |

## Output Format

For planning, return: current state (Capacitor version, pods, plugins without SPM, customizations at risk), chosen path and why, ordered steps, remaining Xcode/device-only checks.

© Cap-go · MIT · Cap-go/capgo-skills

Похожие скиллы

Всё по теме «Мобильная разработка» →
capacitor-app-spm-migration capawesome-team Скилл ведёт агента через перенос iOS-зависимостей Capacitor-приложения с CocoaPods на Swift Package Manager. Пригодится, когда ios/ уже оброс кастомными файлами. CX Codex +1 593установок spm-build-analysis AvdLee Скилл находит узкие места в зависимостях Swift Package Manager, плагинах сборки и структуре модулей Xcode. Пригодится, когда затягивается чистая или инкрементальная сборка проекта. CX Codex +1 3 400установок kotlin-tooling-cocoapods-spm-migration JetBrains Скилл переносит KMP-проект с CocoaPods на Swift Package Manager: меняет Gradle DSL, импорты Kotlin и настройки Xcode. Нужен для поэтапной миграции. CX Codex +1 1 800установок xcode-build-orchestrator AvdLee Ведёт оптимизацию сборки Xcode в два этапа: сначала замеряет и предлагает план, потом правит код после вашего одобрения. CX Codex +1 3 600установок axiom-build CharlesWiltgen Маршрутизирует сбои сборки iOS и macOS, зависания симулятора и ошибки Xcode до разбора кода приложения. CX Codex +1 1 300установок ios-simulator-skill conorluddy 30 Python-скриптов для сборки, тестирования и управления iOS-приложениями в симуляторе. Навигация по accessibility-дереву вместо скриншотов, работа с логами, симуляция GPS и внешнего вида — всё через структурированные данные. CX Codex +1 2 400установок

Из того же набора29

tailwind-capacitor Настраивает Tailwind CSS v4 в приложениях на Capacitor и разбирает грабли мобильной вёрстки: safe-area, тёмная тема, варианты под iOS и Android. CX Codex +1 955установок framework-to-capacitor Настраивает статическую сборку Next.js, Nuxt, Angular, SvelteKit или Vite так, чтобы Capacitor упаковал её в приложение для iOS и Android. CX Codex +1 870установок capgo-live-updates Помогает подключить и отладить живые обновления Capgo в приложении на Capacitor: первый бандл, режимы autoUpdate, откаты. CX Codex +1 848установок konsta-ui Скилл помогает агенту собирать интерфейс Capacitor-приложения на Konsta UI v5 с Tailwind CSS v4 и разбираться, почему компоненты остались без стилей. CX Codex +1 836установок capacitor-app-upgrades Ведёт приложение на Capacitor через мажорные версии по одной, с обязательным шагом UIScene для iOS перед Capacitor 9. CX Codex +1 771установок capacitor-plugin-upgrades Ведёт плагин Capacitor через один или несколько мажорных апгрейдов, от 4 до 9, с аудитом iOS UIScene. Пригодится мейнтейнерам, у которых peerDependencies отстали от приложения. CX Codex +1 730установок sqlite-to-fast-sql Переносит Capacitor-приложение с bridge-плагинов SQLite на @capgo/capacitor-fast-sql, сохраняя данные, транзакции и BLOB. CX Codex +1 706установок capgo-release-management Скилл ведёт релизы Capgo из CLI: загрузка бандлов, каналы, постепенный выкат, откат и шифрование. Пригодится, когда релиз ломается на загрузке или нужно откатить бандл. CX Codex +1 705установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой