Volver al inicio

El ecosistema oculto de JavaScript

🇺🇸You can read the English version here

Cuando me preguntan cuál es el mejor lenguaje para programar, mi respuesta casi siempre es “depende”. JavaScript me gusta mucho, pero la elección de un lenguaje si depende de muchos factores, y uno de los más importantes es el ecosistema que existe a su alrededor.

El ecosistema incluye todo lo que rodea a un lenguaje: la comunidad, la documentación, las herramientas de testing, los gestores de paquetes y dependencias, el soporte de IntelliSense y los proyectos reales que demuestran su uso en producción. Todos estos elementos influyen directamente en la experiencia de desarrollo, también conocida como DX.

🤿 DX (Developer Experience): es el concepto que se enfoca en mejorar la experiencia al desarrollar software. Por ejemplo, que escribir código sea rápido y cómodo, o que puedas automatizar tareas para validar que tu código cumple ciertos estándares de calidad.

Parte de ese ecosistema está formada por componentes de los que normalmente no nos preocupamos. A esto lo llamo “el ecosistema oculto”: piezas fundamentales para que JavaScript sea tan versátil y esté presente prácticamente en todas partes, como los motores y los entornos de ejecución.

Motores de JavaScript

Los navegadores web modernos utilizan distintos motores de JavaScript para interpretar o compilar el código, como vimos en el capítulo sobre Tipos de lenguajes de programación. Cada motor tiene su propia arquitectura, optimizaciones y decisiones de diseño.

JavaScript no se ejecuta de forma nativa en el navegador. El código debe ser transformado a código máquina, y el motor es el responsable de realizar ese proceso. Veamos algunos de los motores actuales y en qué se destacan.

V8

V8 es uno de los motores más populares. Fue creado por Google para su navegador Chrome, pero también dio origen a Node.js y hoy en día es utilizado por Deno, entre otros proyectos.

Es un motor de código abierto que se destaca por su alto rendimiento. Utiliza un intérprete y un compilador just-in-time optimizado para convertir JavaScript a código máquina, además de un recolector de basura avanzado que ayuda a reducir pausas largas.

⏱️ Just-in-time compilation (JIT): es una técnica en la que el código se compila a código máquina mientras el programa se está ejecutando, en lugar de hacerlo completamente antes. Esto permite aplicar optimizaciones basadas en cómo se comporta el código en tiempo real.

🚛 Recolector de basura (Garbage Collector): es un mecanismo que se emplea en los lenguajes de programación para liberar espacios de memoria que contienen objetos o datos que ya no son necesarios.

El resultado es un arranque rápido y una gran velocidad de ejecución una vez que el código está “caliente”. 🔥

V8 se actualiza con frecuencia para incorporar las últimas características de ECMAScript y es fácilmente embebible en otras aplicaciones. Además, está presente en muchos navegadores gracias al proyecto Chromium.

🐤 Chromium: es el proyecto de código abierto en el que se basa Chrome. En otras palabras, es el corazón de Chrome sin las partes privadas y propietarias que añade Google. Navegadores como Microsoft Edge, Opera y Brave también se basan en Chromium.

SpiderMonkey

SpiderMonkey es el motor utilizado por Mozilla Firefox, originalmente creado por Netscape. Emplea un intérprete base y múltiples niveles de compilación just-in-time, junto con un recolector de basura ajustado para el entorno del navegador. Se destaca por su estricto apego al estándar ECMAScript y por ofrecer excelentes herramientas de depuración.

También puede ser embebido en aplicaciones que necesiten un entorno de ejecución de JavaScript completo y conforme al estándar. Un caso conocido fue MongoDB, un motor de base de datos no relacional que utilizó SpiderMonkey para ejecutar JavaScript en distintas funcionalidades internas, aunque con el tiempo este uso se ha ido reduciendo.

JavaScriptCore

JavaScriptCore, también llamado Nitro o WebKit JavaScript Engine, es el motor utilizado por Safari. Evolucionó desde el antiguo motor SquirrelFish hacia una arquitectura de múltiples niveles con un compilador just-in-time optimizado.

