Skip to main content

<SwiftPatchProvider>

Wrap your app once. The provider initializes the native module, arms crash detection, polls for updates on launch and resume, and renders the update banner when a release is ready.

The two-line integration

App.tsx
import { SwiftPatchProvider } from '@swiftpatch/react-native';

export default function Root() {
return (
<SwiftPatchProvider config={{ debug: __DEV__ }}>
<App />
</SwiftPatchProvider>
);
}

With zero extra props the provider:

  • Reads your deployment key from Info.plist / strings.xml.
  • Checks for updates on cold start and on resume.
  • Renders <UpdateBanner /> at the bottom of the screen when a release is ready.
  • Renders <UpdateBlocker /> as a full-screen modal for mandatory releases.
  • Matches the OS light/dark theme.

Props

interface SwiftPatchProviderProps {
config: SwiftPatchUserConfig | SwiftPatchConfig;
children: ReactNode;

// Optional opinionated DX layer
autoShowBanner?: boolean;
blockOnMandatory?: boolean;
showOnboardingOnFirstUpdate?: boolean;
onUpdate?: (update: ReleaseInfo) => void;
theme?: 'auto' | 'light' | 'dark' | Partial<Theme>;
}
PropDefaultWhat it does
configrequiredSDK config. See Configuration.
autoShowBannertrueRender <UpdateBanner /> when an update is ready. Set false to render your own UI.
blockOnMandatorytrueRender <UpdateBlocker /> full-screen for mandatory releases.
showOnboardingOnFirstUpdatefalseOne-time walkthrough after the first OTA applies.
onUpdateFires when an update becomes available. Complements config.onUpdate.
theme'auto''auto' follows the OS. Pass a partial Theme to override.

Recipes

Silent mode — render your own UI

<SwiftPatchProvider
config={{ debug: __DEV__ }}
autoShowBanner={false}
blockOnMandatory={false}
>
<App />
</SwiftPatchProvider>

Lifecycle events still fire. Subscribe with useSwiftpatchUpdate() or Swiftpatch.onUpdateReady() to drive your own banner. See Hooks and Methods.

Custom theme

<SwiftPatchProvider
config={{ debug: __DEV__ }}
theme={{
accent: '#ff3366',
background: '#0a0a0f',
surface: '#14141f',
text: '#ffffff',
textMuted: '#8a8aa0',
}}
>
<App />
</SwiftPatchProvider>

The full Theme interface and per-component overrides live in UI components.

Fire analytics on every update

<SwiftPatchProvider
config={{ debug: __DEV__ }}
onUpdate={(update) => {
analytics.track('ota.update_available', {
version: update.version,
isPatch: update.isPatch,
sizeKb: Math.round(update.downloadSize / 1024),
});
}}
>
<App />
</SwiftPatchProvider>

Force-update gate with onboarding

<SwiftPatchProvider
config={{ debug: __DEV__ }}
blockOnMandatory
showOnboardingOnFirstUpdate
>
<App />
</SwiftPatchProvider>

The blocker shows for any release flagged mandatory. Onboarding shows exactly once, after the first OTA applies successfully.

What happens on mount

  1. Initializes the native module with your deployment key, crash window, and threshold.
  2. Reads Info.plist / strings.xml for any field you didn't pass in JS.
  3. Calls markMounted() to arm the crash watchdog and clear the boot-loop flag.
  4. Loads the current bundle info and slot metadata.
  5. Transitions to RESTART_REQUIRED if a pending install exists.
  6. Fires the initial checkForUpdate().
  7. Starts the event-polling loop with adaptive backoff — pauses when backgrounded.
  8. Subscribes to AppState to re-check on resume.
One provider per app

Mounting multiple providers corrupts the crash watchdog and double-counts events. Wrap your app once at the root.

Do you need the provider?

If you want the built-in banner, blocker, onboarding, or any hook: yes.

For headless background tasks or non-React surfaces, drive updates through the imperative Swiftpatch class — see Methods.

Next steps

  • HooksuseSwiftpatchUpdate, useSwiftpatchProgress, useSwiftpatchReady
  • UI components — theme or replace the banner, blocker, and onboarding
  • Methods — the imperative Swiftpatch.* facade