Comprehensive reference for building cross-platform apps with Capacitor. Covers architecture, CLI, plugins, framework integration, best practices, and Capawesome Cloud.
Capacitor is a cross-platform native runtime for building web apps that run natively on iOS, Android, and the web. The web app runs in a native WebView, and Capacitor provides a bridge to native APIs via plugins.
A Capacitor app has three layers:
Data passed across the bridge must be JSON-serializable. Pass files as paths, not base64.
my-app/
android/ # Native Android project (committed to VCS)
ios/ # Native iOS project (committed to VCS)
App/
App/ # iOS app source files
App.xcodeproj/
src/ # Web app source code
dist/ or www/ or build/ # Built web assets
capacitor.config.ts # Capacitor configuration
package.json
The android/ and ios/ directories are full native projects -- they are committed to version control and can be modified directly.
capacitor.config.ts (preferred) or capacitor.config.json controls app behavior:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'My App',
webDir: 'dist',
server: {
// androidScheme: 'https', // default in Cap 6+
},
};
export default config;
For details, see App Configuration.
# 1. Create a web app (React example with Vite)
npm create vite@latest my-app -- --template react-ts
cd my-app && npm install
# 2. Install Capacitor
npm install @capacitor/core
npm install -D @capacitor/cli
# 3. Initialize Capacitor
npx cap init "My App" com.example.myapp --web-dir dist
# 4. Build web assets
npm run build
# 5. Add platforms
npm install @capacitor/android @capacitor/ios
npx cap add android
npx cap add ios
# 6. Sync and run
npx cap sync
npx cap run android
npx cap run ios
Web asset directories by framework:
dist//browser (Angular 17+ with application builder)distdistwwwFor the full guided creation flow, see capacitor-app-creation.
All commands: npx cap . Most important commands:
| Command | Purpose |
|---|---|
| ------- | ------- |
npx cap init | Initialize Capacitor in a project |
npx cap add | Add Android or iOS platform |
npx cap sync | Copy web assets + update native dependencies (run after every plugin install, config change, or web build) |
npx cap copy | Copy web assets only (faster, no native dependency update) |
npx cap run | Build, sync, and deploy to device/emulator |
npx cap run | Run with live reload |
npx cap open | Open native project in IDE |
npx cap build | Build native project |
npx cap doctor | Diagnose configuration issues |
npx cap ls | List installed plugins |
npx cap migrate | Automated upgrade to newer Capacitor version |
For the full CLI reference, see CLI Reference.
Capacitor works with any web framework. Framework-specific patterns:
NgZone.run().ngOnInit, remove in ngOnDestroy.For details, see capacitor-angular.
useCamera, useNetwork) that wrap Capacitor plugins.useEffect for listener registration with cleanup to prevent memory leaks.For details, see capacitor-react.
useCamera, useNetwork) using Vue 3 Composition API.onMounted, remove in onUnmounted.ref changes automatically (no NgZone equivalent needed).For details, see capacitor-vue.
Plugins are Capacitor's extension mechanism. Each plugin exposes a JS API backed by native implementations.
@capacitor/*) -- Camera, Filesystem, Geolocation, Preferences, etc.@capawesome/, @capawesome-team/) -- SQLite, NFC, Biometrics, Live Update, etc.@capacitor-community/*) -- AdMob, BLE, SQLite, Stripe, etc.@capacitor-firebase/*) -- Analytics, Auth, Messaging, Firestore, etc.@capacitor-mlkit/*) -- Barcode scanning, face detection, translation.@revenuecat/purchases-capacitor) -- In-app purchases.npm install @capacitor/camera
npx cap sync
After installation, apply any required platform configuration (permissions in AndroidManifest.xml, Info.plist entries, etc.) as documented by the plugin.
import { Camera, CameraResultType } from '@capacitor/camera';
const photo = await Camera.getPhoto({
quality: 90,
resultType: CameraResultType.Uri,
});
For the full plugin index (160+ plugins) and setup guides, see capacitor-plugins.
Create custom Capacitor plugins with native iOS (Swift) and Android (Java/Kotlin) implementations:
npm init @capacitor/plugin@latest.src/definitions.ts.src/web.ts.ios/Sources/.android/src/main/java/.npm run verify.Key rules:
registerPlugin() name in src/index.ts must match jsName on iOS and @CapacitorPlugin(name = "...") on Android.@objc and must be listed in pluginMethods (CAPBridgedPlugin).@PluginMethod() annotation and must be public.For full details, see capacitor-plugin-development.
import { Capacitor } from '@capacitor/core';
const platform = Capacitor.getPlatform(); // 'android' | 'ios' | 'web'
if (Capacitor.isNativePlatform()) { /* native-only code */ }
if (Capacitor.isPluginAvailable('Camera')) { /* plugin available */ }
Follow the check-then-request pattern:
const status = await Camera.checkPermissions();
if (status.camera !== 'granted') {
const requested = await Camera.requestPermissions();
if (requested.camera === 'denied') {
// Guide user to app settings -- cannot re-request on iOS
return;
}
}
const photo = await Camera.getPhoto({ ... });
Always wrap plugin calls in try-catch:
try {
const photo = await Camera.getPhoto({ resultType: CameraResultType.Uri });
} catch (error) {
if (error.message === 'User cancelled photos app') {
// Not an error
} else {
console.error('Camera error:', error);
}
}
For full details, see Cross-Platform Best Practices.
Deep links open specific content in the app from external URLs.
apple-app-site-association hosted at https:///.well-known/ .assetlinks.json hosted at https:///.well-known/ .import { App } from '@capacitor/app';
App.addListener('appUrlOpen', (event) => {
const path = new URL(event.url).pathname;
// Route to the appropriate page
});
applinks: to Associated Domains capability in ios/App/App/App.entitlements. to android/app/src/main/AndroidManifest.xml.For full setup, see Deep Links.
| Requirement | Solution |
|---|---|
| ----------- | -------- |
| App settings, preferences | @capacitor/preferences (native key-value, persists reliably) |
| Sensitive data (tokens, credentials) | @capawesome-team/capacitor-secure-preferences (Keychain/Keystore) |
| Relational data, offline-first | SQLite (@capawesome-team/capacitor-sqlite or @capacitor-community/sqlite) |
| Files, images, documents | @capacitor/filesystem |
Do NOT use localStorage, IndexedDB, or cookies for persistent data -- the OS can evict them (especially on iOS).
For details, see Storage.
@capawesome-team/capacitor-secure-preferences) for tokens and credentials, not localStorage or @capacitor/preferences. CSP tag in index.html.webContentsDebuggingEnabled: false in capacitor.config.ts.PrivacyInfo.xcprivacy) -- required for iOS 17+ when using privacy-sensitive APIs.For details, see Security.
Mock Capacitor plugins in Jest/Vitest since tests run in Node.js, not a WebView:
vi.mock('@capacitor/camera', () => ({
Camera: {
getPhoto: vi.fn().mockResolvedValue({
webPath: 'https://example.com/photo.jpg',
}),
},
}));
webContentsDebuggingEnabled: true, open chrome://inspect in Chrome.webContentsDebuggingEnabled: true, use Safari > Develop menu > select device.For details, see Testing.
npx cap sync fails: Verify @capacitor/core and @capacitor/cli versions match. Run cd android && ./gradlew clean.cd android && ./gradlew clean, then rebuild.npx cap sync after plugin installation. Verify Gradle sync completed.ANDROID_HOME is set. Install missing SDK versions via Android Studio SDK Manager.npx cap sync ios. For CocoaPods: cd ios/App && pod install --repo-update.ios/App/Pods and re-run pod install.webDir in capacitor.config.ts matches the actual build output directory.--external flag.npx cap sync. Verify plugin is in package.json dependencies.Capacitor is not defined: Install @capacitor/core (npm install @capacitor/core).For full troubleshooting, see Android Troubleshooting and iOS Troubleshooting.
Capacitor supports upgrades across major versions (4 through 8). Apply each major version jump sequentially -- do not skip intermediate versions.
| Current to Target | Node.js | Xcode | Android Studio |
|---|---|---|---|
| ----------------- | ------- | ----- | -------------- |
| to 5 | 16+ | 14.1+ | Flamingo 2022.2.1+ |
| to 6 | 18+ | 15.0+ | Hedgehog 2023.1.1+ |
| to 7 | 20+ | 16.0+ | Ladybug 2024.2.1+ |
| to 8 | 22+ | 26.0+ | Otter 2025.2.1+ |
Quick automated upgrade:
npx cap migrate
npx cap sync
If npx cap migrate fails partially, apply manual steps from the upgrade guides.
For app upgrades, see capacitor-app-upgrades.
For plugin upgrades, see capacitor-plugin-upgrades.
Capawesome Cloud provides cloud infrastructure for Capacitor apps: native builds, live updates, and automated app store publishing.
Website: capawesome.io | Cloud Services: cloud.capawesome.io
# Install and authenticate
npx @capawesome/cli login
# Create an app
npx @capawesome/cli apps:create
Deploy over-the-air (OTA) web updates to Capacitor apps without going through the app stores. Users receive updates immediately on next app launch.
Setup:
# Install the live update plugin
npm install @capawesome/capacitor-live-update
npx cap sync
Configure in capacitor.config.ts:
const config: CapacitorConfig = {
plugins: {
LiveUpdate: {
appId: '<APP_ID>',
autoUpdate: true,
},
},
};
Deploy an update:
npm run build
npx @capawesome/cli apps:liveupdates:upload --app-id <APP_ID>
Build iOS and Android apps in the cloud without local build environments. Supports signing certificates, environments, and build configuration.
# Trigger a build
npx @capawesome/cli apps:builds:create --app-id <APP_ID> --platform android
# Download the artifact
npx @capawesome/cli apps:builds:download --app-id <APP_ID> --build-id <BUILD_ID>
Automate submissions to Apple App Store (TestFlight) and Google Play Store.
# Create a deployment destination
npx @capawesome/cli apps:destinations:create --app-id <APP_ID>
# Deploy a build
npx @capawesome/cli apps:deployments:create --app-id <APP_ID> --build-id <BUILD_ID>
Use token-based auth for CI/CD pipelines:
npx @capawesome/cli login --token <TOKEN>
npx @capawesome/cli apps:builds:create --app-id <APP_ID> --platform ios --detached
For full Capawesome Cloud setup, see capawesome-cloud.
For the Capawesome CLI reference, see capawesome-cli.
Set up push notifications using Firebase Cloud Messaging (FCM) via @capacitor-firebase/messaging:
npm install @capacitor-firebase/messaging firebase
npx cap sync
Requires Firebase project setup, platform-specific configuration (APNs for iOS, google-services.json for Android), and permission handling.
For the full setup guide, see capacitor-push-notifications.
Set up in-app purchases and subscriptions with either:
@capawesome-team/capacitor-purchases) -- lightweight, no third-party backend, requires Capawesome Insiders license.@revenuecat/purchases-capacitor) -- full managed backend with receipt validation, analytics, and integrations.Both require App Store Connect (iOS) and/or Google Play Console (Android) product configuration.
For the full setup guide, see capacitor-in-app-purchases.
共 1 个版本