Apple lo ha afinado especialmente para maximizar la eficiencia en memoria y el bajo consumo energético, pensando en dispositivos con recursos limitados. Se integra estrechamente con las APIs nativas de iOS y macOS a través del framework JavaScriptCore y prioriza la estabilidad y el comportamiento predecible sobre cambios radicales.

Chakra

Chakra fue el motor utilizado por Internet Explorer 9 y posteriores, así como por Microsoft Edge en su versión legada, Edge 18. Diseñado por Microsoft, ofrecía compilación just-in-time y estaba fuertemente optimizado para los sistemas operativos Windows.

🦋 Microsoft Edge migró a Chromium y pasó a utilizar V8 en 2020. Aun así, Chakra continuó disponible como ChakraCore, un proyecto de código abierto orientado a usos embebidos, pero Microsoft dejó de publicar nuevas versiones y la disponibilidad de sus descargas oficiales se retiró en 2024.

JavaScript en el servidor

Durante muchos años, JavaScript tuvo un lugar muy limitado en el desarrollo web. Hasta inicios del nuevo milenio, alrededor del año 2000, era visto casi exclusivamente como un lenguaje para el navegador. Su propósito se reducía a añadir pequeñas dosis de interactividad: validación de formularios, mostrar u ocultar elementos, reaccionar a clics, entre otras tareas similares.

Quien quisiera construir una aplicación web completa debía enfrentarse, al menos, a dos mundos distintos. Por un lado, JavaScript en el navegador. Por el otro, cualquier lenguaje de la época capaz de ejecutarse en el servidor, como PHP, Python, Java o Ruby. Dos lenguajes, dos ecosistemas y, muchas veces, dos formas muy diferentes de solucionar problemas.

Ese fue el escenario dominante durante varios años, hasta que en 2009 ocurrió un punto de inflexión. En una conferencia, Ryan Dahl presentó Node.js, una idea que en su momento parecía una locura: ejecutar JavaScript no solo en el navegador, sino también en el servidor.

Node.js se convirtió así en el entorno de ejecución que popularizó JavaScript del lado del servidor, construido sobre el motor V8. De pronto, el lenguaje que durante años había sido considerado lento e inadecuado para tareas “serias” comenzaba a demostrar que podía competir en las grandes ligas.

Pero Node.js no solo trajo JavaScript al servidor. También introdujo un modelo de ejecución no bloqueante y orientado a eventos. A diferencia de muchos lenguajes y servidores tradicionales, Node.js podía manejar miles de conexiones concurrentes de forma eficiente, delegando las operaciones costosas al sistema y reaccionando cuando estas finalizaban.

Este enfoque encajaba de manera natural con la realidad de la web moderna: aplicaciones altamente concurrentes, más enfocadas en coordinar eventos que en consumir recursos de forma constante.

Por primera vez, JavaScript podía cubrir todo el recorrido de una aplicación web. El mismo lenguaje servía para construir la interfaz de usuario y las interacciones, implementar la lógica de negocio, acceder a datos y exponer APIs. El límite entre cliente y servidor seguía existiendo y siendo claro, pero el lenguaje que los conectaba era ahora el mismo.

El impacto fue inmediato: JavaScript dejó de ser solo un lenguaje y comenzó a consolidarse como una plataforma completa. Surgió npm, un sistema de paquetes que con el tiempo se convertiría en uno de los repositorios de software más grandes del mundo. Aparecieron frameworks web como Express, que simplificaron enormemente la creación de servidores con tan solo unas líneas de código. Y, casi sin darse cuenta, la comunidad empezó a construir sus propias herramientas en JavaScript: linters, bundlers, task runners y, más adelante, compiladores y entornos completos de desarrollo.

Por primera vez, los desarrolladores podían apostar por un solo lenguaje, profundizar en él y utilizarlo en todos los niveles de una aplicación. JavaScript dejaba atrás su papel secundario y se consolidaba como algo nuevo, un lenguaje verdaderamente full-stack.

Nuevas generaciones de entornos

