← Volver al blog

BroadcastChannel vs window.open: cómo comunicar ventanas en el navegador

·5 min de lectura

Comunicar dos pestañas o ventanas del navegador que están bajo el mismo dominio suena a tarea sencilla. Pero en la práctica hay dos APIs que compiten para resolverlo, cada una con fortalezas y casos de uso distintos: BroadcastChannel y window.open + postMessage.

La pregunta no es cuál es mejor, sino cuál necesitas según lo que quieras hacer.

BroadcastChannel: el bus de mensajes del navegador

BroadcastChannel es una API relativamente moderna (2016, pero bien soportada desde 2020) que permite a cualquier contexto de navegación —pestañas, iframes, workers— del mismo origen comunicarse a través de un canal nombre.

// Canal compartido
const canal = new BroadcastChannel('notificaciones')

// Escuchar
canal.onmessage = (e) => console.log('Recibido:', e.data)

// Emitir (cualquier pestaña conectada al mismo canal lo recibe)
canal.postMessage('¡Hola a todas las pestañas!')

Características clave:

  • Multidireccional. Un mensaje lo reciben todas las pestañas conectadas al canal. No hay emisor/receptor fijo.
  • Sin relación jerárquica. No importa quién abrió a quién. Cualquier pestaña puede unirse al canal.
  • Mismo origen obligatorio. No funciona entre dominios distintos.
  • Lifecycle automático. El canal se limpia solo cuando todas las pestañas se cierran.
  • API mínima. Dos métodos (postMessage, close) y un evento (onmessage).

Cuándo usarlo

  • Sincronizar estado entre pestañas (preferencias de tema, carrito de compra, sesión).
  • Chats o notificaciones en tiempo real sin servidor.
  • Cualquier patrón "publicar/suscribir" dentro del mismo origen.

Demo interactiva

Abre esta página en dos pestañas y envía mensajes entre ellas:

window.open + postMessage: control 1:1 con relación jerárquica

window.open devuelve una referencia a la ventana hija, y con postMessage puedes enviarle mensajes. La hija responde usando window.opener.postMessage().

// Ventana padre
const hija = window.open('detalle.html', 'detalle', 'width=600,height=400')

// Enviar a la hija
hija.postMessage({ productoId: 42 }, 'https://midominio.com')

// Escuchar respuesta
window.addEventListener('message', (e) => {
  if (e.origin !== 'https://midominio.com') return
  console.log('Hija responde:', e.data)
})
// Ventana hija (detalle.html)
window.addEventListener('message', (e) => {
  if (e.origin !== 'https://midominio.com') return
  cargarProducto(e.data.productoId)
})

// Responder al padre
window.opener.postMessage({ tipo: 'comprado' }, 'https://midominio.com')

Características clave:

  • Unidireccional por conexión. Una ventana habla con otra específica. Para llegar a N ventanas necesitas N referencias.
  • Relación jerárquica. Quien abre tiene el control (puede cerrar la hija, reposicionarla, etc.).
  • Soporta cross-origin. Usando targetOrigin puedes comunicar ventanas de distintos dominios de forma segura.
  • Requiere gestión manual. Ventanas huérfanas, referencias rotas, limpieza de event listeners.

Cuándo usarlo

  • Diálogos o ventanas modales abiertas desde la app (editor de imágenes, asistente de pago).
  • Comunicación con iframes o ventanas de terceros (con targetOrigin restringido).
  • Flujos donde la ventana padre necesita controlar el ciclo de vida de la hija.

Demo interactiva

La ventana padre abre una hija. La comunicación es 1:1 y el padre puede cerrar la hija:

Comparativa rápida

CaracterísticaBroadcastChannelwindow.open + postMessage
ÁmbitoMismo origenCualquier origen (con targetOrigin seguro)
DirecciónMultidireccional (broadcast)1:1 (punto a punto)
Relación entre ventanasPlana (canal)Jerárquica (padre-hija)
Control de ventanaNoSí (cerrar, enfocar, mover)
ComplejidadBajaMedia
Soporte navegadores~95%~100%
Ideal paraSincronizar estado entre pestañasDiálogos y flujo controlado

Comparativa lado a lado

Ambas APIs funcionando simultáneamente en la misma página:

Conclusión

No elijas una API porque sea "más moderna". BroadcastChannel es perfecto cuando necesitas que varias pestañas del mismo origen se enteren de algo sin importar quién lo emitió. window.open + postMessage es mejor cuando necesitas controlar una ventana hija, trabajar con orígenes distintos, o mantener una relación 1:1 clara.

Úsalas juntas cuando tenga sentido. No son excluyentes.

Índice de demos

Referencias