Hermes — qué es, motor JS para React Native y principio de funcionamiento

Autor: IT Sectr Publicado: 2026-07-06 Tiempo de lectura: 9 min

Hermes es un motor JavaScript con compilación AOT (Ahead-of-Time), desarrollado por Meta para React Native y optimizado para dispositivos móviles con memoria limitada. Según el blog oficial de Meta Engineering (2022), Hermes reduce el tiempo de inicio de la aplicación entre un 20 y un 50 % y disminuye el tamaño del bundle entre un 30 y un 40 % en comparación con JavaScriptCore. A diferencia de V8 o JSC, Hermes no utiliza compilación JIT en el dispositivo — todo el JavaScript se compila en bytecode durante la fase de compilación a través de Hermes CLI. Esto es especialmente importante para iOS, donde la compilación JIT está restringida por las políticas de App Store.

Puntos clave

  • Hermes — un motor JavaScript con compilación AOT, desarrollado por Meta para React Native
  • AOT vs JIT — Hermes compila JS en bytecode en la compilación, sin JIT en el dispositivo
  • Rendimiento — inicio de la aplicación 20-50% más rápido, bundle 30-40% más pequeño
  • Hades GC — recolector de basura de baja latencia optimizado para escenarios móviles
  • Estándar — ECMAScript 2020+ sin soporte completo de Proxy, BigInt y Reflect

Qué es Hermes

Hermes es un motor JavaScript compacto de código abierto (licencia MIT) creado por Meta para React Native y optimizado para funcionar en dispositivos móviles con recursos limitados. La principal innovación de Hermes es abandonar la compilación JIT en favor de AOT (Ahead-of-Time). Durante la fase de compilación de la aplicación React Native, Metro Bundler pasa el JavaScript compilado a Hermes CLI, que lo transforma en bytecode HBC (Hermes ByteCode). Este bytecode se ejecuta directamente por el motor sin compilación adicional en el dispositivo. Este enfoque proporciona un rendimiento predecible: sin calentamiento JIT, sin pausas de compilación, sin consumo extra de batería. Hermes está diseñado teniendo en cuenta las limitaciones de los dispositivos móviles: poca RAM (1-4 GB), consumo de energía limitado y la necesidad de un inicio en frío rápido. La primera versión pública de Hermes se lanzó en 2019 y, a partir de React Native 0.70 (2022), el motor se convirtió en el estándar en Android.

Hermes vs JavaScriptCore: comparación de motores

JavaScriptCore (JSC) es el motor WebKit estándar utilizado por Safari y React Native antes de la versión 0.70. JSC admite compilación JIT, lo que proporciona un alto rendimiento para operaciones JavaScript complejas. Sin embargo, JIT requiere calentamiento: los primeros segundos de ejecución son más lentos (modo interpretado), luego JIT compila las rutas más usadas. En iOS, JIT prácticamente no está disponible debido a las políticas de App Store (prohibición de generación dinámica de código), por lo que JSC en iOS funciona solo en modo interpretado — el rendimiento cae. JSC tiene un tamaño binario mayor (aproximadamente 10 MB) y consume más RAM debido a la infraestructura JIT. Hermes no depende de JIT, lo que proporciona un rendimiento predecible inmediatamente después del inicio (cold start). JSC es más completo en soporte del estándar ECMAScript (incluyendo Proxy, BigInt, Reflect), pero a costa de un mayor consumo de recursos. Para proyectos React Native donde el inicio en frío y el tamaño pequeño son críticos — Hermes es preferible. Para proyectos con cálculos JS pesados (juegos, WebGL) — JSC puede ofrecer un rendimiento máximo más alto.

ParámetroHermesJavaScriptCore
CompilaciónAOT (en compilación)JIT + Interpretado (en dispositivo)
Cold start20-50% más rápidoNivel base
Tamaño del bundle30-40% menorNivel base
Consumo de RAM20-30% menosNivel base
ECMAScriptES2020 (limitaciones)ES2022+ (completo)
JIT en iOSNo requeridoNo disponible (solo interpretado)
Binario~3 MB~10 MB

Compilación AOT: cómo funciona la compilación anticipada

La compilación AOT (Ahead-of-Time) en Hermes ocurre en dos etapas. En la primera etapa, Metro Bundler recopila los archivos JavaScript en un bundle único y lo pasa a Hermes CLI (la utilidad hermesc). En la segunda etapa, hermesc analiza el AST de JavaScript, genera una representación intermedia HIR (Hermes Intermediate Representation) y luego emite bytecode HBC binario. El resultado es un archivo .hbc que contiene solo bytecode sin el JavaScript original. El runtime de Hermes carga HBC directamente, sin análisis ni compilación. Esto acelera radicalmente el inicio: en lugar de analizar miles de líneas de JS (async), el motor lee un formato binario precompilado. AOT también reduce el tamaño: el bytecode es en promedio un 30% más compacto que el AST de JavaScript. La desventaja de AOT — la imposibilidad de ejecutar eval, new Function o require dinámico en tiempo de ejecución — todos los módulos deben conocerse en la compilación.

