capacitor
Comprehensive Capacitor expert skill that consolidates core concepts, CLI usage, app creation, plugin management, framework integration, cross-platform best practices, storage, security, testing, troubleshooting, upgrading, and Capawesome Cloud workflows (live updates, native builds, app store publishing). Use as a single-source reference for Capacitor app and plugin development.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw skills install shop:github:LeoYeAI~openclaw-master-skills~capacitorcURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/github%3ALeoYeAI~openclaw-master-skills~capacitor/file -o capacitor.md# Capacitor
Comprehensive reference for building cross-platform apps with Capacitor. Covers architecture, CLI, plugins, framework integration, best practices, and Capawesome Cloud.
## Core Concepts
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.
### Architecture
A Capacitor app has three layers:
1. **Web layer** -- HTML/CSS/JS app running inside a native WebView (WKWebView on iOS, Android System WebView on Android).
2. **Native bridge** -- Serializes JS plugin calls, routes them to native code, and returns results as Promises.
3. **Native layer** -- Swift/ObjC (iOS) and Kotlin/Java (Android) code implementing native functionality.
Data passed across the bridge must be JSON-serializable. Pass files as paths, not base64.
### Project Structure
```
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
`capacitor.config.ts` (preferred) or `capacitor.config.json` controls app behavior:
```typescript
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](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-app-development/references/app-configuration.md).
## Creating a New App
### Quick Start
```bash
# 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:**
- Angular: `dist/<project-name>/browser` (Angular 17+ with application builder)
- React (Vite): `dist`
- Vue (Vite): `dist`
- Vanilla: `www`
For the full guided creation flow, see [capacitor-app-creation](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-app-creation/SKILL.md).
## Capacitor CLI
All commands: `npx cap <command>`. Most important commands:
| Command | Purpose |
| ------- | ------- |
| `npx cap init <name> <id>` | Initialize Capacitor in a project |
| `npx cap add <platform>` | 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 <platform>` | Build, sync, and deploy to device/emulator |
| `npx cap run <platform> -l --external` | Run with live reload |
| `npx cap open <platform>` | Open native project in IDE |
| `npx cap build <platform>` | 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](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-app-development/references/cli.md).
## Framework Integration
Capacitor works with any web framework. Framework-specific patterns:
### Angular
- Wrap Capacitor plugins in Angular services for DI and testability.
- Plugin event listeners run outside NgZone -- always wrap callbacks in `NgZone.run()`.
- Register listeners in `ngOnInit`, remove in `ngOnDestroy`.
For details, see [capacitor-angular](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-angular/SKILL.md).
### React
- Create custom hooks (`useCamera`, `useNetwork`) that wrap Capacitor plugins.
- Use `useEffect` for listener registration with cleanup to prevent memory leaks.
- React 18 strict mode double-mounts -- ensure cleanup functions work correctly.
For details, see [capacitor-react](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-react/SKILL.md).
### Vue
- Create composables (`useCamera`, `useNetwork`) using Vue 3 Composition API.
- Register listeners in `onMounted`, remove in `onUnmounted`.
- Vue reactivity picks up `ref` changes automatically (no NgZone equivalent needed).
For details, see [capacitor-vue](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-vue/SKILL.md).
## Plugins
Plugins are Capacitor's extension mechanism. Each plugin exposes a JS API backed by native implementations.
### Plugin Sources
- **Official** (`@capacitor/*`) -- Camera, Filesystem, Geolocation, Preferences, etc.
- **Capawesome** (`@capawesome/*`, `@capawesome-team/*`) -- SQLite, NFC, Biometrics, Live Update, etc.
- **Community** (`@capacitor-community/*`) -- AdMob, BLE, SQLite, Stripe, etc.
- **Firebase** (`@capacitor-firebase/*`) -- Analytics, Auth, Messaging, Firestore, etc.
- **MLKit** (`@capacitor-mlkit/*`) -- Barcode scanning, face detection, translation.
- **RevenueCat** (`@revenuecat/purchases-capacitor`) -- In-app purchases.
### Installing a Plugin
```bash
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.
### Using a Plugin
```typescript
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](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-plugins/SKILL.md).
## Plugin Development
Create custom Capacitor plugins with native iOS (Swift) and Android (Java/Kotlin) implementations:
1. Scaffold with `npm init @capacitor/plugin@latest`.
2. Define the TypeScript API in `src/definitions.ts`.
3. Implement the web layer in `src/web.ts`.
4. Implement iOS plugin in `ios/Sources/`.
5. Implement Android plugin in `android/src/main/java/`.
6. Verify with `npm run verify`.
Key rules:
- The `registerPlugin()` name in `src/index.ts` must match `jsName` on iOS and `@CapacitorPlugin(name = "...")` on Android.
- iOS methods need `@objc` and must be listed in `pluginMethods` (CAPBridgedPlugin).
- Android methods need `@PluginMethod()` annotation and must be `public`.
For full details, see [capacitor-plugin-development](https://github.com/capawesome-team/skills/blob/main/skills/capacitor-plugin-development/SKILL.md).
## Cross-Platform Best Practices
### Platform Detection
```typescript
import { Capacitor } from '@capacitor/core';
const platform = Capacitor.getPlatform(); // 'android' | 'ios' | 'web'
if (Capacitor.isNativePlatform()) { /* native-only code */ }
if (Capacitor.isPluginAvailable('Camera')) { /* plugin available */ }
```
### Permissions
Follow the check-then-request pattern:
```typescript
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({ ... });
```
### Performance
- **Minimize bridge calls** -- batch operations instead