Setup

Get OtaKit running in your Capacitor project using the hosted service. Start in the dashboard to create an organization and app, then wire that app into your Capacitor project. If you want to run your own server, use the self-hosting guide.

1. Create your app in the dashboard

Sign in to the OtaKit dashboard, create an app, and copy its OtaKit appId. That hosted dashboard flow is the primary setup path.

If you prefer CLI-based app creation, otakit register --slug ... still exists, but it is optional.

2. Install the Capacitor plugin

npm install @otakit/capacitor-updater
npx cap sync

3. Configure the plugin

Add the OtaKit plugin to capacitor.config.ts. Use the OtaKit appId you copied from the dashboard. The CLI also reads webDir from this file, so you do not need a separate OtaKit project config file.

// capacitor.config.ts
import type { CapacitorConfig } from "@capacitor/cli";

const config: CapacitorConfig = {
  appId: "com.example.myapp",
  appName: "My App",
  webDir: "out",
  plugins: {
    OtaKit: {
      appId: "YOUR_OTAKIT_APP_ID",
      appReadyTimeout: 10000,
      // Optional:
      // updateMode: "manual",
      // updateMode: "immediate",
    }
  }
};

export default config;

4. Add notifyAppReady()

Call notifyAppReady() once your app has loaded. If this isn't called within appReadyTimeout (default 10s), the plugin rolls back to the previous bundle.

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

// Call once your app is fully loaded
await OtaKit.notifyAppReady();

For frameworks like React/Next.js, wrap it in a useEffect:

"use client";
import { useEffect } from "react";
import { OtaKit } from "@otakit/capacitor-updater";
import { Capacitor } from "@capacitor/core";

export function AppReadyProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    if (Capacitor.isNativePlatform()) {
      OtaKit.notifyAppReady();
    }
  }, []);

  return <>{children}</>;
}

5. Install the CLI and sign in

npm install -g @otakit/cli

For the hosted OtaKit flow, sign in with your account:

otakit login

This stores a local token for the managed OtaKit service. You do not need to set OTAKIT_SERVER_URL for the hosted path.

Hosted manifest verification is automatic too. The native plugin already trusts the managed OtaKit signing keys, so do not add manifestKeys unless you are intentionally overriding trust.

6. Upload and release

Build your web assets, then ship:

npm run build
otakit upload --release

upload uses the bundle path you pass explicitly, or thewebDir value from capacitor.config.*. If you prefer env-based setup, OTAKIT_BUILD_DIR and OTAKIT_OUTPUT_DIR are also supported as overrides.

Version resolution is deterministic: --version wins, then OTAKIT_VERSION, otherwise the CLI auto-generates a version. --release publishes to the base stream; use --release staging to target a named release track.

Advanced alternative: if you want to create apps from CI or scripts, run otakit register --slug com.example.myapp and paste the returned appId into capacitor.config.ts.

That's it. Relaunch the app on your device and it will pick up the update on the next cold launch by default. If you prefer manual control over update prompts, set updateMode to "manual" and use OtaKit.getState(), OtaKit.check(), and either OtaKit.update() or OtaKit.download() plus OtaKit.apply(). If you prefer immediate activation during startup, set updateMode to "immediate". See the CLI reference for all options, or the full walkthrough for a step-by-step guide from scratch. If you need a custom server or self-hosted deployment, continue with the self-hosting guide.