Back

Reactividad sin un Framework: Lo que JavaScript Nativo Puede Hacer Hoy

Reactividad sin un Framework: Lo que JavaScript Nativo Puede Hacer Hoy

Quieres comportamiento reactivo en la interfaz de usuario—cambios de estado que actualicen automáticamente el DOM—pero no quieres enviar 40KB de código de framework para un widget simple. Buenas noticias: la reactividad con JavaScript vanilla es completamente alcanzable con APIs que han sido estables en los navegadores durante años.

Este artículo cubre las herramientas nativas disponibles a finales de 2025 para construir interfaces reactivas: estado reactivo basado en Proxy, EventTarget y CustomEvent para pub/sub, y observadores del navegador para reacciones conscientes del DOM. Aprenderás qué funciona hoy, qué está por venir y dónde estos patrones se relacionan con los internos de los frameworks.

Puntos Clave

  • Los objetos Proxy interceptan cambios de propiedades y permiten actualizaciones automáticas del DOM sin dependencias de frameworks
  • EventTarget y CustomEvent proporcionan una capa nativa de pub/sub para comunicación desacoplada entre componentes
  • Los observadores del navegador (MutationObserver, IntersectionObserver, ResizeObserver) manejan la reactividad del DOM y del layout
  • La propuesta TC39 Signals podría estandarizar primitivas de reactividad, pero los patrones actuales de Proxy + EventTarget logran resultados similares hoy

Qué Significa Realmente la Reactividad

La reactividad es un bucle simple: los cambios de estado desencadenan actualizaciones de la interfaz. Los frameworks automatizan esto con DOMs virtuales, compiladores o seguimiento de dependencias de grano fino. Pero la mecánica subyacente se basa en características de JavaScript que puedes usar directamente.

El patrón central:

  1. Almacenar el estado en una estructura rastreable
  2. Notificar a los suscriptores cuando el estado cambia
  3. Actualizar solo el DOM relevante

Las APIs nativas del navegador manejan cada paso sin dependencias externas.

Estado Reactivo Basado en Proxy

El objeto Proxy intercepta el acceso y la asignación de propiedades. Combinado con Reflect, forma la base del estado reactivo basado en proxy.

function createReactiveStore(initial, onChange) {
  return new Proxy(initial, {
    set(target, prop, value) {
      const result = Reflect.set(target, prop, value)
      onChange(prop, value)
      return result
    }
  })
}

const state = createReactiveStore({ count: 0 }, (prop, value) => {
  document.getElementById('count').textContent = value
})

state.count = 5 // El DOM se actualiza automáticamente

Este patrón se siente como “signals”—escribes en el estado y los efectos se ejecutan. El sistema de reactividad de Vue 3 usa Proxy internamente exactamente por esta razón.

Limitación: Las trampas de Proxy se activan solo en mutaciones aplicadas al objeto proxy en sí. Si los objetos anidados o arrays no están también envueltos en sus propios proxies, los cambios dentro de ellos (como array.push()) no serán rastreados. Muchos desarrolladores usan actualizaciones inmutables (por ejemplo, state.items = [...state.items, newItem]) para garantizar que las actualizaciones se activen.

EventTarget y CustomEvent como Capa de Pub/Sub

Para la comunicación desacoplada entre componentes, EventTarget proporciona un mecanismo nativo de pub/sub. Cualquier objeto puede convertirse en un emisor de eventos.

const bus = new EventTarget()

// Suscribirse
bus.addEventListener('state-change', (e) => {
  console.log('Nuevo valor:', e.detail)
})

// Publicar
bus.dispatchEvent(new CustomEvent('state-change', { 
  detail: { count: 10 } 
}))

Este patrón impulsa la interfaz reactiva con APIs nativas del navegador. Los componentes se suscriben a eventos, reaccionan a cambios y permanecen desacoplados. A diferencia de implementaciones personalizadas de pub/sub, EventTarget se integra con las DevTools del navegador y sigue la semántica estándar de eventos.

