Plugin API

Import from @otakit/capacitor-updater. All methods return promises.

import { Updater } from "@otakit/capacitor-updater";

Configuration

Add the Updater plugin to your capacitor.config.ts:

plugins: {
    Updater: {
      appId: "YOUR_APP_ID",
      publicKey: "YOUR_PUBLIC_KEY",
      defaultChannel: "default",
      updateMode: "silent", // or "eager" for staging/internal builds
      autoUpdate: true,
      appReadyTimeout: 10000,
    // Optional
    // updateUrl: "https://your-server.com/api/v1",  // defaults to https://updatekit.vercel.app/api/v1
    // allowInsecureUrls: false,
    // manifestPublicKeys: [
    //   { kid: "key-2026-01", key: "MFkwEwYH..." }
    // ]
  }
}
updateUrlstringOtaKit server URL. Defaults to https://updatekit.vercel.app/api/v1.
appIdstringYour app ID from the dashboard.
publicKeystringApp public key for manifest access.
defaultChannelstringChannel to check for updates. Default: default.
updateMode'silent' | 'eager'Update startup strategy. Default: silent. Legacy aliases: background -> silent, blocking -> eager.
autoUpdatebooleanCheck for updates on app launch. Default: true.
appReadyTimeoutnumberMilliseconds to wait for notifyAppReady(). Default: 10000.
allowInsecureUrlsbooleanAllow HTTP (localhost only). Default: false.
manifestPublicKeysarrayES256 public keys for manifest signature verification.

Core methods

notifyAppReady()void

Confirm the current bundle is working. Must be called within appReadyTimeout or the plugin rolls back. Call this once when your app has fully loaded.

getCurrent()BundleInfo

Get info about the currently active bundle (id, version, status).

getLatest()LatestVersion | null

Check the server for a newer version. Returns null if up to date.

checkAndDownload()BundleInfo | null

Check for updates and download if available. Returns null if no update. This is the auto-update flow in a single call.

Manual update control

download(options)BundleInfo

Download a specific bundle by URL. Options: { url, version, sha256 }. SHA-256 is required for verification.

next({ bundleId })void

Queue a bundle to activate on next app restart. Does not reload the WebView.

set({ bundleId })void

Activate a bundle immediately. Warning: the WebView reloads after this call.

reload()void

Force reload the WebView with the current or pending bundle.

reset()void

Reset to the factory (builtin) bundle. The WebView reloads.

Bundle management

list(){ bundles: BundleInfo[] }

List all downloaded bundles on the device.

delete({ bundleId })void

Delete a specific bundle from the device.

getNextBundle()BundleInfo | null

Get the bundle queued for next activation, if any.

getFailedUpdate()BundleInfo | null

Get the last failed bundle (one-shot — clears after retrieval). Useful for diagnostics.

getBuiltinVersion(){ version: string }

Get the version of the factory-installed bundle.

Events

Listen to update lifecycle events with Updater.addListener(event, callback). Returns a handle that can be removed with .remove().

downloadStarted{ version }A download has begun
downloadProgress{ percent, downloaded, total }Download progress
downloadCompleteBundleInfoDownload finished
downloadFailed{ version, error }Download failed
updateAvailableLatestVersionNew version available
noUpdateAvailableApp is up to date
appReadyBundleInfonotifyAppReady() called
rollback{ from, to, reason? }Rolled back
Updater.addListener("downloadProgress", (progress) => {
  console.log(`Downloaded: ${progress.percent}%`);
});

// Remove all listeners when done
await Updater.removeAllListeners();

Types

interface BundleInfo {
  id: string;
  version: string;
  status: "BUILTIN" | "DOWNLOADING" | "PENDING"
        | "TRIAL" | "SUCCESS" | "ERROR";
  downloadedAt?: string;
  sha256?: string;
  channel?: string;
  releaseId?: string;
}

interface LatestVersion {
  version: string;
  url: string;
  sha256: string;
  size: number;
  releaseId?: string;
  minNativeBuild?: number;
}

interface DownloadProgressData {
  percent: number;   // 0–100
  downloaded: number;
  total: number;
}