bash
# Install Hermes CLI standalone
npm install hermes-engine

# Compile JS to HBC bytecode
npx hermesc -emit-binary -out bundle.hbc bundle.js

# Bytecode statistics
npx hermesc -dump-bytecode bundle.hbc  # shows HBC instructions

# Original JS vs HBC size
wc -c bundle.js      # 2,300,000 bytes
wc -c bundle.hbc     # 1,450,000 bytes (37% reduction)

Métricas de rendimiento de Hermes

El rendimiento de Hermes se mide mediante tres métricas clave: Time-To-Interactive (TTI), tamaño del APK/IPA y consumo de RAM. Según datos de Meta, en Android Hermes reduce el TTI en un 34% en comparación con JSC: de 4.2 segundos a 2.8 segundos en un dispositivo de gama media (Moto G7). El tamaño del APK disminuye un 28% gracias al bytecode compacto y la ausencia de bibliotecas JIT. El consumo de RAM es en promedio un 22% menor bajo la misma carga — esto es especialmente importante para dispositivos con 2-3 GB de RAM. En iOS, la ganancia es aún más significativa: dado que JSC no puede usar JIT, Hermes proporciona una mejora del TTI de hasta el 45%. Las métricas se basan en pruebas de Meta con la aplicación Facebook Lite. En proyectos reales, la ganancia varía: para pantallas simples (listas, texto) Hermes da una mejora mayor, para animaciones pesadas — menor. Herramienta de perfilado: React Native Profiler + hermes profile --heap.

Perfilado de memoria con Hermes

Hermes incluye un perfilador de memoria integrado accesible a través de Chrome DevTools. Conéctate a la aplicación mediante Metro, abre la pestaña Memoria y selecciona Hermes (JavaScript) en los tipos de instantáneas. Hermes admite tres tipos de instantáneas: Heap Snapshot (todos los objetos), Allocation Timeline (tiempo de vida de los objetos) y Allocation Sampling (perfil de muestreo). Hades GC reduce las pausas del GC al mínimo — en promedio una pausa de 2-5ms por cada 10 segundos de funcionamiento, frente a pausas de 10-20ms para JSC en el mismo período.

Recolector de basura Hades GC

Hades GC es el recolector de basura de Hermes, diseñado para escenarios móviles con pausas mínimas. A diferencia del GC mark-sweep de JSC, Hades utiliza recolección concurrente: el recolector trabaja en paralelo con el hilo principal de ejecución, deteniéndolo solo por intervalos cortos. Hades GC divide el heap en generaciones: la generación joven (nursery) se recolecta con frecuencia y rapidez (Scavenge), la generación vieja se recolecta con menos frecuencia y con pausas más pequeñas. El tamaño del heap es configurable: por defecto — 2/3 de la RAM disponible de la aplicación, umbral mínimo — 32 MB. Hades no utiliza el enfoque stop-the-world: incluso una recolección completa de la generación vieja no toma más de 5-8ms. El recolector está optimizado para escenarios móviles típicos: muchos objetos de corta duración (cadenas temporales, objetos React fiber), pocos de larga duración. Para aplicaciones con creación intensiva de objetos (listas, animaciones), Hades proporciona FPS más fluidos en comparación con JSC.

Cómo habilitar Hermes en un proyecto React Native

La habilitación de Hermes depende de la versión de React Native y la plataforma. A partir de React Native 0.70, Hermes está habilitado por defecto para Android en proyectos nuevos. Para iOS, Hermes es opcional. Para habilitar en Android: en el archivo android/app/build.gradle establece enableHermes: true en el bloque project.ext.react.enableHermes. Para iOS: establece hermes_enabled en true en el Podfile mediante use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). Después de habilitar, ejecuta pod install. Para proyectos existentes, verifica la compatibilidad de las bibliotecas: Hermes no soporta Proxy, eval y algunas características de ES2021. Usa npx react-native info para verificar la configuración. Para cambiar entre Hermes y JSC, cambia la bandera y realiza una limpieza y reconstrucción.

groovy
// android/app/build.gradle — enable Hermes
project.ext.react = [
    enableHermes: true,
    cliPath: "node_modules/react-native/cli.js"
]

// iOS/Podfile — enable Hermes on iOS
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'MyApp' do
  config = use_native_modules!
  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => true
  )
end

Limitaciones de Hermes: qué no es compatible

