WSL2 ofrece a los desarrolladores de Windows un shell de Linux real, algo vital cuando los scripts, Dockerfiles y CI de tu equipo asumen bash. Para Capacitor funciona de maravilla con una regla: mantén el toolchain web en WSL2 y el emulador de Android, dispositivos USB y Android Studio en Windows. Luego, conéctalos mediante adb.
Esta guía muestra esa configuración, los detalles de red que suelen confundir y cómo encaja iOS a través de Build de Capgo.
Cuándo vale la pena usar WSL2
Usa WSL2 cuando:
- Tu repo tenga scripts de bash, Makefiles o hooks de Husky que fallen en PowerShell.
- Ejecutes las mismas imágenes de Docker localmente y en tu CI.
- Quieras el layout de Linux
node_modulespara que los lockfiles coincidan con tu CI de Linux.
Evita WSL2 si solo necesitas Android Studio y una terminal. La guía para Windows nativo es más sencilla en ese caso.
1) Instala WSL2 y una distribución
Desde PowerShell como administrador:
wsl --install -d Ubuntu
Reinicia, abre Ubuntu y crea tu usuario de Linux. Actualiza e instala lo básico:
sudo apt update && sudo apt install -y build-essential unzip openjdk-21-jdk
curl -fsSL https://bun.sh/install | bash
2) Mantén el proyecto en el sistema de archivos de Linux
Crea tus proyectos dentro de tu home de Linux, no en /mnt/c:
mkdir -p ~/dev && cd ~/dev
bun create vite@latest my-app
cd my-app
bun install
Accede a los archivos desde herramientas de Windows mediante \\wsl$\Ubuntu\home\you\dev\my-app. VS Code con la extensión WSL lo abre directamente con code ..
Por qué es importante: el acceso entre sistemas de archivos mediante /mnt/c es lento para los miles de archivos pequeños en node_modules, y los inotify watchers que usa Vite no funcionan de forma fiable para archivos en la unidad de Windows.
3) Decide dónde reside el SDK de Android
Dos layouts viables:
Layout A (recomendado): SDK en Windows, Gradle en WSL2 apuntando a una copia SDK en Linux. Instala Android Studio en Windows para el emulador y las herramientas GUI, e instala un SDK de línea de comandos aparte en WSL2 para Gradle:
mkdir -p ~/Android/Sdk/cmdline-tools && cd ~/Android/Sdk/cmdline-tools
# download commandlinetools-linux-*.zip from the Android developer site
unzip commandlinetools-linux-*.zip && mv cmdline-tools latest
echo 'export ANDROID_HOME=$HOME/Android/Sdk' >> ~/.bashrc
echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools' >> ~/.bashrc
source ~/.bashrc
sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0"
sdkmanager --licenses
Sí, duplica unos cientos de megabytes. A cambio, Gradle corre a velocidad de Linux y nunca toca /mnt/c.
Layout B: todo en Windows, WSL2 solo para el build web. Ejecutas bun run build en WSL2 y cap sync además de gradlew desde PowerShell sobre los mismos archivos mediante \\wsl$. Funciona, pero es más lento y mezcla dos shells. Elígelo solo si no puedes instalar nada en WSL2.
El resto de esta guía asume el Layout A.
4) Bridge de adb entre WSL2 y Windows
El emulador y los teléfonos USB están conectados a Windows. El build de Gradle en WSL2 y cap run android necesitan alcanzarlos. Mantén un único servidor adb en Windows y deja que WSL2 sea el cliente.
En Windows, inicia el servidor adb escuchando en todas las interfaces. Usa el adb desde el SDK de Windows:
adb kill-server
adb -a -P 5037 nodaemon server
Mantén esa ventana abierta. Si se solicita, permite el puerto 5037 en el firewall de Windows para el adaptador virtual de WSL.
En WSL2, apunta el cliente adb al host de Windows:
export WSL_HOST=$(ip route show default | awk '{print $3}')
export ADB_SERVER_SOCKET=tcp:$WSL_HOST:5037
adb devices
El emulador o tu teléfono ya aparecen en WSL2. Ambos binarios de adb deben tener la misma versión principal, así que actualiza platform-tools en ambos lados al mismo tiempo.
El modo mirrored de red simplifica esto
En Windows 11 22H2 o superior, activa el modo mirrored de red para que WSL2 comparta el stack de red de Windows. Crea o edita %USERPROFILE%\.wslconfig:
[wsl2]
networkingMode=mirrored
Ejecuta wsl --shutdown, vuelve a abrir Ubuntu y luego usa ADB_SERVER_SOCKET=tcp:127.0.0.1:5037. La IP del host ya no cambia en cada reinicio, y el live reload también se simplifica.
Alternativa: pasa el dispositivo USB a WSL2
Si quieres usar adb totalmente dentro de WSL2 con un teléfono físico, usa usbipd-win:
winget install usbipd
usbipd list
usbipd bind --busid 2-3
usbipd attach --wsl --busid 2-3
Luego añade la regla udev desde el Guía de Linux dentro de WSL2. Esto no ayuda con el emulador, que requiere una conexión de red.
5) Ejecuta la app
Con adb en bridge, Capacitor funciona como en Linux:
bun add @capacitor/core @capacitor/android @capacitor/ios
bun add -d @capacitor/cli
bunx cap init
bun run build
bunx cap add android
bunx cap add ios
bunx cap run android
cap open android requiere Android Studio en la misma máquina. En su lugar, abre la android/ carpeta en Windows Android Studio mediante \\wsl$\Ubuntu\home\you\dev\my-app\android. El Gradle incluido en Studio compila en Windows mientras tu terminal compila en WSL2; ambos comparten los mismos archivos fuente.
6) Live reload entre entornos
Vite corre en WSL2, la app corre en un emulador de Windows o en un teléfono. El emulador debe alcanzar el dev server.
Inicia Vite vinculado a todas las interfaces:
bun run dev -- --host 0.0.0.0
Apunta Capacitor hacia él en capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'dist',
server: {
url: 'http://10.0.2.2:5173',
cleartext: true,
},
};
10.0.2.2 es el alias del emulador para la máquina host. Con mirrored networking, el puerto de WSL2 es visible en el host de Windows, así que esta dirección llega a Vite. Sin mirrored networking, primero haz un port forward en Windows:
netsh interface portproxy add v4tov4 listenport=5173 listenaddress=0.0.0.0 connectport=5173 connectaddress=$(wsl hostname -I)
Para un móvil por USB, cambia la URL por tu IP de la LAN de Windows y permite el puerto 5173 en el firewall de Windows. Ejecuta bunx cap sync android tras cambiar la config, y elimina el server block antes de generar el release.
7) iOS desde WSL2 con Capgo Build
Xcode requiere macOS, así que WSL2 gestiona todo hasta la compilación nativa y Capgo hace el resto:
bun run build
bunx cap sync ios
bunx @capgo/cli@latest login
bunx @capgo/cli@latest build init --platform ios
bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release
CLI sube el preparado ios/ proyecto y transmite los logs a tu terminal de WSL2. El signing se crea sin un Mac, con OpenSSL o el generador de certificados iOS. Los detalles completos están en Crea una app de iOS desde Linux con Capacitor y Capgo Build, lo cual aplica igual a WSL2.
8) Evita los native builds para cambios diarios
Una vez que ambas apps estén en las tiendas, Live Updates de Capgo envía cambios web desde WSL2 sin tocar Gradle ni el Capgo Build:
bunx @capgo/cli@latest bundle upload --channel production
Problemas comunes de WSL2
adb: device offlineo una lista vacía en WSL2: el servidor adb de Windows no se está ejecutando con-a, o las versiones difieren. Reinícialo y comparaadb versionen ambos lados.- La IP del host cambió tras reiniciar: es normal sin mirrored networking. Pon el
WSL_HOSTexport en~/.bashrcpara que se recalcule, o usa el modo mirrored. - Vite no detecta cambios en los archivos: el proyecto está en
/mnt/c. Muévelo al home de Linux. - Gradle es extremadamente lento: misma causa, o el caché de Gradle está en
/mnt/c. Mantén~/.gradleen WSL2. - El desfase del reloj rompe la autenticación de API durante
build init: WSL2 clocks drift after sleep. Runsudo hwclock -sand retry. cap open androidfalla: Studio está en Windows. Abre la carpeta desde Studio.
Resumen
WSL2 es el entorno ideal para el toolchain web de Capacitor si tu equipo trabaja en bash. Mantén el emulador y los dispositivos en Windows, conéctalos mediante un servidor adb, gestiona los archivos en el sistema de Linux y deja que Capgo Build se encargue de la compilación de iOS. El resultado es un flujo de trabajo Linux en un portátil Windows que permite publicar en ambas tiendas.