Flipping the New Architecture flag is trivial. The migration is not.
The real work is auditing every native module and native view manager your app depends on, because each one needs a Fabric/TurboModule-compatible release before the flag is safe to flip in production.
#The old way
import { NativeModules } from 'react-native';
const { AnalyticsBridge } = NativeModules;
export function trackEvent(name: string, props: Record<string, string>) {
AnalyticsBridge.track(name, props);
}
On the old architecture this works as long as the native module exists at runtime. Nothing checks the contract at build time. Nothing tells you whether the module is New Architecture ready.
#The new way
import { TurboModuleRegistry, type TurboModule } from 'react-native';
export interface Spec extends TurboModule {
track(name: string, props: { [key: string]: string }): void;
}
export default TurboModuleRegistry.get<Spec>('AnalyticsBridge');
import AnalyticsBridge from './NativeAnalyticsBridge';
export function trackEvent(name: string, props: Record<string, string>) {
AnalyticsBridge?.track(name, props);
}
TurboModuleRegistry.get, unlike getEnforcing, returns null when a module hasn't shipped a compatible implementation yet. So the call degrades gracefully while you migrate dependencies one at a time instead of a single big-bang cutover.
#Why it matters
- Bridgeless startup and synchronous layout are opt-in per app, but only safe once every dependency underneath them is compatible. Migration is a dependency audit.
TurboModuleRegistry.getplus optional chaining lets you ship a partially migrated app rather than blocking on every library at once.- The community CLI's compatibility check flags unmigrated native libraries before you flip the flag app-wide, catching gaps earlier than a crash in QA.
#Gotcha
Flipping newArchEnabled doesn't fail loudly for a module that hasn't migrated. A legacy view manager without a Fabric component descriptor can silently render blank space instead of crashing, and a type check alone won't catch that. Budget time to manually exercise every screen using a third-party native view.