Mobile & Cross-Platform

Capacitor mit Claude Code: iOS & Android Apps mit TypeScript 2026

Capacitor.js hat sich als die führende Lösung für Cross-Platform Mobile-Entwicklung mit Web-Technologien etabliert. In Kombination mit Claude Code und TypeScript entstehen native iOS- und Android-Apps in einem Bruchteil der Zeit — mit vollem Zugriff auf Native APIs, Push Notifications, Biometrie und App Store Distribution.

📅 6. Mai 2026 ⏱ 12 min Lesezeit ✍️ Agentic Movers Team
Was du in diesem Artikel lernst:
  • Capacitor-Projekt mit Claude Code aufsetzen und für iOS & Android konfigurieren
  • Native APIs: Camera, Filesystem, Geolocation mit TypeScript
  • Push Notifications über Firebase & APNS integrieren
  • Biometrie-Authentifizierung und sicheren Speicher implementieren
  • Over-the-Air (OTA) Live Updates ohne App-Store-Review deployen
  • iOS App Store & Google Play Store Deployment vollständig

Der entscheidende Vorteil von Capacitor gegenüber React Native oder Flutter: Du nutzt deine bestehenden Web-Kenntnisse (React, Vue, Angular oder Vanilla TypeScript) und erhältst trotzdem vollständigen Zugriff auf native Gerätefunktionen. Claude Code beschleunigt dabei jeden Entwicklungsschritt — von der Plugin-Konfiguration bis zum Debugging komplexer nativer Bridge-Probleme.

1. Capacitor Setup & Native Build Setup

Ein neues Capacitor-Projekt beginnt mit der Installation der Core-Abhängigkeiten. Claude Code übernimmt die Konfiguration der nativen Plattformen und erkennt typische Setup-Fehler automatisch.

# Neues Projekt initialisieren npm create vite@latest my-cap-app -- --template react-ts cd my-cap-app npm install # Capacitor Core & CLI installieren npm install @capacitor/core npm install -D @capacitor/cli # Capacitor initialisieren npx cap init "My App" "com.example.myapp" --web-dir dist # iOS & Android Plattformen hinzufügen npm install @capacitor/ios @capacitor/android npx cap add ios npx cap add android

Nach dem initialen Build synchronisierst du den Web-Code mit den nativen Projekten:

# Web-App bauen & in native Projekte synchronisieren npm run build npx cap sync # In Xcode / Android Studio öffnen npx cap open ios npx cap open android # Live Reload für Entwicklung npx cap run ios --livereload --external npx cap run android --livereload --external
capacitor.config.ts — Zentrale Konfiguration:
import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.example.myapp', appName: 'My App', webDir: 'dist', server: { androidScheme: 'https', iosScheme: 'https', }, plugins: { SplashScreen: { launchShowDuration: 2000, backgroundColor: '#ffffff', showSpinner: false, }, StatusBar: { style: 'dark', backgroundColor: '#ffffff', }, }, }; export default config;
💡 Claude Code Tipp: Wenn du Claude Code das Setup-Problem beschreibst (z. B. "Android SDK nicht gefunden" oder "Xcode Command Line Tools fehlen"), analysiert es die Fehlermeldung und liefert plattformspezifische Fix-Befehle — oft schneller als die offizielle Dokumentation.

Claude Code hilft beim Erkennen von Konfigurationsfehlern in capacitor.config.ts, beim Schreiben plattformspezifischer Permissions in Info.plist (iOS) und AndroidManifest.xml (Android) sowie beim Troubleshooting von Gradle- und CocoaPods-Problemen.

2. Native APIs: Camera & Filesystem Native

Die Camera-API von Capacitor gibt dir vollständigen Zugriff auf Kamera und Galerie — auf iOS und Android mit identischer TypeScript-Schnittstelle.

