<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
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>;
}
| Prop | Default | What it does |
|---|---|---|
config | required | SDK config. See Configuration. |
autoShowBanner | true | Render <UpdateBanner /> when an update is ready. Set false to render your own UI. |
blockOnMandatory | true | Render <UpdateBlocker /> full-screen for mandatory releases. |
showOnboardingOnFirstUpdate | false | One-time walkthrough after the first OTA applies. |
onUpdate | — | Fires 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
- Initializes the native module with your deployment key, crash window, and threshold.
- Reads
Info.plist/strings.xmlfor any field you didn't pass in JS. - Calls
markMounted()to arm the crash watchdog and clear the boot-loop flag. - Loads the current bundle info and slot metadata.
- Transitions to
RESTART_REQUIREDif a pending install exists. - Fires the initial
checkForUpdate(). - Starts the event-polling loop with adaptive backoff — pauses when backgrounded.
- Subscribes to
AppStateto re-check on resume.
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
- Hooks —
useSwiftpatchUpdate,useSwiftpatchProgress,useSwiftpatchReady - UI components — theme or replace the banner, blocker, and onboarding
- Methods — the imperative
Swiftpatch.*facade