El live reload convierte el lento ciclo de build, sync y run en solo guardar y mirar. En Mac, el flag de Capacitor CLI --live-reload funciona casi siempre. En Windows y Linux el mismo flag también funciona, pero los firewalls, la red del emulador y el ruteo USB causan la mayoría de los reportes de "no recarga". Esta guía cubre cada caso.
Cómo funciona el live reload en Capacitor
La app nativa normalmente carga dist/ desde el interior del APK. Con server.url configurado, la WebView carga desde una URL, que es tu servidor de dev de Vite o de tu framework. El hot module replacement funciona igual que en un navegador de escritorio. Nada nativo cambia; solo cambia el origen de la página.
Dos consecuencias:
- El dispositivo necesita acceso de red a tu ordenador.
- Simple
http://necesitacleartext: true, porque Android bloquea el tráfico cleartext por defecto.
Opción A: el flag CLI
El Capacitor CLI puede configurar esto para una ejecución:
bun run dev -- --host 0.0.0.0 &
bunx cap run android --live-reload --host 192.168.1.20 --port 5173
Reemplaza el host con la IP LAN de tu ordenador. El CLI escribe una config temporal, lanza la app y restaura la config después. Si tu dev server usa un puerto distinto, pásalo.
Este es el camino más rápido. El resto de esta guía usa la configuración explícita, que es más fácil de depurar y funciona con el dev server de cualquier framework.
Opción B: configuración explícita
Inicia el dev server vinculado a todas las interfaces:
# Vite
bun run dev -- --host 0.0.0.0
# Angular
bunx ng serve --host 0.0.0.0
# Next.js
bun run dev -- -H 0.0.0.0
Luego crea una configuración Capacitor solo para dev. Capacitor lee capacitor.config.ts, así que activa una variable de entorno:
import type { CapacitorConfig } from '@capacitor/cli';
const liveReloadUrl = process.env.CAP_LIVE_RELOAD_URL;
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'dist',
...(liveReloadUrl
? { server: { url: liveReloadUrl, cleartext: true } }
: {}),
};
export default config;
Ejecuta con la variable configurada:
CAP_LIVE_RELOAD_URL=http://10.0.2.2:5173 bunx cap sync android
bunx cap run android
En Windows PowerShell:
$env:CAP_LIVE_RELOAD_URL="http://10.0.2.2:5173"; bunx cap sync android
bunx cap run android
Sin la variable, cap sync escribe una configuración normal y los builds de release son seguros.
Emulador: usa 10.0.2.2
Dentro del emulador de Android, 10.0.2.2 es tu computadora. Funciona en Windows y Linux sin cambiar el firewall, ya que el tráfico no sale de la máquina. Si falla, confirma que el dev server esté vinculado a 0.0.0.0 y no solo eso, 127.0.0.1; un servidor en loopback no es accesible desde la red virtual del emulador.
Teléfono por USB: adb reverse
La opción más limpia para un dispositivo físico, sin necesidad de Wi-Fi ni reglas de firewall:
adb reverse tcp:5173 tcp:5173
Ahora localhost:5173 en el teléfono apunta a tu ordenador. Configura la URL de esta forma:
CAP_LIVE_RELOAD_URL=http://localhost:5173 bunx cap sync android
adb reverse se borra al reconectar el dispositivo, así que ejecútalo de nuevo tras desconectarlo. CLI puede hacerlo por ti: bunx cap run android --live-reload --host localhost --port 5173 --forwardPorts 5173:5173. Los usuarios de Linux necesitan la regla udev de la guía de configuración de Linux antes adb detecta el teléfono.
Teléfono por Wi-Fi: IP de LAN y firewall
Si el USB no es una opción, usa la IP de la LAN de tu equipo y abre el puerto.
Busca la IP:
# Linux
ip -4 addr show | grep inet
# Windows
ipconfig
Abre el puerto en Windows. Desde un PowerShell con permisos de administrador:
netsh advfirewall firewall add rule name="Vite dev server" dir=in action=allow protocol=TCP localport=5173
Los perfiles de red pública en Windows bloquean conexiones entrantes incluso con una regla en entornos corporativos; cambia la red Wi-Fi a Privada en Settings si el móvil sigue sin conectar.
En Linux con ufw:
sudo ufw allow 5173/tcp
En Fedora con firewalld:
sudo firewall-cmd --add-port=5173/tcp
Luego:
CAP_LIVE_RELOAD_URL=http://192.168.1.20:5173 bunx cap sync android
bunx cap run android
Ambos dispositivos deben estar en la misma subred. Las redes Wi-Fi de invitados suelen aislar a los clientes, lo que parece exactamente un problema de firewall.
Detalles de WSL2
Cuando Vite se ejecuta en WSL2, el host de Windows no expone el puerto automáticamente. Activa el mirrored networking en .wslconfig o añade un port proxy en Windows. Los detalles están en la guía de WSL2.
Problemas con el websocket de HMR
¿La página carga pero los cambios no se aplican? El websocket de HMR intenta conectar con el host incorrecto. Indica a Vite la dirección pública:
// vite.config.ts
export default defineConfig({
server: {
host: '0.0.0.0',
hmr: {
host: '192.168.1.20', // or 10.0.2.2 for the emulator
port: 5173,
},
},
});
Angular y Next.js tienen opciones equivalentes; el síntoma es el mismo y la solución es fijar el host del websocket.
Depuración con Chrome DevTools
Abrir chrome://inspect en Chrome o Edge en tu ordenador. El WebView aparece bajo el dispositivo con la URL del dev server. Tendrás console, network, sources y breakpoints, tanto en Windows como en Linux. Si el dispositivo no aparece, comprueba adb devices y que la depuración USB esté aceptada.
Nunca despliegues la config de dev
Un release build con server.url configurado intenta cargar desde una máquina inexistente y la app muestra una pantalla en blanco. Evítalo:
- Usa el patrón de variables de entorno anterior para que la config por defecto no tenga
serverbloqueos. - Añade un check de CI que falle si el build
android/app/src/main/assets/capacitor.config.jsoncontiene"url". - Si también usas Live Updates de Capgo, ten en cuenta que una
server.urlconfig sobrescribe el bundle del updater; mantén ambos workflows separados.
Resumen
El Live reload en Android funciona desde Windows y Linux con tres detalles clave: vincula el dev server a todas las interfaces, elige la dirección que el dispositivo pueda alcanzar (10.0.2.2 para el emulador, adb reverse para USB, la IP de la LAN con una regla de firewall para Wi-Fi), y mantén la dev config fuera de los release builds. Una vez que el ciclo de iteración es rápido en Android, la capa web compartida ya está probada antes de llegar a iOS mediante Build de Capgo.