Las principales limitaciones de Hermes están relacionadas con la falta de JIT. Hermes no soporta: Proxy y Reflect API (usados en MobX, Vue, algunos state managers), BigInt (números grandes), Symbol.toStringTag, WeakRef y FinalizationRegistry. Las funciones eval y new Function lanzan una excepción en tiempo de ejecución. Los callbacks de Array.prototype.flat y flatMap con un argumento this funcionan con limitaciones. Los formatos de fecha ISO 8601 con zonas horarias no se procesan completamente. La mayoría de estas limitaciones no afectan a las aplicaciones típicas de React Native: React y React Native utilizan un conjunto limitado de características de ES. Si una biblioteca requiere Proxy (por ejemplo, MobX 6+ con Proxy), usa configure({ useProxies: false }) o elige una alternativa. Para verificar la compatibilidad del código existente, ejecuta npx hermesc -check en tu bundle — mostrará la lista de características no soportadas.

  • Proxy / Reflect — no implementados; las bibliotecas que requieren Proxy necesitan modo fallback
  • BigInt — no disponible; usa bibliotecas bignumber.js para números grandes
  • eval / new Function — lanza excepción; todos los módulos deben ser estáticos
  • WeakRef / FinalizationRegistry — no soportados; no hay alternativa
  • Symbol.toStringTag — ignorado; instanceof funciona correctamente

Preguntas frecuentes

¿Cómo comprobar si la aplicación funciona con Hermes?

En la consola de la aplicación, ejecuta console.log(global.HermesInternal). Si el objeto HermesInternal existe — la aplicación funciona con Hermes. Alternativamente: console.log(global.HermesInternal?.getRuntimeProperties()) — mostrará la versión del motor y los parámetros del GC. En compilaciones Release, HermesInternal puede no estar disponible para minimizar el tamaño.

¿Por qué la aplicación falla en iOS después de habilitar Hermes?

Verifica la configuración del Podfile: Hermes en iOS requiere New Architecture (Fabric Renderer). Establece :hermes_enabled => true, ejecuta pod install --repo-update. Si el proyecto se actualiza desde React Native inferior a 0.70, verifica la compatibilidad de las bibliotecas con New Architecture. Deshabilita Hermes si una biblioteca de terceros requiere JSC — cambia la bandera a false y reinstala los Pods.

¿Afecta Hermes al Hot Reload durante el desarrollo?

No, Hermes no afecta al Hot Reload / Fast Refresh. Durante el desarrollo, Metro ejecuta el bundle de JavaScript sin compilación Hermes (JS plano). El bytecode de Hermes se compila solo para compilaciones Release. En modo Debug, se usa JavaScriptCore estándar o Hermes en modo interpretado. La velocidad de Hot Reload no cambia cuando Hermes está habilitado en la configuración — el cambio ocurre solo en la etapa de compilación de producción.

¿Se puede usar Hermes con Expo?

, a partir de Expo SDK 45, Hermes es compatible con managed workflow. En app.json especifica "jsEngine": "hermes". Para bare workflow, Hermes funciona como en un proyecto React Native normal. Expo Go no soporta Hermes — usa Expo Dev Client o EAS Build para compilaciones con Hermes. Verifica la compatibilidad de las bibliotecas mediante expo doctor.

¿Cómo comparar el rendimiento de Hermes y JSC en mi proyecto?

Usa React Native Performance Monitor (métricas FPS) y Hermes Profiling Tools. Compila dos versiones de la aplicación — con Hermes y JSC — en el mismo dispositivo. Mide: cold start (desde tocar el icono hasta la primera pantalla interactiva), TTI (Time-To-Interactive), tamaño del APK/IPA y consumo máximo de RAM. Ejecuta las pruebas al menos 3 veces para cada configuración. Ventaja típica de Hermes: inicio 20-40% más rápido, RAM 15-25% menor.

Resumen

  • Hermes — un motor JavaScript de Meta con compilación AOT para React Native, estándar en Android desde 0.70
  • Compilación AOT proporciona un rendimiento predecible sin calentamiento JIT en el dispositivo
  • Cold start 20-50% más rápido, tamaño del bundle 30-40% menor vs JavaScriptCore
  • Hades GC — recolector de basura concurrente con pausas de 2-5ms en lugar de 10-20ms para JSC
  • Limitaciones: Proxy, BigInt, eval, WeakRef no soportados — verifica tus bibliotecas
  • Habilitación: enableHermes en build.gradle (Android) o hermes_enabled en Podfile (iOS)
  • Hermes CLI permite compilar bytecode .hbc y perfilar memoria a través de DevTools
  • Hermes no afecta al Hot Reload en desarrollo — el bytecode se compila solo para Release

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también