AppRegistry

The Entry Point and AppRegistry

A React Native 36,878 app has no index.html and no createRoot. The native side starts first, loads the bundle into Hermes 11,328 and asks JavaScript for a component by name. AppRegistry connects the two: AppRegistry.registerComponent(appKey, () => Component) stores a component under a key, and the native host calls AppRegistry.runApplication(appKey, params) to mount it in a root view. The Community CLI's index.js calls registerComponent(appName, () => App) with appName read from app.json ("BookNestCli"), and its MainActivity.kt returns the same string from getMainComponentName(). Expo 6,418 wraps the call:

index.js in the Expo blank templateJavaScript
import { registerRootComponent } from 'expo';
import App from './App';
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

Its source, node_modules/expo/src/launch/registerRootComponent.tsx, imports Expo's side effects, wraps the component in developer tools unless NODE_ENV is production, and registers it as 'main'. The generated MainActivity.kt answers with override fun getMainComponentName(): String = "main", and the handshake shows in the device log:

Finding the runApplication call in logcatShell
adb -s emulator-5566 logcat -d -v raw -s ReactNativeJS | grep 'Running "main"' | tail -n 1
Output
Running "main" with {"rootTag":1,"initialProps":{},"fabric":true}

rootTag identifies the native root view, and "fabric":true confirms the New Architecture renderer (JSI, Fabric, TurboModules). The two names must match, or the app starts and then reports that no component was registered under that key. With Expo Router 6,418 , package.json sets "main": "expo-router/entry", which registers a root that renders your routes, so you never write index.js at all.