| name | capgo-live-updates |
| description | Complete guide to implementing live updates in Capacitor apps using Capgo. Covers account creation, plugin installation, configuration, update strategies, and CI/CD integration. Use this skill when users want to deploy updates without app store review. |
Capgo Live Updates for Capacitor
Deploy updates to your Capacitor app instantly without waiting for app store review.
When to Use This Skill
- User wants live/OTA updates
- User asks about Capgo
- User wants to skip app store review
- User needs to push hotfixes quickly
- User wants A/B testing or staged rollouts
What is Capgo?
Capgo is a live update service for Capacitor apps that lets you:
- Push JavaScript/HTML/CSS updates instantly
- Skip app store review for web layer changes
- Roll back bad updates automatically
- A/B test features with channels
- Monitor update analytics
Note: Native code changes (Swift/Kotlin/Java) still require app store submission.
Getting Started
Step 1: Create a Capgo Account
- Go to https://capgo.app
- Click "Sign Up" or "Get Started"
- Sign up with GitHub, Google, or email
- Choose a plan:
- Free: 1 app, 500 updates/month
- Solo: $14/mo, unlimited updates
- Team: $49/mo, team features
- Enterprise: Custom pricing
Step 2: Install the CLI
npm install -g @capgo/cli
Step 3: Login to Capgo
capgo login
Or use API key:
capgo login --apikey YOUR_API_KEY
Step 4: Initialize Your App
cd your-capacitor-app
capgo init
This will:
- Create app in Capgo dashboard
- Add
@capgo/capacitor-updater to your project
- Configure capacitor.config.ts
- Set up your first channel
Step 5: Install the Plugin
If not installed automatically:
npm install @capgo/capacitor-updater
npx cap sync
Configuration
Basic Configuration
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.yourapp.id',
appName: 'Your App',
webDir: 'dist',
plugins: {
CapacitorUpdater: {
autoUpdate: true,
},
},
};
export default config;
Advanced Configuration
plugins: {
CapacitorUpdater: {
autoUpdate: true,
resetWhenUpdate: true,
updateUrl: 'https://api.capgo.app/updates',
statsUrl: 'https://api.capgo.app/stats',
defaultChannel: 'production',
periodCheckDelay: 600,
delayConditionsFail: false,
privateKey: 'YOUR_PRIVATE_KEY',
},
},
Implementing Updates
Automatic Updates (Recommended)
With autoUpdate: true, updates are automatic:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
CapacitorUpdater.notifyAppReady();
Important: Always call notifyAppReady(). If not called within 10 seconds, Capgo assumes the update failed and rolls back.
Manual Updates
For more control:
plugins: {
CapacitorUpdater: {
autoUpdate: false,
},
},
import { CapacitorUpdater } from '@capgo/capacitor-updater';
class UpdateService {
async checkForUpdate() {
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) {
const bundle = await CapacitorUpdater.download({
url: update.url,
version: update.version,
});
console.log('Downloaded:', bundle.id);
return bundle;
}
async installUpdate(bundle: any) {
await CapacitorUpdater.set(bundle);
console.log('Update will apply on next restart');
}
async installAndReload(bundle: any) {
await CapacitorUpdater.set(bundle);
await CapacitorUpdater.reload();
}
}
Update with User Prompt
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) {
showLoading('Downloading update...');
const bundle = await CapacitorUpdater.download({
url: update.url,
version: update.version,
});
hideLoading();
await CapacitorUpdater.set(bundle);
await CapacitorUpdater.reload();
}
}
Listen for Update Events
import { CapacitorUpdater } from '@capgo/capacitor-updater';
CapacitorUpdater.addListener('updateAvailable', (info) => {
console.log('Update available:', info.bundle.version);
});
CapacitorUpdater.addListener('downloadProgress', (progress) => {
console.log('Download:', progress.percent, '%');
});
CapacitorUpdater.addListener('updateFailed', (info) => {
console.error('Update failed:', info.bundle.version);
});
CapacitorUpdater.addListener('appReady', () => {
console.log('App is ready');
});
Deploying Updates
Deploy via CLI
npm run build
capgo upload
capgo upload --channel beta
capgo upload --bundle 1.2.3
Deploy via CI/CD
GitHub Actions
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
deploy:
stage: deploy
image: node:20
script:
- npm install
- npm run build
- npx @capgo/cli bundle upload
only:
- main
variables:
CAPGO_TOKEN: $CAPGO_TOKEN
Channels and Staged Rollouts
Create Channels
capgo channel create beta
capgo channel create staging
Deploy to Channels
capgo upload --channel beta
capgo upload --channel production
Staged Rollout
In Capgo dashboard:
- Go to Channels > production
- Set rollout percentage (e.g., 10%)
- Monitor analytics
- Increase to 50%, then 100%
Device-Specific Channels
import { CapacitorUpdater } from '@capgo/capacitor-updater';
await CapacitorUpdater.setChannel({ channel: 'beta' });
await CapacitorUpdater.setChannel({ channel: 'production' });
Rollback and Version Management
Automatic Rollback
If notifyAppReady() isn't called within 10 seconds, Capgo automatically rolls back to the previous working version.
Manual Rollback
capgo bundle list
capgo bundle revert --bundle 1.2.2 --channel production
In-App Rollback
const bundles = await CapacitorUpdater.list();
await CapacitorUpdater.reset();
await CapacitorUpdater.delete({ id: 'bundle-id' });
Self-Hosted Option
For enterprise or privacy requirements:
docker run -d \
-p 8080:8080 \
-e DATABASE_URL=postgres://... \
capgo/capgo-server
Configure app to use self-hosted:
plugins: {
CapacitorUpdater: {
autoUpdate: true,
updateUrl: 'https://your-server.com/updates',
statsUrl: 'https://your-server.com/stats',
},
},
Security
Encrypted Updates
For sensitive apps, enable encryption:
capgo key create
capgo upload --key-v2
Configure in app:
plugins: {
CapacitorUpdater: {
autoUpdate: true,
privateKey: 'YOUR_PRIVATE_KEY',
},
},
Code Signing
Verify updates are from trusted source:
capgo upload --sign
capgo key verify
Monitoring and Analytics
Dashboard Metrics
In Capgo dashboard, view:
- Active devices
- Update success rate
- Rollback rate
- Version distribution
- Error logs
Custom Analytics
import { CapacitorUpdater } from '@capgo/capacitor-updater';
const current = await CapacitorUpdater.current();
console.log('Current version:', current.bundle.version);
const stats = await CapacitorUpdater.getBuiltinVersion();
Troubleshooting
Issue: Updates Not Applying
- Check
notifyAppReady() is called
- Verify app ID matches Capgo dashboard
- Check channel assignment
- Review Capgo dashboard logs
Issue: Rollback Loop
- App crashes before
notifyAppReady()
- Fix: Ensure
notifyAppReady() is called early
- Temporarily disable updates to debug
Issue: Slow Downloads
- Enable delta updates (automatic)
- Optimize bundle size
- Use CDN (enterprise)
Best Practices
- Always call
notifyAppReady() - First thing after app initializes
- Test updates on beta channel first - Never push untested to production
- Use semantic versioning - Makes rollback easier
- Monitor rollback rate - High rate indicates quality issues
- Implement error boundary - Catch crashes before rollback
- Keep native code stable - Native changes need app store
Resources