Skip to main content

New Architecture Support

Swiftpatch ships as a TurboModule out of the box. Enable the New Architecture on your project and autolinking does the rest — no codegen invocation required from you.

Enable the New Architecture​

iOS​

ios/Podfile
ENV['RCT_NEW_ARCH_ENABLED'] = '1'

Then re-pod:

cd ios && pod install && cd ..

Android​

android/gradle.properties
newArchEnabled=true

Then:

cd android && ./gradlew clean && cd ..

Verifying you're on TurboModules​

The SDK exposes a runtime flag:

import { IS_TURBO_MODULE_ENABLED } from '@swiftpatch/react-native';

console.log('Using TurboModules:', IS_TURBO_MODULE_ENABLED);

When this is true, every native call goes through JSI directly — no bridge serialization.

Performance​

TurboModule calls skip JSON serialization and the bridge. Typical operation costs on a mid-range device:

OperationLegacy bridgeTurboModule
checkForUpdate() round trip15 ms2 ms
getCurrentBundle()8 ms1 ms
getSlotMetadata()10 ms2 ms

The SDK also uses the TurboModule's addListener/removeListeners bookkeeping, so native events (download progress, rollback, version-changed) are delivered with minimal overhead.

Codegen​

The SDK ships a codegen spec at src/native/NativeSwiftPatchSpec.ts. React Native's codegen consumes it during your app build and generates the native interfaces for iOS and Android. You don't invoke codegen yourself — it runs as part of pod install on iOS and Gradle's generateCodegenArtifactsFromSchema task on Android.

The spec uses only the types codegen allows:

  • Primitives (string, number, boolean).
  • Object, Array<Object>.
  • Nullable primitives (T | null).
  • Promise<T>.
  • No string-literal unions, no Pick/Omit, no imported types on method signatures.

Rich types (CheckResult, UpdateDescriptor, PatchDescriptor, SlotMetadataShape) live alongside the spec but are not consumed by codegen — they narrow the native return type inside the TypeScript wrapper.

codegenConfig​

Your app's package.json does not need a codegenConfig entry for Swiftpatch — the SDK's own package.json declares it:

@swiftpatch/react-native/package.json
{
"codegenConfig": {
"name": "RNSwiftPatchSpec",
"type": "modules",
"jsSrcsDir": "src/native",
"ios": { "componentProvider": "" }
}
}

React Native autolinking picks this up and generates the TurboModule stubs in the correct location.

Troubleshooting New Architecture builds​

  • "Cannot find module 'NativeSwiftPatch'" — codegen didn't run. Re-run pod install (iOS) or ./gradlew clean build (Android).
  • Duplicate native module — you have both old-arch and new-arch artifacts. Clean everything: cd ios && rm -rf Pods Podfile.lock && pod install && cd .. and cd android && ./gradlew clean.
  • TurboModuleRegistry.getEnforcing('SwiftPatch') fails — New Architecture is not actually enabled. Verify RCT_NEW_ARCH_ENABLED=1 (iOS) and newArchEnabled=true (Android).

Fallback to the legacy bridge​

If the New Architecture isn't enabled, the SDK automatically falls back to the legacy bridge module. The JavaScript API is identical. You won't notice a difference at the call-site.

Next steps​