Skip to main content

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

DependencyMinimum
React Native0.76.0
React18.2.0
iOS13.4
AndroidAPI 24 (Android 7.0)
Node.js20.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

FileChange
ios/<App>/AppDelegate.mm or .swiftInjects a bundleURL override that calls Swiftpatch first and falls through to the default loader on nil.
ios/<App>/Info.plistAdds SwiftPatchDeploymentKey, BGTaskSchedulerPermittedIdentifiers entry (com.swiftpatch.bg-refresh), and UIBackgroundModes entries (fetch, processing).
android/app/src/main/java/.../MainApplication.kt or .javaInjects getJSBundleFile() / jsBundleFilePath override.
android/app/src/main/res/values/strings.xmlAdds <string name="swiftpatch_deployment_key">…</string>.
.swiftpatchrcProject config (app id, platform, signing-key path). Commit-safe — no secrets.
.swiftpatch/keys/private.pem + public.pemGenerated Ed25519 keypair. Private key is gitignored; upload the public key in the dashboard.
.gitignoreAppends .swiftpatch/, swiftpatch-artifacts/, swiftpatch-private.pem.

Monorepo + Expo support

  • Monorepo: swiftpatch init discovers every app under apps/* and patches each one.
  • Expo bare workflow: Detected automatically. The CLI patches the generated ios/ and android/ directories. If you later run npx expo prebuild --clean, re-run swiftpatch 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

App.tsx
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