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