Plugin API
Import from @otakit/capacitor-updater. For normal app code, the main methods are getState(), check(), download(), update(), apply(), and notifyAppReady().
import { OtaKit } from "@otakit/capacitor-updater";Configuration
For hosted OtaKit, keep the plugin config small:
plugins: {
OtaKit: {
appId: "YOUR_OTAKIT_APP_ID",
appReadyTimeout: 10000,
// Optional:
// updateMode: "manual",
// updateMode: "immediate",
}
}Hosted OtaKit points at the managed server automatically. Do not set serverUrl or manifestKeys unless you intentionally want custom server or verification behavior.
Update Modes
OtaKit supports three update behaviors:
Manifest Verification
Hosted OtaKit verifies manifests automatically. The native plugin ships with built-in trusted public keys for the managed service and uses them by default when you stay on the hosted server.
You only need manifestKeys when you intentionally override trust for a custom or self-hosted server. In that case, also set serverUrl to your own API base URL.
Normal App Usage
Inspect the current app-facing updater state: current bundle, staged bundle, and builtin version.
Check the configured release target for a newer bundle without downloading it. When downloaded=true, that exact update is already staged locally.
Ensure the latest bundle is staged for later activation. If it is already staged, the staged bundle is returned without re-downloading it.
Friendly manual-mode helper. Bring the app to the newest available update now. If the newest update is already staged, apply it. Otherwise download it and apply it. Terminal operation.
Activate the currently staged bundle and reload the WebView. Terminal operation.
Confirm the current bundle is working. Call this once when your app has fully loaded. If it is not called within appReadyTimeout, the plugin rolls back.
import { OtaKit } from "@otakit/capacitor-updater";
const state = await OtaKit.getState();
const latest = await OtaKit.check();
// Low-level manual flow:
const bundle = await OtaKit.download();
if (bundle) {
await OtaKit.apply();
}
// Or the one-shot manual helper:
await OtaKit.update();
await OtaKit.notifyAppReady();Manual update prompt
The normal hosted flow is automatic, but you can also build your own app-level update prompt. A common pattern is: check for an update, show “Update available”, then download and apply it only after the user confirms.
If you want a stricter flow, you can also block parts of your UI until the update is applied. That policy lives in your app code, not in a separate server-side release mode.
If check() returns downloaded: true, the latest update is already staged locally and you can call apply() directly.
const state = await OtaKit.getState();
if (state.staged) {
await OtaKit.apply();
} else {
const latest = await OtaKit.check();
if (!latest) {
return;
}
// Show your own dialog / banner here.
const accepted = window.confirm("Update available. Install now?");
if (accepted) {
await OtaKit.update();
}
}Debug API
Manual inspection and control methods live under OtaKit.debug. These are for diagnostics, support, and test flows, not normal app code.
Check the server for a newer bundle without downloading it. You can optionally pass { channel } for a one-off debug override.
Debug version of download() that ensures the latest bundle is staged for a one-off { channel } override.
Clear active updater state, return to the builtin bundle, clear fallback and last failure state, and reload the WebView. Terminal operation.
List downloaded OTA bundles stored on the device.
Delete a downloaded bundle that is not current, fallback, or staged.
Return the last failed update metadata for diagnostics. The failed bundle files themselves are cleaned up automatically after rollback.
Advanced Overrides
Use these only when you run a custom server or need custom verification behavior.
plugins: {
OtaKit: {
appId: "YOUR_OTAKIT_APP_ID",
// Optional advanced overrides
// serverUrl: "https://your-server.com/api/v1",
// allowInsecureUrls: false,
// manifestKeys: [
// { kid: "key-2026-01", key: "MFkwEwYH..." }
// ]
}
}Events
Listen to update lifecycle events with OtaKit.addListener(event, callback). Returns a handle that can be removed with .remove().
OtaKit.addListener("downloadProgress", (progress) => {
console.log(`Downloaded: ${progress.percent}%`);
});
await OtaKit.removeAllListeners();Types
interface BundleInfo {
id: string;
version: string;
status: "builtin" | "pending"
| "trial" | "success" | "error";
downloadedAt?: string;
sha256?: string;
channel?: string;
releaseId?: string;
}
interface OtaKitState {
current: BundleInfo;
staged: BundleInfo | null;
builtinVersion: string;
}
interface LatestVersion {
version: string;
url: string;
sha256: string;
size: number;
downloaded?: boolean;
releaseId?: string;
minNativeBuild?: number;
}