Observadores del Navegador para Reactividad del DOM

Cuando necesitas reaccionar a cambios del DOM o del layout—no solo del estado—los observadores del navegador llenan ese vacío.

MutationObserver observa modificaciones del DOM:

const observer = new MutationObserver((mutations) => {
  mutations.forEach(m => console.log('DOM cambió:', m))
})
observer.observe(document.body, { childList: true, subtree: true })

IntersectionObserver rastrea la visibilidad de elementos—útil para lazy loading o analíticas.

ResizeObserver responde a cambios de tamaño de elementos sin hacer polling.

Estas APIs han sido estables durante mucho tiempo y son seguras para producción. Complementan la reactividad basada en estado al manejar casos donde factores externos modifican el DOM.

La Propuesta TC39 Signals: Lo que Viene

Hay un interés creciente en estandarizar primitivas de reactividad. La propuesta TC39 Signals tiene como objetivo definir un modelo común que los frameworks puedan compartir.

Importante: A partir de 2025, esto sigue siendo una propuesta—no una característica implementada en JavaScript. Frameworks como Solid, Angular y Preact han adoptado patrones similares a signals, influyendo en el diseño de la propuesta. Pero no puedes usar “signals nativos” en los navegadores hoy.

Los patrones de Proxy + EventTarget anteriores logran objetivos similares. Si los signals se estandarizan, la migración debería ser sencilla ya que el modelo mental está alineado.

Elegir el Patrón Correcto

PatrónMejor ParaCompromiso
ProxyEstado local del componenteSolo rastrea cambios en el objeto proxy a menos que los valores anidados también estén proxificados
EventTargetMensajería entre componentesCableado manual
MutationObserverReaccionar a cambios externos del DOMSobrecarga de rendimiento

Para aplicaciones pequeñas y widgets, combinar estado basado en Proxy con EventTarget cubre la mayoría de las necesidades de interfaz reactiva sin la sobrecarga de un framework.

Conclusión

La reactividad sin un framework es práctica hoy. Proxy maneja el seguimiento del estado, EventTarget proporciona pub/sub, y los observadores del navegador reaccionan a cambios del DOM. Estas APIs son estables, están bien documentadas y se componen en un núcleo reactivo ligero.

No necesitas un framework para obtener reactividad de grano fino. Necesitas entender las primitivas sobre las que se construyen los frameworks—y ahora las conoces.

Preguntas Frecuentes

Las trampas de Proxy solo se activan en la asignación directa de propiedades al objeto proxy. Para objetos anidados, necesitas envolver recursivamente cada objeto anidado en su propio Proxy, o reemplazar toda la estructura anidada al hacer cambios. La mayoría de los desarrolladores optan por patrones de actualización inmutables como el spread para crear nuevas referencias.

EventTarget es una API nativa del navegador que se integra con las DevTools y sigue la semántica estándar de dispatch. El bubbling y capturing completos solo se aplican cuando el objetivo del evento es parte del árbol DOM. Las bibliotecas personalizadas pueden ofrecer características adicionales como listeners con comodines o suscripciones de una sola vez, pero EventTarget no requiere dependencias y funciona consistentemente en todos los navegadores modernos.

Usa MutationObserver cuando necesites reaccionar a cambios del DOM realizados por código externo, scripts de terceros o extensiones del navegador. Proxy rastrea cambios de estado de JavaScript que tú controlas. MutationObserver observa el árbol DOM real independientemente de qué causó el cambio. Sirven propósitos diferentes y a menudo trabajan juntos.

La propuesta Signals tiene como objetivo estandarizar primitivas de reactividad que los frameworks puedan compartir, no reemplazar las APIs existentes. Proxy y EventTarget seguirán siendo enfoques válidos. Si Signals se implementa, probablemente complementarán estos patrones al proporcionar una interfaz estándar para el seguimiento de dependencias de grano fino entre diferentes bibliotecas.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay