Installation
The Swiftpatch SDK is a single npm package. The swiftpatch init command handles all of the native setup — no hand-editing of AppDelegate, MainApplication, Info.plist, or strings.xml.
Prerequisites
| Dependency | Minimum |
|---|---|
| React Native | 0.76.0 |
| React | 18.2.0 |
| iOS | 13.4 |
| Android | API 24 (Android 7.0) |
| Node.js | 20.0 |
1. Install the package
npm install @swiftpatch/react-native
Install the CLI globally (or invoke with npx):
npm install -g swiftpatch-cli
2. Run swiftpatch init
npx swiftpatch init
The CLI patches your project end-to-end. Every file it touches is bounded by // swiftpatch-begin / // swiftpatch-end markers so swiftpatch unlink can cleanly reverse the operation.
What gets patched
| File | Change |
|---|---|
ios/<App>/AppDelegate.mm or .swift | Injects a bundleURL override that calls Swiftpatch first and falls through to the default loader on nil. |
ios/<App>/Info.plist | Adds SwiftPatchDeploymentKey, BGTaskSchedulerPermittedIdentifiers entry (com.swiftpatch.bg-refresh), and UIBackgroundModes entries (fetch, processing). |
android/app/src/main/java/.../MainApplication.kt or .java | Injects getJSBundleFile() / jsBundleFilePath override. |
android/app/src/main/res/values/strings.xml | Adds <string name="swiftpatch_deployment_key">…</string>. |
.swiftpatchrc | Project config (app id, platform, signing-key path). Commit-safe — no secrets. |
.swiftpatch/keys/private.pem + public.pem | Generated Ed25519 keypair. Private key is gitignored; upload the public key in the dashboard. |
.gitignore | Appends .swiftpatch/, swiftpatch-artifacts/, swiftpatch-private.pem. |
Monorepo + Expo support
- Monorepo:
swiftpatch initdiscovers every app underapps/*and patches each one. - Expo bare workflow: Detected automatically. The CLI patches the generated
ios/andandroid/directories. If you later runnpx expo prebuild --clean, re-runswiftpatch init. - Expo managed workflow: Use the Expo config plugin instead.
Re-running safely
swiftpatch init is idempotent. Running it twice is a no-op — existing markers are detected and skipped. If you want to remove everything cleanly:
swiftpatch unlink
That deletes the blocks between the markers, restoring the default React Native bundle loader.
3. Re-pod on iOS
cd ios && pod install && cd ..
4. Wrap your app
import { SwiftPatchProvider } from '@swiftpatch/react-native';
export default function Root() {
return (
<SwiftPatchProvider config={{ debug: __DEV__ }}>
<App />
</SwiftPatchProvider>
);
}
No JS-side deployment key needed — the SDK reads it from the native config swiftpatch init wrote.
Manual install (fallback)
If you cannot run the automated patcher (monorepo quirks, custom AppDelegate, strict code review policies), run it in manual mode:
npx swiftpatch init --manual
The CLI still generates keys, creates your app in the dashboard, writes .swiftpatchrc, and updates .gitignore. It then prints the exact snippets to paste into your native files. See iOS setup and Android setup for the full manual reference.
Verify the install
Start your app with npx react-native run-ios (or run-android) and check the debug logs. You should see:
SwiftPatch initialized (v2.x with dual-slot architecture)
Or call getNativeConfig() from JS to confirm the native keys are present:
import { getNativeConfig } from '@swiftpatch/react-native';
const cfg = await getNativeConfig();
console.log('Deployment key:', cfg.deploymentKey);
console.log('Project ID:', cfg.projectId);
If the keys are null, swiftpatch init has not yet been run in this project — re-run it.
Next steps
- Configuration — every Provider prop and
.swiftpatchrcfield. - Provider reference —
autoShowBanner,blockOnMandatory,theme,onUpdate. - iOS setup — the native file changes explained.
- Android setup — same, for Android.
- Expo projects — use the config plugin in managed or bare workflows.