El crecimiento de JavaScript trajo consigo la aparición de entornos de ejecución alternativos a Node.js, diseñados para casos modernos como aplicaciones serverless, edge computing o para mejorar decisiones históricas que en Node.js eran difíciles de cambiar sin romper compatibilidad.

Deno

Deno es un entorno de ejecución creado por Ryan Dahl, el mismo creador de Node.js. Fue presentado en 2018 con la intención de corregir algunos “errores de diseño” que Dahl identificaba en Node.js.

🦕 Por si aún no lo has notado, Deno es un anagrama de Node, el nombre asociado a Node.js.

Es de código abierto, está escrito en Rust y utiliza el motor V8. A diferencia de Node.js, Deno se diseñó con la seguridad como punto de partida: por defecto, no permite acceder al sistema de archivos, a la red o a variables de entorno a menos que se otorguen permisos explícitos.

Además, incorpora soporte nativo para TypeScript y adopta la importación de módulos mediante URLs o archivos locales, en lugar de tomar npm como punto de partida obligatorio. Deno también busca ofrecer una experiencia más integrada. Incluye herramientas como formateador, linter, servidor de documentación y ejecutor de pruebas, además de priorizar APIs web estándar cuando es posible. Su comunidad sigue siendo más pequeña que la de Node.js, pero Deno ha avanzado mucho en compatibilidad con paquetes y proyectos del ecosistema Node.js.1

Una buena razón para usar Deno es precisamente esa: representa una segunda oportunidad para diseñar un entorno de ejecución moderno de JavaScript, aprendiendo de más de una década de experiencia con Node.js.

Bun

Bun es un entorno de ejecución que sorprendió a la comunidad por hacer varias cosas fuera de lo convencional. Fue introducido en 2021 y se posicionó como una alternativa ultrarrápida, enfocada principalmente en rendimiento y experiencia de desarrollo.

🏎️ Benchmarking: en el ecosistema siempre nos vamos a encontrar con herramientas, frameworks o entornos de ejecución que dicen ser más rápidos que otros. Pero muchas comparaciones suelen usar ejemplos que benefician a la herramienta que reclama ser la ganadora. Por lo tanto, es importante revisar el contexto y el código usado con criterio propio.

Bun fue escrito en Zig2 y, en lugar de V8, utiliza JavaScriptCore. Su objetivo es ser un reemplazo directo de Node.js, pero extremadamente más rápido.

Bun integra varias herramientas que normalmente requerirían configuraciones separadas: viene con un gestor de paquetes, bundler, transpiler, motor de pruebas y soporte para TypeScript de forma nativa. Por eso mismo puede ejecutar una app de React sin instalaciones ni dependencias extra3.

La filosofía de Bun es reducir la fricción: iniciar más rápido, consumir menos recursos y facilitar al desarrollador tener todo en uno. Si bien Bun todavía está evolucionando y afinando compatibilidad con todos los paquetes de Node, ya ha generado mucha expectativa en la comunidad por sus capacidades y sus números de rendimiento.

Entornos de ejecución especializados

Además de Deno y Bun, existen entornos de ejecución orientados a escenarios específicos.

En edge computing y funciones serverless de nueva generación, por ejemplo, se usan aislamientos de V8 en lugar de procesos tradicionales de Node.js. Plataformas como Cloudflare Workers permiten ejecutar código JavaScript en instancias aisladas de manera casi instantánea. Esto posibilita tener miles de funciones concurrentes por servidor y reducir drásticamente el tiempo de arranque.

En el mundo del IoT y los dispositivos embebidos, también existen motores JavaScript minimalistas como JerryScript4, diseñado para funcionar en microcontroladores con muy poca memoria. Estos motores sacrifican algunas características avanzadas, pero permiten correr scripts JavaScript en hardware muy limitado.

Lo interesante es que JavaScript ya no depende de un único modelo de ejecución. La necesidad de iniciar más rápido, consumir menos recursos y adaptarse a distintos entornos ha dado lugar a entornos de ejecución con prioridades muy diferentes: servidores, herramientas de desarrollo, funciones en la nube, dispositivos embebidos y ejecución en el borde de la red.

Todos estos entornos coexisten hoy y muestran cómo JavaScript sigue expandiéndose sin quedarse atado al navegador ni al modelo clásico de Node.js.

