El paquete expo es más que un fijador de versión - inicia Expo Modules Core, el runtime JSI-nativo que registra módulos de SDK de Expo, expone requireNativeModule, y conecta JavaScript con implementaciones en Swift/Kotlin en todas las aplicaciones Expo y bare React Native.
Registra componente raíz como "main"; entrada web + helpers de desarrollo
requireNativeModule(name)
Carga módulo nativo; lanza si falta
requireOptionalNativeModule(name)
Igual, devuelve null cuando está ausente
requireNativeView
Reemplazo drop-in para requireNativeComponent
NativeModule
Clase base para módulos nativos; extiende EventEmitter
SharedObject / SharedRef
Identificadores nativos duraderos (reproductores de video, refs de imagen) sobre JSI
isRunningInExpoGo()
Verificación en tiempo de ejecución para Expo Go vs binario personalizado
import { EventEmitter, requireNativeModule } from "expo-modules-core";// Los métodos de NativeModule son asíncronos por defecto a menos que se marquen como síncronos en código nativoconst module = requireNativeModule("ExpoFileSystem");
Nombre MainComponent incorrecto en aplicaciones bare - La entrada nativa aún dice "MyApp" mientras que JS registra "main". Solución: Establece getMainComponentName() / moduleName a "main" o coincide con tu nombre registerRootComponent.
Autolinking faltante después de agregar expo-camera - La compilación nativa nunca compila el módulo. Solución: Ejecuta npx expo prebuild o verifica expo-modules-autolinking en Gradle/Podfile; reconstruye nativo.
Llamar a requireNativeModule en Expo Go para módulos no empaquetados - Core funciona, pero la clase nativa nunca se envió en Expo Go. Solución: Development build con el módulo instalado.
Asumir métodos síncronos de bridge en proxy de fallback - Cuando falta el enlace JSI, algunas API síncronas no funcionan o lanzan. Solución: Reconstruye con New Architecture habilitada; verifica que el módulo soporte funciones síncronas.
Importar desde expo vs expo-modules-core - Los autores de aplicaciones pueden usar cualquiera para requireNativeModule; los paquetes de biblioteca deben importar desde expo-modules-core para evitar ciclos de peer-dep. Solución: Bibliotecas - expo-modules-core; aplicaciones - re-exportaciones de expo.
Fugando SharedObjects - Los identificadores nativos duraderos (reproductores de video) retienen memoria hasta release() o limpieza de hook. Solución: Usa hooks de paquete (useVideoPlayer) o llama a release() cuando hayas terminado.
Omitir npx expo install - Las versiones npm manuales desajustan binarios nativos vs stubs JS. Solución: Siempre npx expo install <pkg> para que autolinking resuelva compilaciones compatibles con SDK 57.
La infraestructura nativa + JavaScript detrás de la API de Expo Modules. Registra módulos nativos en un objeto host JSI, expone requireNativeModule, y proporciona primitivas NativeModule, EventEmitter, y SharedObject utilizadas por cada paquete expo-*.
¿Cuál es la diferencia entre el paquete expo y expo-modules-core?
expo es el runtime paraguas - registerRootComponent, isRunningInExpoGo, polyfills web, y re-exportaciones. expo-modules-core es la capa de cargador de módulo de bajo nivel que los autores de biblioteca dependen.
¿Qué hace registerRootComponent?
Llama a AppRegistry.registerComponent("main", …), configura renderizado web, rellena process.nextTick, y habilita helpers de Fast Refresh solo para desarrollo. Cada aplicación Expo en última instancia registra "main" como el nombre del componente raíz.
¿Cómo encuentra requireNativeModule código nativo?
Consulta el objeto host JSI rellenado en el lanzamiento nativo. Si está ausente, retrocede a un módulo proxy de bridge - aún funcional pero carece de algunos métodos síncronos JSI.
Causas comunes: proyecto nativo no reconstruido después de instalar, autolinking mal configurado en aplicación bare, módulo no incluido en Expo Go, o error tipográfico en nombre del módulo. Reconstruye nativo y verifica con npx expo-modules-autolinking resolve.
¿Expo Modules Core requiere Expo Go?
No. Se ejecuta en compilaciones de desarrollo, binarios de producción, y aplicaciones bare React Native una vez que se configure autolinking y el nombre de entrada "main".
¿Cómo se relaciona esto con New Architecture?
Los módulos Expo son JSI-first y soportan TurboModules/Fabric. SDK 57 por defecto usa New Architecture en RN 0.86; Core maneja ambas rutas con fallback de bridge para configuraciones más antiguas.
¿Qué es SharedObject?
Una instancia nativa respaldada por JSI con métodos y eventos - p. ej. un reproductor de video. Extiende EventEmitter y persiste a través de llamadas JS hasta release() o desmontaje de hook.
Trampa común: ¿Por qué funcionan importaciones de alto nivel pero requireNativeModule falla?
Podrías estar en Expo Go donde existe el paquete JS de alto nivel pero el módulo nativo no está empaquetado, o el nombre nativo difiere (ExpoDevice vs Device). Verifica el nombre exacto del módulo nativo en los documentos del paquete y usa un development build.
¿Puedo usar Expo Modules en una aplicación brownfield?
Sí. Ejecuta npx install-expo-modules, alinea el nombre del componente raíz, reconstruye nativo, e instala paquetes de SDK con npx expo install.
¿Qué es expo-modules-autolinking?
Herramientas en tiempo de compilación que escanean dependencias y vinculan entradas Gradle/Podspec para que los módulos Expo nativos se compilen en tu aplicación sin vinculación manual.
¿Cómo llegan eventos nativos a JavaScript?
NativeModule extiende EventEmitter. El código nativo emite eventos; JS se suscribe a través de addListener, useEventListener, o useEvent desde expo.
¿Debería el código de biblioteca importar desde expo o expo-modules-core?
Los paquetes de biblioteca deben depender de expo-modules-core para requireNativeModule para evitar peers circulares. El código de aplicación puede importar desde expo por ergonomía.
¿expo incluye fetch global en SDK 57?
Sí. SDK 57 instala fetch global compatible con WinterCG en nativo a menos que se establezca EXPO_PUBLIC_USE_RN_FETCH=1. La importación nombrada import { fetch } from 'expo/fetch' siempre usa la implementación de Expo.