# Camera & Filesystem Plugins installieren npm install @capacitor/camera @capacitor/filesystem @capacitor/preferences npx cap sync
camera.service.ts — Vollständige Camera-Integration:
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera'; import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; export class CameraService { async takePhoto(): Promise<Photo> { const photo = await Camera.getPhoto({ quality: 90, allowEditing: false, resultType: CameraResultType.Uri, source: CameraSource.Camera, correctOrientation: true, }); return photo; } async pickFromGallery(): Promise<Photo> { const photo = await Camera.getPhoto({ quality: 85, allowEditing: true, resultType: CameraResultType.Base64, source: CameraSource.Photos, }); return photo; } async savePhotoToFilesystem(photo: Photo, fileName: string): Promise<string> { if (!photo.base64String) { throw new Error('Kein Base64-Daten im Photo-Objekt'); } const result = await Filesystem.writeFile({ path: `photos/${fileName}.jpeg`, data: photo.base64String, directory: Directory.Documents, recursive: true, }); return result.uri; } async loadPhoto(filePath: string): Promise<string> { const contents = await Filesystem.readFile({ path: filePath, directory: Directory.Documents, }); return `data:image/jpeg;base64,${contents.data}`; } async listPhotos(): Promise<string[]> { try { const result = await Filesystem.readdir({ path: 'photos', directory: Directory.Documents, }); return result.files.map(f => f.name); } catch { return []; } } async deletePhoto(fileName: string): Promise<void> { await Filesystem.deleteFile({ path: `photos/${fileName}`, directory: Directory.Documents, }); } }

Für iOS musst du in Info.plist die Kamera-Permissions deklarieren:

<!-- ios/App/App/Info.plist --> <key>NSCameraUsageDescription</key> <string>Diese App benötigt Kamerazugriff für Profilfotos.</string> <key>NSPhotoLibraryUsageDescription</key> <string>Diese App benötigt Galerie-Zugriff zum Auswählen von Fotos.</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>Diese App speichert Fotos in deiner Galerie.</string>
⚠️ Android Permissions: Ab Android 13 (API Level 33) sind READ_MEDIA_IMAGES und READ_MEDIA_VIDEO statt READ_EXTERNAL_STORAGE erforderlich. Claude Code generiert automatisch die korrekten Permission-Deklarationen basierend auf deiner Ziel-API-Version.

3. Push Notifications: Firebase & APNS Push

Push Notifications sind für moderne Mobile-Apps unverzichtbar. Capacitor abstrahiert die Unterschiede zwischen Firebase Cloud Messaging (Android) und Apple Push Notification Service (iOS) hinter einer einheitlichen API.

