HealkiteDocs

React Native SDK

@healkite/react-native supports React Native 0.80+ with the New Architecture and Hermes, on iOS (Swift) and Android (Kotlin).

Install

sh
npm install @healkite/react-native && cd ios && pod install

Using Expo? Follow Expo instead of the native steps below.

Configure

iOS Info.plistAndroid res/values/strings.xml
CDN base URLHealkiteCdnUrlhealkite_cdn_url
Channel keyHealkiteChannelhealkite_channel
Runtime version (default: app version)HealkiteRuntimeVersionhealkite_runtime_version
Your bundle-signing public keyHealkitePublicKeyhealkite_public_key
Server manifest keyHealkiteManifestKeyhealkite_manifest_key
Backup CDN (optional)HealkiteCdnFallbackUrlhealkite_cdn_fallback_url

The dashboard's Settings tab shows these values ready to copy. On Healkite Cloud the CDN URL is https://cdn.healkite.com. Use HTTPS in release builds.

Load the OTA bundle

iOS, in your RCTDefaultReactNativeFactoryDelegate (for example AppDelegate.swift):

swift
import Healkite

override func bundleURL() -> URL? {
  #if DEBUG
  RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
  #else
  HealkiteCore.bundleURL() ?? Bundle.main.url(forResource: "main", withExtension: "jsbundle")
  #endif
}

Android, in MainApplication.kt:

kotlin
import dev.healkite.Healkite

getDefaultReactHost(
  context = applicationContext,
  packageList = PackageList(this).packages,
  jsBundleFilePath = if (BuildConfig.DEBUG) null else Healkite.getJSBundleFile(this),
)

Sync

tsx
import { useEffect } from "react";
import Healkite, { KillSwitchGate } from "@healkite/react-native";

export default function App() {
  useEffect(() => {
    Healkite.sync(); // confirm this bundle, check, install, send telemetry. Never throws.
  }, []);
  return <KillSwitchGate>{/* your app */}</KillSwitchGate>;
}

Call sync() (or notifyAppReady()) after your first screen renders. A new bundle that never gets there is rolled back on the next launch and never retried.

API

sync({ installMode? })Ready → check → install → restart if mandatory or installMode: "immediate" → telemetry
checkForUpdate()UPDATE_AVAILABLE, UP_TO_DATE, NOT_IN_ROLLOUT, SKIPPED_FAILED, ROLLBACK_TO_EMBEDDED, NO_RELEASE
notifyAppReady()Confirm the running bundle
restart()Apply a staged update now
getState()Running, pending and failed bundles, last rollback, last install method
trackEvent(name, props?)Business events used by guarded rollouts and experiments
installErrorHandler()Report fatal JS errors (crash-free sessions)
getKillSwitch(), useKillSwitch(), <KillSwitchGate fallback?>Maintenance mode
openPreview(url), exitPreview(), <PreviewBanner />PR previews
getPushTopic(), handlePush(data)Instant hotfix
flushEvents()Send queued telemetry now

Crashes and business metrics

ts
Healkite.installErrorHandler();                 // once, at startup
Healkite.trackEvent("checkout_success");        // whenever it happens

Guarded rollouts compare these per session with the previous release.

Testing

js
jest.mock("@healkite/react-native", () => require("@healkite/react-native/jest/mock"));

How an update is applied

  1. The manifest is fetched (CDN-cached, revalidated) and its server signature verified.
  2. The device decides rollout membership locally from a hash of its random id.
  3. The bundle signature is checked before download. A patch is used when one exists for the running bundle.
  4. Every file is checked against its sha256 and unpacked into the app's support directory.
  5. The next launch is a trial; notifyAppReady() keeps it. A crash before that rolls back.
  6. A new store binary always starts from its embedded bundle.