From capgo-cloud
Guides Capgo setup for live OTA updates in Capacitor apps: account creation, CLI install, plugin config, channels, A/B testing, rollbacks, CI/CD. For skipping app store review on web changes.
npx claudepluginhub cap-go/capgo-skills --plugin capgo-cloudThis skill uses the workspace's default tool permissions.
Deploy updates to your Capacitor app instantly without waiting for app store review.
Sets up Capgo-centered release workflows for Capacitor apps covering OTA live updates, native builds, and app store publishing via repository CI/CD.
Guides publishing Capacitor apps to Apple App Store and Google Play Store with checklists, configurations, screenshots, metadata, and submission steps.
Migrates web apps, PWAs, SPAs to store-ready Capacitor iOS/Android apps. Addresses thin WebView rejections, native UX, permissions, offline support, billing, testing, Capgo updates.
Share bugs, ideas, or general feedback.
Deploy updates to your Capacitor app instantly without waiting for app store review.
Capgo is a live update service for Capacitor apps that lets you:
Note: Native code changes (Swift/Kotlin/Java) still require app store submission.
npm install -g @capgo/cli
capgo login
# Opens browser to authenticate
Or use API key:
capgo login --apikey YOUR_API_KEY
cd your-capacitor-app
capgo init
This will:
@capgo/capacitor-updater to your projectIf not installed automatically:
npm install @capgo/capacitor-updater
npx cap sync
// capacitor.config.ts
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.yourapp.id',
appName: 'Your App',
webDir: 'dist',
plugins: {
CapacitorUpdater: {
autoUpdate: true, // Enable automatic updates
},
},
};
export default config;
// capacitor.config.ts
plugins: {
CapacitorUpdater: {
autoUpdate: true,
// Update behavior
resetWhenUpdate: true, // Reset to built-in on native update
updateUrl: 'https://api.capgo.app/updates', // Default
statsUrl: 'https://api.capgo.app/stats', // Analytics
// Channels
defaultChannel: 'production',
// Update timing
periodCheckDelay: 600, // Check every 10 minutes (seconds)
delayConditionsFail: false, // Don't delay on condition fail
// Private updates (enterprise)
privateKey: 'YOUR_PRIVATE_KEY', // For encrypted updates
},
},
With autoUpdate: true, updates are automatic:
// app.ts - Just notify when ready
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// Tell Capgo the app loaded successfully
// This MUST be called within 10 seconds of app start
CapacitorUpdater.notifyAppReady();
Important: Always call notifyAppReady(). If not called within 10 seconds, Capgo assumes the update failed and rolls back.
For more control:
// capacitor.config.ts
plugins: {
CapacitorUpdater: {
autoUpdate: false, // Disable auto updates
},
},
// update-service.ts
import { CapacitorUpdater } from '@capgo/capacitor-updater';
class UpdateService {
async checkForUpdate() {
// Check for available update
const update = await CapacitorUpdater.getLatest();
if (!update.url) {
console.log('No update available');
return null;
}
console.log('Update available:', update.version);
return update;
}
async downloadUpdate(update: any) {
// Download the update bundle
const bundle = await CapacitorUpdater.download({
url: update.url,
version: update.version,
});
console.log('Downloaded:', bundle.id);
return bundle;
}
async installUpdate(bundle: any) {
// Set as next version (applies on next app start)
await CapacitorUpdater.set(bundle);
console.log('Update will apply on next restart');
}
async installAndReload(bundle: any) {
// Set and reload immediately
await CapacitorUpdater.set(bundle);
await CapacitorUpdater.reload();
}
}
import { CapacitorUpdater } from '@capgo/capacitor-updater';
import { Dialog } from '@capacitor/dialog';
async function checkUpdate() {
const update = await CapacitorUpdater.getLatest();
if (!update.url) return;
const { value } = await Dialog.confirm({
title: 'Update Available',
message: `Version ${update.version} is available. Update now?`,
});
if (value) {
// Show loading indicator
showLoading('Downloading update...');
const bundle = await CapacitorUpdater.download({
url: update.url,
version: update.version,
});
hideLoading();
// Apply and reload
await CapacitorUpdater.set(bundle);
await CapacitorUpdater.reload();
}
}
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// Update downloaded
CapacitorUpdater.addListener('updateAvailable', (info) => {
console.log('Update available:', info.bundle.version);
});
// Download progress
CapacitorUpdater.addListener('downloadProgress', (progress) => {
console.log('Download:', progress.percent, '%');
});
// Update failed
CapacitorUpdater.addListener('updateFailed', (info) => {
console.error('Update failed:', info.bundle.version);
});
// App ready
CapacitorUpdater.addListener('appReady', () => {
console.log('App is ready');
});
# Build your web app
npm run build
# Upload to Capgo
capgo upload
# Upload to specific channel
capgo upload --channel beta
# Upload with version
capgo upload --bundle 1.2.3
# .github/workflows/deploy.yml
name: Deploy to Capgo
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Deploy to Capgo
run: npx @capgo/cli bundle upload
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# .gitlab-ci.yml
deploy:
stage: deploy
image: node:20
script:
- npm install
- npm run build
- npx @capgo/cli bundle upload
only:
- main
variables:
CAPGO_TOKEN: $CAPGO_TOKEN
# Create beta channel
capgo channel create beta
# Create staging channel
capgo channel create staging
# Deploy to beta (internal testing)
capgo upload --channel beta
# Promote to production
capgo upload --channel production
In Capgo dashboard:
// Assign device to channel
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// For beta testers
await CapacitorUpdater.setChannel({ channel: 'beta' });
// For production users
await CapacitorUpdater.setChannel({ channel: 'production' });
If notifyAppReady() isn't called within 10 seconds, Capgo automatically rolls back to the previous working version.
# List available versions
capgo bundle list
# Rollback to specific version
capgo bundle revert --bundle 1.2.2 --channel production
// Get list of downloaded bundles
const bundles = await CapacitorUpdater.list();
// Rollback to built-in version
await CapacitorUpdater.reset();
// Delete a specific bundle
await CapacitorUpdater.delete({ id: 'bundle-id' });
For enterprise or privacy requirements:
# Install self-hosted Capgo
docker run -d \
-p 8080:8080 \
-e DATABASE_URL=postgres://... \
capgo/capgo-server
Configure app to use self-hosted:
// capacitor.config.ts
plugins: {
CapacitorUpdater: {
autoUpdate: true,
updateUrl: 'https://your-server.com/updates',
statsUrl: 'https://your-server.com/stats',
},
},
For sensitive apps, enable encryption:
# Generate key pair
capgo key create
# Upload with encryption
capgo upload --key-v2
Configure in app:
// capacitor.config.ts
plugins: {
CapacitorUpdater: {
autoUpdate: true,
privateKey: 'YOUR_PRIVATE_KEY',
},
},
Verify updates are from trusted source:
# Sign bundle
capgo upload --sign
# Verify signature in app
capgo key verify
In Capgo dashboard, view:
// Track custom events
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// Get current bundle info
const current = await CapacitorUpdater.current();
console.log('Current version:', current.bundle.version);
// Get download stats
const stats = await CapacitorUpdater.getBuiltinVersion();
notifyAppReady() is callednotifyAppReady()notifyAppReady() is called earlynotifyAppReady() - First thing after app initializes