Live Update — Config
LiveUpdateConfig is the configuration block passed to NativeUpdate.initialize() (under liveUpdate, or as part of the top-level PluginInitConfig shorthand). Every field except appId is optional, but a few — serverUrl, publicKey, requireSignature — are effectively required for a production setup.
import type { LiveUpdateConfig } from 'native-update';
Full type
interface LiveUpdateConfig {
appId: string;
serverUrl?: string;
apiKey?: string; // since v3.1.3
channel?: string;
autoUpdate?: boolean;
updateStrategy?: UpdateStrategy;
publicKey?: string;
requireSignature?: boolean;
checksumAlgorithm?: ChecksumAlgorithm;
checkInterval?: number;
allowEmulator?: boolean;
mandatoryInstallMode?: InstallMode;
optionalInstallMode?: InstallMode;
maxBundleSize?: number;
allowedHosts?: string[];
}
Field reference
appId
| Type | string |
| Required | yes |
| Default | — |
The Capacitor app ID (matches capacitor.config.ts → appId). The server uses this to scope which bundles a device is allowed to download.
appId: 'com.yourcompany.yourapp'
serverUrl
| Type | string |
| Required | yes for production (technically optional for "I'll call setUpdateUrl() later" flows) |
| Default | — |
HTTPS origin of your update server. Plain HTTP is rejected at startup — use HTTPS even in development. Trailing slash is optional. The plugin appends /v1/updates/check itself, so for the hosted backend the value is:
serverUrl: 'https://nativeupdatebe.aoneahsan.com/api'
apiKey
| Type | string |
| Required | yes for the hosted backend (every check without it is skipped / rejected) |
| Since | v3.1.3 (earlier versions only accepted it via the flat initialize({ apiKey })) |
| Default | — |
The app API key, sent as the X-API-Key header on every update check (web AND native since v3.1.3). Mint, copy, rotate, or delete keys in the dashboard: Apps → your app → API Keys (max 3 active keys per app; lifecycle actions are rate-limited).
apiKey: 'nu_app_…'
channel
| Type | string |
| Required | no |
| Default | 'production' (server-side convention; SDK does not enforce a list) |
The release channel the device tracks. Common values: production, staging, beta, dev. Channel switching at runtime is supported via setChannel().
autoUpdate
| Type | boolean |
| Required | no |
| Default | false |
When true, sync() automatically downloads available updates. When false, sync() returns UPDATE_AVAILABLE and you call downloadUpdate() yourself. Most apps want false so the user sees a prompt before bytes start moving on metered connections.
updateStrategy
| Type | UpdateStrategy |
| Required | no |
| Default | 'background' |
How a READY bundle is applied. See the enum for tradeoffs. Override per-call via SyncOptions.updateMode.
publicKey
| Type | string (PEM-encoded) |
| Required | when requireSignature: true |
| Default | — |
PEM-encoded public key (RSA or ECDSA). Generated by npx native-update keys generate. Keep the public half here in your app config; the private half stays on your CI / signing server and never ships in the binary.
requireSignature
| Type | boolean |
| Required | no |
| Default | false |
When true, every downloaded bundle must carry a signature that verifies against publicKey. Set this to true in production. It is false by default only so the development quick-start works without immediately needing a key pair.
checksumAlgorithm
| Type | ChecksumAlgorithm |
| Required | no |
| Default | 'SHA-256' |
Algorithm used for bundle integrity checks. Must match the algorithm used by your CLI signing step.
checkInterval
| Type | number (seconds) |
| Required | no |
| Default | 0 (no auto-check) |
Interval between automatic background sync calls, in seconds. 0 disables periodic checks (you call sync() manually). Common values: 3600 (hourly), 21600 (every 6 hours).
allowEmulator
| Type | boolean |
| Required | no |
| Default | false |
When false, sync calls fail on emulators / simulators with PLATFORM_NOT_SUPPORTED. Set to true for QA / CI flows running in emulators. Always false in production builds.
mandatoryInstallMode
| Type | InstallMode |
| Required | no |
| Default | 'immediate' |
How updates flagged mandatory: true by the server are applied. Default forces an immediate reload — the user cannot defer a mandatory update.
optionalInstallMode
| Type | InstallMode |
| Required | no |
| Default | 'on_next_restart' |
How updates not flagged mandatory are applied. Default waits until the next restart so the user is not interrupted.
maxBundleSize
| Type | number (bytes) |
| Required | no |
| Default | platform-dependent (~50 MB on Android, ~50 MB on iOS, ~10 MB on web) |
Hard size cap. Bundles exceeding this throw SIZE_LIMIT_EXCEEDED. Apple imposes its own ~200 MB cellular cap regardless.
allowedHosts
| Type | string[] |
| Required | no |
| Default | [] (every HTTPS host accepted) |
Allow-list of hostnames for bundle downloads. When non-empty, any download URL whose host is not in the list is rejected with INSECURE_URL. Use this to lock the plugin to your own CDN even if setUpdateUrl() is mis-used.
allowedHosts: ['updates.yourdomain.com', 'cdn.yourdomain.com']
Recommended production config
const liveUpdate: LiveUpdateConfig = {
appId: 'com.yourcompany.yourapp',
serverUrl: 'https://updates.yourdomain.com',
channel: 'production',
autoUpdate: false,
updateStrategy: UpdateStrategy.BACKGROUND,
publicKey: import.meta.env.VITE_NATIVE_UPDATE_PUBLIC_KEY,
requireSignature: true,
checksumAlgorithm: ChecksumAlgorithm.SHA256,
checkInterval: 3600, // hourly auto-check
allowEmulator: false,
mandatoryInstallMode: InstallMode.IMMEDIATE,
optionalInstallMode: InstallMode.ON_NEXT_RESTART,
maxBundleSize: 50 * 1024 * 1024, // 50 MB
allowedHosts: ['updates.yourdomain.com'],
};
Recommended development config
const liveUpdate: LiveUpdateConfig = {
appId: 'com.yourcompany.yourapp',
serverUrl: 'http://localhost:4477', // local dev server (CLI: `native-update server start`)
channel: 'dev',
autoUpdate: true,
updateStrategy: UpdateStrategy.IMMEDIATE,
requireSignature: false, // skip signing in dev
allowEmulator: true,
checkInterval: 60, // every minute for fast iteration
};
The dev config above uses http://localhost — that only works because Capacitor's local dev WebView allows non-HTTPS to localhost. In any non-localhost setup, the SDK will reject http:// URLs.