# Push Notifications Plugin installieren npm install @capacitor/push-notifications npx cap sync
push-notifications.service.ts:
import { PushNotifications, PushNotificationSchema, Token, ActionPerformed } from '@capacitor/push-notifications'; import { Capacitor } from '@capacitor/core'; export class PushNotificationService { async initialize(): Promise<void> { if (!Capacitor.isNativePlatform()) { console.log('Push Notifications nur auf nativen Plattformen verfügbar'); return; } // Permission anfragen const permStatus = await PushNotifications.requestPermissions(); if (permStatus.receive === 'granted') { await PushNotifications.register(); } else { console.warn('Push Notification Permission verweigert'); return; } // Token empfangen (FCM Token für Android, APNS Token für iOS) PushNotifications.addListener('registration', (token: Token) => { console.log('Push Registration Token:', token.value); this.sendTokenToBackend(token.value); }); // Registration-Fehler behandeln PushNotifications.addListener('registrationError', (error) => { console.error('Push Registration Fehler:', error); }); // Empfangene Notifications (App im Vordergrund) PushNotifications.addListener('pushNotificationReceived', (notification: PushNotificationSchema) => { console.log('Notification empfangen:', notification.title, notification.body); this.handleForegroundNotification(notification); } ); // Notification angeklickt (App im Hintergrund oder geschlossen) PushNotifications.addListener('pushNotificationActionPerformed', (action: ActionPerformed) => { console.log('Notification Action:', action.actionId, action.notification.data); this.handleNotificationTap(action); } ); } private async sendTokenToBackend(token: string): Promise<void> { await fetch('/api/push-tokens', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, platform: Capacitor.getPlatform(), userId: this.getCurrentUserId(), }), }); } private handleForegroundNotification(notification: PushNotificationSchema): void { // In-App Banner anzeigen const event = new CustomEvent('push-notification', { detail: notification }); document.dispatchEvent(event); } private handleNotificationTap(action: ActionPerformed): void { const data = action.notification.data; if (data?.route) { // Navigation zu Deep-Link-Route window.location.hash = data.route; } } private getCurrentUserId(): string { return localStorage.getItem('userId') ?? 'anonymous'; } async removeAllListeners(): Promise<void> { await PushNotifications.removeAllListeners(); } }

Firebase-Konfiguration für Android: Lade google-services.json aus der Firebase Console herunter und platziere die Datei in android/app/. Für iOS benötigst du GoogleService-Info.plist in ios/App/App/.

# android/app/build.gradle — Firebase einbinden apply plugin: 'com.google.gms.google-services' dependencies { implementation platform('com.google.firebase:firebase-bom:32.7.0') implementation 'com.google.firebase:firebase-messaging' }
💡 APNS Zertifikate (iOS): Im Apple Developer Portal benötigst du ein APNs Authentication Key (empfohlen) oder ein APNs-Zertifikat. Claude Code führt dich Schritt für Schritt durch den Prozess — inklusive der korrekten Konfiguration in Xcode Signing & Capabilities.

4. Biometrie & Secure Storage Sicherheit

Biometrische Authentifizierung (Face ID, Touch ID, Fingerprint) und sicheres Speichern sensibler Daten sind in modernen Apps Standard. Capacitor-Plugins kapseln die plattformspezifischen Keychain- und Keystore-APIs.

# Biometrie & Secure Storage Plugins npm install @capawesome-team/capacitor-biometrics npm install @aparajita/capacitor-secure-storage npm install @capacitor/preferences npx cap sync
biometric-auth.service.ts — Face ID, Touch ID & Fingerprint:
import { Biometrics, BiometryType } from '@capawesome-team/capacitor-biometrics'; import { SecureStorage } from '@aparajita/capacitor-secure-storage'; import { Preferences } from '@capacitor/preferences'; interface BiometricResult { success: boolean; error?: string; biometryType?: BiometryType; } export class BiometricAuthService { async isAvailable(): Promise<boolean> { try { const result = await Biometrics.isBiometryAvailable(); return result.isAvailable; } catch { return false; } } async getBiometryType(): Promise<BiometryType | null> { try { const result = await Biometrics.getBiometryType(); return result.biometryType; } catch { return null; } } async authenticate(reason: string): Promise<BiometricResult> { try { const isAvailable = await this.isAvailable(); if (!isAvailable) { return { success: false, error: 'Biometrie nicht verfügbar' }; } await Biometrics.authenticate({ reason, cancelTitle: 'Abbrechen', allowDeviceCredential: true, // Fallback auf PIN/Passwort }); return { success: true }; } catch (error: any) { return { success: false, error: error.message ?? 'Authentifizierung fehlgeschlagen', }; } } // Sicheres Speichern in iOS Keychain / Android Keystore async saveSecretSecurely(key: string, value: string): Promise<void> { await SecureStorage.set(key, value, true); // true = synchronize to iCloud Keychain } async getSecretSecurely(key: string): Promise<string | null> { try { const result = await SecureStorage.get(key, true); return result?.value ?? null; } catch { return null; } } // Auth-Token nach Biometrie-Prüfung laden async getAuthTokenWithBiometrics(): Promise<string | null> { const result = await this.authenticate('Authentifiziere dich für den Zugriff auf dein Konto'); if (!result.success) { console.error('Biometrie-Authentifizierung fehlgeschlagen:', result.error); return null; } return this.getSecretSecurely('auth_token'); } // Preferences (nicht-sensitiv, für App-Settings) async saveSetting(key: string, value: string): Promise<void> { await Preferences.set({ key, value }); } async getSetting(key: string): Promise<string | null> { const { value } = await Preferences.get({ key }); return value; } }
⚠️ Sicherheitshinweis: Nutze SecureStorage (Keychain/Keystore) für alle sensitiven Daten wie Auth-Tokens, API-Keys oder persönliche Daten. Preferences (AsyncStorage-basiert) ist für nicht-sensitive App-Einstellungen gedacht und nicht verschlüsselt.

5. Live Updates & OTA Deployment OTA

Over-the-Air (OTA) Updates ermöglichen es, den Web-Layer deiner App zu aktualisieren, ohne eine neue Version durch den App Store Review-Prozess zu schicken. Capawesome Live Updates ist die führende Lösung für Capacitor.

# Capawesome Live Updates Plugin npm install @capawesome/capacitor-live-update npx cap sync
live-update.service.ts — OTA Update Management:
import { LiveUpdate } from '@capawesome/capacitor-live-update'; import { App } from '@capacitor/app'; interface UpdateConfig { channel: string; autoDownload: boolean; resetOnNewBundle: boolean; } export class LiveUpdateService { private config: UpdateConfig = { channel: 'production', autoDownload: true, resetOnNewBundle: false, }; async initialize(): Promise<void> { // Beim App-Start auf Updates prüfen App.addListener('appStateChange', async ({ isActive }) => { if (isActive) { await this.checkForUpdates(); } }); } async checkForUpdates(): Promise<boolean> { try { const result = await LiveUpdate.getLatestBundle({ channel: this.config.channel, }); if (!result.bundleId) { console.log('Kein neues Update verfügbar'); return false; } console.log('Neues Bundle verfügbar:', result.bundleId); if (this.config.autoDownload) { await this.downloadAndApply(result.bundleId); } return true; } catch (error) { console.error('Update-Check fehlgeschlagen:', error); return false; } } async downloadAndApply(bundleId: string): Promise<void> { try { // Bundle herunterladen await LiveUpdate.downloadBundle({ bundleId }); console.log('Bundle heruntergeladen:', bundleId); // Bundle als nächstes aktives setzen await LiveUpdate.setNextBundle({ bundleId }); console.log('Bundle als nächstes gesetzt'); // App neu laden (beim nächsten Start aktiv) if (this.config.resetOnNewBundle) { await LiveUpdate.reload(); } } catch (error) { console.error('Bundle-Download fehlgeschlagen:', error); await this.rollback(); } } async rollback(): Promise<void> { try { await LiveUpdate.reset(); // Zurück zum eingebetteten Bundle console.log('Rollback erfolgreich'); } catch (error) { console.error('Rollback fehlgeschlagen:', error); } } async getCurrentBundleVersion(): Promise<string> { const result = await LiveUpdate.getCurrentBundle(); return result.bundleId ?? 'built-in'; } async setChannel(channel: 'production' | 'staging' | 'beta'): Promise<void> { this.config.channel = channel; console.log('Update-Channel gesetzt:', channel); } }

Live Updates per CI/CD-Pipeline deployen:

# .github/workflows/live-update.yml name: Live Update Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install & Build run: | npm ci npm run build - name: Deploy Live Update run: | npx @capawesome/cli live-update deploy \ --channel production \ --artifacts dist/ \ --token ${{ secrets.CAPAWESOME_TOKEN }}
💡 Richtlinien beachten: Apple und Google erlauben OTA-Updates nur für den Web-Layer (JavaScript, HTML, CSS, Assets). Änderungen am nativen Code (neue Plugins, Permissions) erfordern immer eine neue App-Version durch den Review-Prozess.

6. App Store Deployment: iOS & Android Deploy

Der finale Schritt: Deine App in den App Store (iOS) und Google Play Store (Android) bringen. Claude Code führt dich durch die Signing-Konfiguration, das Erstellen von Builds und den Submission-Prozess.

iOS: Archive & TestFlight

# iOS Release Build vorbereiten npm run build npx cap sync ios # In Xcode: Product → Archive → Distribute App # Oder via Fastlane (empfohlen für CI/CD): gem install fastlane # fastlane/Fastfile lane :beta do increment_build_number build_app(scheme: "App") upload_to_testflight( skip_waiting_for_build_processing: true, api_key_path: "fastlane/api_key.json" ) end lane :release do increment_version_number(version_number: "2.1.0") increment_build_number build_app(scheme: "App") upload_to_app_store( submit_for_review: true, automatic_release: false ) end
iOS App Review Checklist:
  • App Store Connect: App ID, Bundle ID, Capabilities konfiguriert
  • Provisioning Profile: Distribution Certificate gültig (1 Jahr)
  • Privacy Manifest (PrivacyInfo.xcprivacy): Alle API-Zugriffstypen deklariert
  • Screenshots: 6.7" iPhone + 12.9" iPad in App Store Connect hochgeladen
  • App Privacy: Datenschutz-Fragebogen vollständig ausgefüllt
  • Export Compliance: Kryptographie-Nutzung deklariert (auch HTTPS)
  • Review Notes: Test-Credentials für Review-Team bereitgestellt

Android: AAB & Google Play Console

# Android Release Build (AAB — bevorzugt für Play Store) npm run build npx cap sync android # In Android Studio: Build → Generate Signed Bundle/APK # Oder via Gradle CLI: cd android ./gradlew bundleRelease # APK signieren (falls nicht über Android Studio) jarsigner -verbose \ -sigalg SHA256withRSA \ -digestalg SHA-256 \ -keystore my-release-key.jks \ app/build/outputs/bundle/release/app-release.aab \ my-key-alias # Mit zipalign optimieren zipalign -v 4 app-release.aab app-release-aligned.aab
# android/app/build.gradle — Signing-Konfiguration android { signingConfigs { release { storeFile file(System.getenv('KEYSTORE_PATH')) storePassword System.getenv('KEYSTORE_PASSWORD') keyAlias System.getenv('KEY_ALIAS') keyPassword System.getenv('KEY_PASSWORD') } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
Google Play Release Tracks:
Internal Testing
Bis 100 Tester, sofort verfügbar, kein Review
Closed Testing (Alpha)
Definierte Testergruppen, schneller Review
Open Testing (Beta)
Öffentlich, Opt-in, vor Production-Review
Production
Gestaffelter Rollout 1% → 10% → 50% → 100%
⚠️ Keystore-Backup ist kritisch: Verlierst du deinen Android Keystore, kannst du KEINE Updates mehr für deine App veröffentlichen — die App muss neu eingereicht werden und verliert alle Bewertungen und Downloads. Keystore-Datei + Passwörter sicher und redundant aufbewahren (z. B. verschlüsseltes Backup in Cloud-Speicher).

Fazit: Capacitor + Claude Code = Mobile Development im Turbogang

Capacitor.js hat die Cross-Platform Mobile-Entwicklung demokratisiert. Mit deinen Web-Kenntnissen (TypeScript, React, Vue) erstellst du native iOS- und Android-Apps mit vollem Zugriff auf alle nativen APIs — ohne Swift oder Kotlin lernen zu müssen.

Claude Code beschleunigt diesen Prozess in jeder Phase:

  • Setup: Plugin-Konfiguration, Permissions, native Projekt-Struktur
  • Native APIs: TypeScript-Service-Klassen für Camera, Filesystem, Geolocation
  • Push & Auth: Firebase-Integration, APNS-Setup, Biometrie-Flows
  • OTA Updates: Live Update-Strategien, Channel-Management, Rollback
  • Deployment: Fastlane-Konfiguration, Signing, App Store Submission
  • Debugging: Xcode/ADB Logs analysieren, native Bridge-Fehler aufklären

Das Ergebnis: Mobile-Apps, die sich nativ anfühlen, in der Hälfte der Entwicklungszeit — und ein einziger TypeScript-Codebase für iOS, Android und Web.

Mobile-Modul im Kurs

Im Claude Code Mastery Kurs: vollständiges Capacitor-Modul mit Native APIs, Push Notifications, Biometrie, Live Updates und App Store Deployment für iOS & Android.

14 Tage kostenlos testen →
AM
Agentic Movers Team Wir helfen Entwicklern und Teams, mit Claude Code schneller bessere Software zu bauen — von Web-Apps bis zu nativen Mobile-Apps.

Weitere Artikel

Mobile

React Native mit Expo & Claude Code 2026

Web

Progressive Web Apps mit Service Worker & Claude Code