
capacitor-best-practices
Review and set up Capacitor apps against current best practices (Capacitor 8.5 stable, 9 alpha via @next). Use for a Capacitor codebase review, capacitor.config.ts audit, new project setup, aligning @capacitor/core/cli/ios/android and plugin majors, plugin patterns (availability checks, checkPermissions/requestPermissions, error code handling, web fallbacks), or release prep; or on " " plugin is not implemented on ios, Could not find the web assets directory, platform has not been added yet, a dev server.url shipped to production, lost edits in android/app/src/main/assets/public, SPM vs CocoaPods, or AppDelegate/UIScene drift. Do not use for security audits (capacitor-security), performance (capacitor-performance), tests (capacitor-testing), crashes (debugging-capacitor), major upgrades (capacitor-app-upgrades), SPM migration (cocoapods-to-spm), UIScene adoption (capacitor-uiscene-migration), or live updates (capgo-live-updates).
- Installs
- 2.7K
- Last 24h
- +13
- Trending rank
- #7669
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-best-practices- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads capacitor-best-practices automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Capacitor Best Practices
Review a Capacitor app for structural mistakes that cause broken builds, lost edits, production leaks, and plugin crashes. Route deep topics to the sibling skill that owns them.
When to Use
TRIGGER when:
- The user asks for a general code/architecture review of a Capacitor or Ionic + Capacitor app.
- Setting up a new Capacitor project or adding iOS/Android to an existing web app.
capacitor.config.ts|jsonreview:webDir,server.url,cleartext, plugin config, env-specific config.- Version drift between
@capacitor/core,@capacitor/cli,@capacitor/ios,@capacitor/android, or plugin majors that do not match Capacitor's major. - Plugin usage review: missing
npx cap sync, no availability check, no permission flow, matching on error message strings. - Errors such as
"<Plugin>" plugin is not implemented on ios,Could not find the web assets directory,ios platform has not been added yet. - Pre-release sanity checklist across config, native projects, and live updates.
Do not use:
- Security audit, secrets, storage, pinning, CSP ->
capacitor-security; Xcode hardening ->capacitor-ios-security-hardening. - Bundle size, startup time, memory, bridge profiling ->
capacitor-performance. - Unit/E2E test setup and plugin mocking ->
capacitor-testing. - Crashes, white screen, native logs ->
debugging-capacitor,ios-android-logs. - Major upgrades ->
capacitor-app-upgrades(8 -> 9:capacitor-app-upgrade-v8-to-v9). - CocoaPods -> SPM ->
cocoapods-to-spm; UIScene adoption ->capacitor-uiscene-migration. - Finding or installing a specific plugin ->
capacitor-plugins. - Store submission and review ->
capacitor-app-store,capacitor-apple-review-preflight; CI ->capacitor-ci-cd; live updates ->capgo-live-updates.
Current baseline (October 2026)
Capacitor 8 (stable, latest 8.5.x) | Capacitor 9 (next, alpha) | |
|---|---|---|
| Node | 22+ | 24+ |
| iOS min / Xcode | iOS 15 / Xcode 26 (8.5 adopts UIScene so Xcode 27 builds work) | iOS 16 / Xcode 27+ |
| Android | minSdk 24, compile/target 36, AGP 8.13, Gradle 8.14.3 | minSdk 26, compile/target 37, AGP 9.2.1, Gradle 9.5.1 |
| iOS deps | SPM default for new projects | SPM default |
CocoaPods Trunk is expected to go read-only on December 2, 2026. Recommend SPM for every app still on CocoaPods. Install Capacitor 9 only with @next until it reaches GA, and do not recommend it for production apps.
Review workflow
- Inventory (read-only).
npx cap doctor # installed vs latest Capacitor packages npx cap ls # plugins Capacitor detects per platform cat capacitor.config.ts 2>/dev/null || cat capacitor.config.json ls ios/App/Podfile ios/App/CapApp-SPM 2>/dev/null # CocoaPods or SPM grep -nE "minSdkVersion|compileSdkVersion|targetSdkVersion" android/variables.gradle - For large codebases, write a TODO list of areas (config, versions, plugins, native iOS, native Android, live updates, release) and review one at a time.
- Report findings before editing, grouped by severity, each with file:line and the fix. Ask before invasive changes (upgrading a major, migrating to SPM, enabling R8, changing
appId). - Fix, loading the matching reference.
- Run Verification.
Rules that matter most
- Keep Capacitor packages on one version.
@capacitor/core,cli,ios,androidmust match. Plugin majors must match the Capacitor major (official and@capgo/*plugins follow it: v8 plugins for Capacitor 8). npx cap syncafter every plugin install/removal and every config change. Missing sync produces"<Plugin>" plugin is not implemented on <platform>.- Never edit generated web assets.
android/app/src/main/assets/public/andios/App/App/public/are overwritten bycap copy/sync. Editsrc/and rebuild. - Commit
ios/andandroid/. They are source code with your native customizations, not build output. Do commitcapacitor.config.*; do not commitnode_modules,Pods/, build dirs. - No dev settings in release config.
server.url,server.cleartext,allowNavigationto dev hosts,webContentsDebuggingEnabled: true. Gate them on an env var (see references/config-and-project.md). On Capacitor 9, usenpx cap run <platform> --url <dev-url>for live reload. - Feature-detect before calling plugins.
Capacitor.isNativePlatform(),Capacitor.getPlatform(),Capacitor.isPluginAvailable('Name'). Provide a web fallback or hide the feature. - Use the permission API. Call
checkPermissions()thenrequestPermissions()for official plugins that expose them, and handledeniedwith a path to Settings. Add the matchingNS*UsageDescriptionkeys / Android permissions. - Branch on
error.code, noterror.message. Messages change between versions and platforms. Official plugins expose structured codes (for exampleOS-PLUG-CAMR-0006for a cancelled camera capture in@capacitor/camera8.1+ new APIs); Capacitor core usesUNIMPLEMENTED/UNAVAILABLE. - Move large binary data as files, not base64. Pass file paths/URIs across the bridge and render with
Capacitor.convertFileSrc(). - iOS lifecycle is scene-based from Capacitor 8.5. After adopting UIScene, AppDelegate
application(_:open:options:),continue userActivity, and foreground/background callbacks stop firing. Move custom native code toSceneDelegate(capacitor-uiscene-migration). AvoidUIScreen.mainand idiom-based layout for resizable windows. - Live updates: call
CapacitorUpdater.notifyAppReady()on every launch, and apply manual updates withnext()(on background/relaunch) rather thanset()mid-session. Details incapgo-live-updates. - Secrets never go in the app. Anything in the bundle or
capacitor.configis extractable. Hand off tocapacitor-securityfor anything beyond this rule.
References
Only load a reference when its topic is in play.
| Reference | Load when |
|---|---|
| references/config-and-project.md | Reviewing capacitor.config, env-specific builds, repo layout, .gitignore, version alignment |
| references/plugins.md | Plugin install/sync, availability checks, permissions, error codes, web fallbacks, lazy loading, mocking |
| references/native-projects.md | iOS SPM vs CocoaPods, UIScene, deployment targets; Android variables.gradle, R8, Capacitor 9 Gradle changes |
| references/release-checklist.md | Preparing a release build or reviewing release readiness |
Verification
# Versions aligned (all @capacitor/* core packages show the same version)
npm ls @capacitor/core @capacitor/cli @capacitor/ios @capacitor/android
npx cap doctor
# Web build exists where webDir points, then sync succeeds without errors
npm run build && npx cap sync
# No dev server or debug flags in the synced native config
grep -nE "\"url\"|cleartext|webContentsDebuggingEnabled" \
android/app/src/main/assets/capacitor.config.json ios/App/App/capacitor.config.json
# No hand edits in generated web assets (should show nothing)
git status --porcelain android/app/src/main/assets/public ios/App/App/public
# Error handling does not depend on message text
grep -rnE "error\.message\s*(===|==|\.includes)" src/
# Native builds
cd android && ./gradlew assembleRelease && cd ..
xcodebuild -project ios/App/App.xcodeproj -scheme App -configuration Release -destination 'generic/platform=iOS' build CODE_SIGNING_ALLOWED=NO
With CocoaPods, build ios/App/App.xcworkspace with -workspace instead of -project. Finally run on a real device and exercise each plugin-backed feature, including permission denial.
Error handling
| Error | Cause | Fix |
|---|---|---|
"<Plugin>" plugin is not implemented on ios (or android) | Plugin installed but not synced, plugin has no implementation for that platform, or plugin major does not match Capacitor | npx cap sync; check npx cap ls; install the plugin version matching your Capacitor major; rebuild the native app |
"<Plugin>.<method>()" is not implemented on web | Calling a native-only method in the browser | Guard with Capacitor.isNativePlatform() or isPluginAvailable, provide a web fallback |
Could not find the web assets directory: ./dist. | webDir wrong or web app not built | Build first; set webDir to the real output folder (dist, www, build, out) |
ios platform has not been added yet. | Native project missing | npx cap add ios (SPM default) or restore the committed ios/ folder |
Invalid App ID "<id>" | appId not reverse-domain or contains invalid characters | Use com.company.app style; changing it on a published app creates a new store listing |
| App loads a LAN IP or blank screen in production | server.url shipped from a dev config | Remove it, rebuild, npx cap sync, rebuild the native app |
net::ERR_CLEARTEXT_NOT_PERMITTED | HTTP request on Android | Use HTTPS; cleartext only in dev config (see capacitor-security) |
pod install fails / CocoaPods spec errors | CocoaPods trunk deprecation, outdated specs | Migrate with cocoapods-to-spm |
Deep links or resume handling stopped on iOS after 8.5 | Custom code still in AppDelegate after UIScene adoption | Move it to SceneDelegate (capacitor-uiscene-migration) |
Resources
- Capacitor docs: https://capacitorjs.com/docs
- Config reference: https://capacitorjs.com/docs/config
- Environment-specific configurations: https://capacitorjs.com/docs/guides/environment-specific-configurations
- Updating to 8.5 (UIScene): https://capacitorjs.com/docs/updating/8-5
- Capgo docs: https://capgo.app/docs/
FAQ
What does the capacitor-best-practices skill do?
Review and set up Capacitor apps against current best practices (Capacitor 8.5 stable, 9 alpha via @next). Use for a Capacitor codebase review, capacitor.config.ts audit, new project setup, aligning @capacitor/core/cli/ios/android and plugin majors, plugin patterns (availability checks, checkPermissions/requestPermissions, error code handling, web fallbacks), or release prep; or on " " plugin is not implemented on ios, Could not find the web assets directory, platform has not been added yet, a dev server.url shipped to production, lost edits in android/app/src/main/assets/public, SPM vs CocoaPods, or AppDelegate/UIScene drift. Do not use for security audits (capacitor-security), performance (capacitor-performance), tests (capacitor-testing), crashes (debugging-capacitor), major upgrades (capacitor-app-upgrades), SPM migration (cocoapods-to-spm), UIScene adoption (capacitor-uiscene-migration), or live updates (capgo-live-updates).
How do I install capacitor-best-practices?
Run npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-best-practices in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/capacitor-best-practices/ (personal) or .claude/skills/capacitor-best-practices/ (project).
Which AI agents can use capacitor-best-practices?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is capacitor-best-practices safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains capacitor-best-practices?
It is published by cap-go in cap-go/capgo-skills. It has 2,684 recorded installs.
More from cap-go/capgo-skills
ionic-design
cap-go/capgo-skills
Builds and reviews Ionic Framework UI in Capacitor apps (Ionic 9 current, Ionic 8 still common) - page structure (ion-header/ion-content/ion-footer), lists, modern form syntax (label/labelPlacement on ion-input/ion-select), sheet modals, tabs + ion-router-outlet, CSS variable theming, dark palettes (palettes/dark.system.css, .ion-palette-dark), iOS vs MD mode, and Ionic 8 - 9 breaking changes (React Router 6, Vue Router 5, Angular 18-22 zoneless, removed ion-picker-legacy, boolean autocorrect, npx @ionic/migrate). Use when writing Ionic components, theming an Ionic app, fixing platform-mode styling, or upgrading @ionic/react, @ionic/vue, @ionic/angular. Do not use for Konsta UI (konsta-ui), Tailwind setup (tailwind-capacitor), raw safe-area CSS (safe-area-handling), keyboard resize (capacitor-keyboard), or Ionic Appflow/Enterprise migrations (ionic-appflow-migration, ionic-enterprise-sdk-migration).
capacitor-plugins
cap-go/capgo-skills
Pick, install, and wire up Capacitor plugins for native features (camera, filesystem, geolocation, biometrics, in-app purchases, social login, SQLite, calendar, contacts, health, BLE, NFC, etc.). Covers official @capacitor/ packages (Capacitor 8.5 stable, 9 alpha on next) plus the 145-package @capgo/ index, native permission keys (Info.plist, AndroidManifest, variables.gradle minSdk), npx cap sync / cap ls verification, and errors like '"Camera" plugin is not implemented on ios', 'unable to find plugin', UNIMPLEMENTED, and OS-PLUG- codes. Use for "which plugin should I use for X", adding a plugin, or a plugin call failing after install. Do not use for push setup (capacitor-push-notifications), splash assets (capacitor-splash-screen), keyboard layout (capacitor-keyboard), deep links (capacitor-deep-linking), OTA updates (capgo-live-updates), upgrading plugin source code (capacitor-plugin-upgrades), or adding SPM to a plugin (capacitor-plugin-spm-support).
debugging-capacitor
cap-go/capgo-skills
Diagnoses and fixes runtime bugs in Capacitor iOS/Android apps - white/blank screen on launch, startup crashes, "X" plugin is not implemented on ios/android, net::ERRCLEARTEXTNOTPERMITTED, App Transport Security blocks, CORS on capacitor://localhost, permission denials, live reload not connecting, and Capacitor 8.5+ UIScene regressions (appUrlOpen, universal links, pause/resume silent because AppDelegate callbacks stopped). Covers Safari Web Inspector, chrome://inspect, Xcode/LLDB, Android Studio, npx cap run --url (Capacitor 9) vs -l --host (8), xcrun simctl openurlprivacypush, xcrun devicectl device process launchopenURL, xctrace. Do not use for only reading device logs (ios-android-logs), the UIScene migration itself (capacitor-uiscene-migration), deep-link setup (capacitor-deep-linking), speed (capacitor-performance), crash SDKs (capacitor-native-observability), tests (capacitor-testing), or upgrades/build errors (capacitor-app-upgrades, cocoapods-to-spm).
capacitor-testing
cap-go/capgo-skills
Testing guide for Capacitor apps and plugins. Covers web-layer unit and component tests with Vitest and mocked Capacitor plugins (vi.mock('@capacitor/core'), registerPlugin), Playwright for the web build, Appium E2E with NATIVEAPP / WEBVIEW context switching, native plugin unit tests with Swift Testing vs XCTest (what can migrate, CAPPluginCall patterns, xcodebuild test on a simulator) and Android JUnit, plus an agent-driven verification loop on simulators and devices (build, install, launch, screenshot, UI hierarchy, tap, logs) with xcrun simctl, xcrun devicectl, adb, Xcode MCP device tools, and live reload via npx cap run --url (Capacitor 9) or -l --host --port (Capacitor 8). Use when adding tests, mocking plugins, "does it work on device", verifying a UI change on a simulator, migrating XCTest to Swift Testing, or setting up test CI. Do not use for crash log capture (ios-android-logs), WebView debugging sessions (debugging-capacitor), or build pipelines (capacitor
safe-area-handling
cap-go/capgo-skills
Fixes notch, Dynamic Island, home indicator, display cutout, and system bar overlap in Capacitor apps. Covers viewport-fit=cover + env(safe-area-inset-), the Capacitor 8 SystemBars core plugin (insetsHandling, injected --safe-area-inset- CSS variables for Android WebView < 140, removal of android.adjustMarginsForEdgeToEdge), Android 15/16 enforced edge-to-edge (overlaysWebView and backgroundColor of @capacitor/status-bar no longer work at targetSdk 36), iOS contentInset, and insets that change at runtime on rotation, iPad/foldable resizable windows. Use when headers sit under the status bar, tab bars hide behind the gesture bar, env() returns 0 on Android, or layout broke after upgrading to Capacitor 8 / targetSdk 35+. Do not use for keyboard overlap (capacitor-keyboard), Ionic/Konsta component theming (ionic-design, konsta-ui), Tailwind utility setup (tailwind-capacitor), or iOS multi-window/resizability adoption (capacitor-ios-resizability).
capacitor-deep-linking
cap-go/capgo-skills
Implements and debugs deep links in Capacitor apps - custom URL schemes, iOS Universal Links (apple-app-site-association, Associated Domains entitlement), Android App Links (assetlinks.json, autoVerify), and routing via @capacitor/app appUrlOpen + App.getLaunchUrl(). Covers the Capacitor 8.5+ UIScene change where AppDelegate application(:open:options:) and continue userActivity stop being called and custom handling must move to SceneDelegate, plus cold vs warm launch testing. Use when links open Safari/Chrome instead of the app, appUrlOpen never fires, the launch URL is lost on cold start, or OAuth redirects do not return to the app. Do not use for the full UIScene migration (capacitor-uiscene-migration), push notification taps (capacitor-push-notifications), or social login plugin setup (capacitor-plugins).
Popular code quality & workflow skills
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
improve-codebase-architecture
mattpocock/skills
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
handoff
mattpocock/skills
Compact the current conversation into a handoff document for another agent to pick up.
domain-modeling
mattpocock/skills
Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.
codebase-design
mattpocock/skills
Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.