Aplicaciones más allá del navegador

Tras la revolución de Node.js, JavaScript continuó extendiéndose más allá del navegador, llegando al desarrollo de aplicaciones móviles y de escritorio multiplataforma.

Esto ha revolucionado la forma de crear productos de software, permitiendo construir apps nativas y de escritorio usando solo conocimientos de JavaScript y compartiendo parte del código entre plataformas.

En plataformas móviles

En 2009 surgieron soluciones híbridas como PhoneGap, que permitían “escribir una vez, ejecutar en cualquier lugar” usando HTML, CSS y JavaScript para crear apps móviles multiplataforma. Básicamente, PhoneGap empaquetaba una aplicación web dentro de un contenedor nativo y exponía APIs en JavaScript para acceder a funcionalidades del dispositivo, como la cámara o los sensores.

El enfoque fue revolucionario, pero venía con limitaciones de rendimiento y UX: las apps eran realmente WebViews, no interfaces nativas, lo que a veces se traducía en menor fluidez.

En 2015, Facebook presentó React Native. A diferencia de PhoneGap, aunque los desarrolladores escriben la lógica en JavaScript, la interfaz se renderiza usando vistas nativas en cada plataforma. Esto significa que la app resultante usa componentes reales de iOS y Android, logrando una apariencia y rendimiento más cercanos a los de una app nativa pura.

Muchas otras opciones siguieron apareciendo, como Ionic, NativeScript y las Progressive Web Apps, que llevan experiencias web al móvil directamente.

En el escritorio

JavaScript también conquistó terreno mediante frameworks como Electron, lanzado en 2013 por GitHub.

Electron permite construir aplicaciones de escritorio multiplataforma para Windows, macOS y Linux usando tecnologías web, con Chromium para la interfaz y Node.js para el acceso al sistema. En la práctica, Electron habilita que una aplicación web se distribuya como aplicación de escritorio, ofreciendo una experiencia cercana a la nativa, pero construida con tecnologías web.

Este enfoque ha tenido un impacto enorme en la industria. Muchas aplicaciones de nuestro día a día han sido construidas con Electron: Visual Studio Code, Slack, Discord, WhatsApp Desktop, Notion, Figma y Descript. Algunas han migrado, o podrían migrar en el futuro, a otras tecnologías, pero sigue siendo sorprendente ver hasta dónde se ha usado JavaScript en aplicaciones de escritorio y en productos que compiten con apps nativas. Es el caso de Figma, para diseño, o Descript, para edición de video: cosas que antes parecían impensables fuera del entorno nativo.

El futuro del ecosistema

JavaScript nos ha demostrado una y otra vez su versatilidad, quizá porque nació junto con la web, como mencionamos en la Historia y evolución de JavaScript.

La web ayudó a posicionarlo, pero JavaScript también tuvo una ventaja particular: avanzó lentamente. Como un caracol. Esa lentitud, sumada a su adopción masiva, permitió que el lenguaje incorporara lecciones aprendidas de otros ecosistemas sin desaparecer en el intento.

Si JavaScript ya llegó a tantos rincones, entonces, ¿qué más le falta? Mi predicción es que en muy poco tiempo también será un lenguaje importante en el desarrollo de aplicaciones de Inteligencia Artificial. La comunidad ya ha empezado a notar que muchas características naturales de JavaScript, Node.js y la web como los Streams, las APIs asíncronas y la ejecución orientada a eventos, encajan muy bien con este nuevo escenario.

Si la Inteligencia Artificial sigue conviviendo mayormente con productos web, JavaScript podría ganar un lugar mucho más relevante en el ecosistema de la inteligencia artificial.

Footnotes

  1. Deno is Node-compatible — https://docs.deno.com/runtime/fundamentals/node/

  2. Zig Language — https://ziglang.org/

  3. Build a React App with Bun — https://bun.com/docs/guides/ecosystem/react

  4. JerryScript — https://jerryscript.net

Únete a nuestra comunidad de Discord

Somos más de 300 personas cambiando el mundo de la programación

Unirse a discord