Pasa pestañas, archivos y texto entre navegadores de la misma red (LAN o Tailscale) con un PIN. Sin nube y sin cuentas: todo viaja por tu propia red y el relay solo reenvía entre los navegadores conectados al mismo PIN. No guarda nada.
Una sola extensión y un solo relay para pasar lo que necesites entre tus PCs (o el de un colega) en clase, en casa o donde sea.
| 🗂️ Pestañas | Envía la pestaña actual a otro PC: botón, clic derecho, atajo Ctrl+Shift+U o arrastrando la pestaña fuera de la ventana. |
| 📎 Archivos | Arrastra y suelta. Se trocean y viajan por la red; en el otro PC salta una ventanita para guardarlos. |
| ⌨️ Texto | Pega un enlace o un código y aparece al instante en el otro PC. |
| 🔢 Salas por PIN | Quien ponga el mismo PIN, se ve (2–8 navegadores por sala). |
| 📥 Siempre escuchando | Un offscreen document mantiene la conexión aunque cierres la pestaña de la app. |
| 🔌 Relay propio | Corre en cualquiera de los PCs (Node + ws). |
Navegador A relay (Node) Navegador B
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ app.html │ │ por PIN │ │ app.html │
│ (panel) │ │ ┌─────────┐ │ │ (panel) │
│ │ │ WebSocket │ │ sala A │ │ WebSocket │ │ │
│ offscreen ◄──┼──────────────────┼──┤ 2 peers ├──┼─────────────────┼──► offscreen │
│ (socket) │ │ └─────────┘ │ │ (socket) │
└───────────────┘ └───────────────┘ └───────────────┘
▲ IndexedDB (blobs) ▲
-
El relay (
server.js) es un hub por PIN: cada cliente que se conecta manda unhellocon su PIN y su nombre, y entra en una sala. Todo lo que envía un miembro se reenvía al resto de la sala. Lleva la cuenta de salas y navegadores (máx. 8 por sala). -
La extensión (Chrome/Edge MV3) tiene tres piezas:
background.js— el service worker: orquesta todo (avisos, ventanita de archivo recibido, envío de pestañas, menú contextual y atajo).offscreen.html/js— un documento offscreen que es el único que mantiene el WebSocket abierto, para poder recibir aunque cierres la pestaña de la app.app.html/js+popup+received— la interfaz.
-
Cómo se pasan los archivos (lo interesante):
- El panel guarda el archivo en IndexedDB (mismo origen
chrome-extension://) y le pasa al offscreen solo la clave, no el binario (los mensajes entre páginas son JSON). - El offscreen lee el
Blob, lo parte en trozos de 256 KB y manda cada trozo como trama binaria:[4 bytes = id de transferencia (uint32 big-endian)] + trozo. - Controla el backpressure con
ws.bufferedAmount(pausa si se acumula, reanuda al bajar). - El receptor reensambla los trozos, guarda el
Bloben IndexedDB y abre la ventanita.
- El panel guarda el archivo en IndexedDB (mismo origen
-
Mensajes de control (JSON):
hello/joined/room,file-meta,file-end,file-cancel,text,tab. El binario va aparte (tramas). Hayping/pongpara mantener vivo el socket.
TABtools/
├─ server.js # relay (hub por PIN) — puerto 8790
├─ test-relay.js # test e2e: 2 clientes, A envía binario y B lo reensambla
├─ extension/ # extensión Chrome/Edge (MV3)
│ ├─ manifest.json
│ ├─ background.js # service worker
│ ├─ offscreen.js/.html # WebSocket persistente (recibir)
│ ├─ app.html/.css/.js # panel de control
│ ├─ popup.html/.css/.js
│ ├─ received.html/.js/.css
│ └─ db.js # helpers de IndexedDB
└─ relay-standalone/ # el relay listo para correr en cualquier PC (start.sh / start.bat)
- Node.js 18+ (para el relay)
- Chrome o Edge con extensiones en modo desarrollador
npm install
npm start # node server.js → puerto 8790
# otro puerto:
TABTOOLS_PORT=9000 npm start- Panel:
http://localhost:8790/ - Estado:
http://localhost:8790/health
¿Lo quieres en otro PC? Usa relay-standalone/ (trae start.sh / start.bat).
- Chrome/Edge →
chrome://extensions→ activa Modo desarrollador. - Cargar descomprimida → selecciona la carpeta
extension/. - Abre la extensión → Abrir TABtools.
- Arranca el relay en uno de los PCs.
- En cada PC: abre el panel, pon el mismo PIN y la URL del relay
(p. ej.
ws://192.168.1.100:8790), y pulsa Conectar. - Cuando el estado diga Conectado, ya podéis:
- Pestañas: botón Enviar pestaña actual, clic derecho sobre una pestaña/enlace, atajo Ctrl+Shift+U, o arrastra una pestaña fuera de la ventana.
- Archivos: arrástralos al recuadro. En el otro PC salta la ventanita para guardar.
- Texto: pégalo y pulsa Enviar.
- Nada sale a internet: todo va por tu LAN o Tailscale.
- El relay no escribe a disco; solo reenvía entre conexiones vivas.
- Sin cuentas, sin telemetría, sin base de datos.
- Envío dirigido a un navegador concreto desde la interfaz (el protocolo ya lo soporta:
to). - Versión P2P por WebRTC (sin relay).
- Historial de transferencias por sesión.
MIT © 2026 Francesc Leon Chamizo