DEV Community

Cover image for 2 GB de RAM y nada de laptop: cómo se ve de verdad desarrollar en iPad en 2026
Franchesco Romero for AWS Community Builders

Posted on Edited on

2 GB de RAM y nada de laptop: cómo se ve de verdad desarrollar en iPad en 2026

Qué cambió en 2026

Cuatro cosas, y ninguna es la tableta.

  • Los CLI agénticos se volvieron remotos primero. Claude Code registra una sesión desde un host tuyo y la abres en una pestaña del navegador. Lo que hace el trabajo nunca fue el editor, así que el editor dejó de necesitar ser local.
  • Los túneles de VS Code movieron el extension host a la máquina remota. Sobre un túnel, una pestaña del navegador recibe el set completo de extensiones de escritorio. Sobre SFTP recibe nada más el subconjunto de web extensions. La misma barra de direcciones, otro producto.
  • Las VPN de malla hicieron alcanzable una caja de solo egreso. Sin regla de entrada, sin bastión, y aun así una sesión de SSH, porque la caja marcó hacia afuera primero.
  • La capacidad spot chica de ARM se volvió lo bastante accesible para sostener el trabajo pesado. Así que la caja siempre encendida se queda chica a propósito.

La pregunta dejó de ser "¿puedo desarrollar en un iPad?". Ahora es "¿puedo reparar la máquina donde está mi agente, desde aquí?".

Qué necesitas

Cosa Por qué Costo
Magic Keyboard Folio, o un Logitech Combo Touch El trackpad es el requisito. Una terminal sin teclado físico es una demostración Unos 250 USD de lista, más económico de terceros
Blink Shell La terminal. Trae mosh, guarda las llaves en el Secure Enclave, tiene un comando code Blink+ son 19.99 USD al año, con prueba de 14 días
La caja de la parte 1 Donde viven Claude Code y el repo Unos 12 USD al mes en t4g.small
VPN de malla Alcanzarla sin abrir un puerto El plan gratuito alcanza
Monitor externo Nada. Los iPads sin chip M solo espejan No compres uno

Empieza sin configurar nada

Abre claude.ai/code en Safari, escoge la máquina, trabaja. Agrégalo a la pantalla de inicio para que se comporte como app y no como pestaña. Si la caja de la parte 1 está corriendo, esto funciona ahora mismo sin instalar nada.

Hazlo antes de construir cualquier otra cosa. Te dice si la ergonomía te acomoda antes de gastar un fin de semana en el resto.

Luego fíjate en lo que no puede hacer: en esa pestaña no hay shell. Y ahí está todo el problema.

Si todavía no tienes caja

La versión durable es la parte 1. La versión corta, suficiente para seguir este post: una t4g.small sobre Ubuntu arm64, un instance profile con AmazonSSMManagedInstanceCore, y un security group sin ninguna regla de entrada.

AMI=$(aws ssm get-parameter --output text --query Parameter.Value \
  --name /aws/service/canonical/ubuntu/server/24.04/stable/current/arm64/hvm/ebs-gp3/ami-id)

aws ec2 run-instances \
  --image-id "$AMI" --instance-type t4g.small \
  --iam-instance-profile Name=agent-box \
  --security-group-ids "$SG" \
  --block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=30,VolumeType=gp3,Encrypted=true}' \
  --metadata-options HttpTokens=required \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=agent-box}]'
Enter fullscreen mode Exit fullscreen mode

Luego, en la caja, los dos paquetes de los que depende este post y un archivo de swap, porque 2 GB con un proceso de Node encima se quedan sin memoria:

sudo apt-get install -y tmux mosh
sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Enter fullscreen mode Exit fullscreen mode

Pon todo eso en el script de bootstrap de la parte 1 en lugar de teclearlo una vez. Una instancia cuyo AMI viene de un parámetro de SSM se reemplaza con el tiempo, y el disco se va con ella.

Configura la tableta

Cuatro instalaciones, una sola vez.

1. El teclado. Magic Keyboard Folio para iPad (A16) si quieres el de Apple, Logitech Combo Touch si no. El requisito es el trackpad, no la marca. Seleccionar texto en una terminal con la yema del dedo es tan incómodo que dejas de hacerlo, y entonces dejas de leer bien la salida.

2. Blink Shell, del App Store. Blink+ son 19.99 USD al año con prueba de 14 días, y es la única pieza que cuesta dinero directo. Se lo gana porque trae mosh, guarda las llaves en el Secure Enclave y tiene un comando code. Termius y Secure ShellFish son alternativas razonables; Secure ShellFish monta el host remoto en la app Archivos, que es otro juego de concesiones.

Genera la llave dentro de Blink en lugar de copiar una llave privada al dispositivo:

config → Keys → + → Secure Enclave
Enter fullscreen mode Exit fullscreen mode

Con Tailscale SSH no vas a necesitar instalar esa llave pública en ningún lado, porque la tailnet negocia la identidad. Genérala de todos modos: es a lo que recurres el día que apagues la VPN.

Luego agrega el host:

config → Hosts → +
  Host:     agent-box
  HostName: agent-box     (el nombre en la tailnet)
  User:     appuser
Enter fullscreen mode Exit fullscreen mode

3. Tailscale, del App Store, con sesión en la misma cuenta que la caja.

4. claude.ai/code en la pantalla de inicio. Safari, Compartir, Agregar a inicio. Pierde la barra del navegador y se comporta como app. Instala también la app de Claude, para que el teléfono sirva de segunda pantalla cuando quieras ver cómo va una corrida larga.

Luego corre la prueba que de verdad te dice si esto funciona:

mosh appuser@agent-box
tmux new -A -s main
Enter fullscreen mode Exit fullscreen mode

Arranca algo largo. Bloquea la tableta, espera un minuto, desbloquea, reconéctate con mosh appuser@agent-box y tmux new -A -s main. La sesión debe estar ahí con el trabajo todavía corriendo. Si está, la configuración quedó y todo lo de abajo es preferencia.

Las tres maneras de entrar

Esta es la parte que solo importa cuando la laptop está apagada.

1. La sesión del navegador

claude.ai/code en Safari. Cero configuración, sobrevive que cierres la pestaña, y aquí pasa la mayor parte del trabajo.

No tiene terminal. Así que cuando la caja necesita un humano, este camino no lo puede dar. Todo lo de abajo existe por esa frase.

2. Una terminal de verdad sobre la VPN de malla

En la caja:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --reset --ssh --hostname=agent-box
Enter fullscreen mode Exit fullscreen mode

La caja marca hacia afuera, así que el security group se queda de solo egreso y nada escucha en internet. --ssh deja que la tailnet negocie la identidad de SSH, así que no hay llave pública que copiar a la tableta.

Tres detalles en ese solo comando:

  1. Sin --advertise-tags, a propósito. Un tag cuesta dos ediciones de política, no una. Hay que declararlo en tagOwners o el comando muere de entrada con requested tags [tag:agentbox] are invalid or not permitted, y además taguear el nodo lo saca de autogroup:self, así que la regla ssh por defecto deja de aplicarle y necesitas una segunda con dst apuntando al tag. Sin tag, el nodo es tuyo y las dos cosas salen gratis. La concesión es la expiración de llave: los nodos sin tag expiran, así que apágale la expiración a ese dispositivo en la consola. Los nodos tagueados no expiran, y ese es el argumento real para hacerlo por el camino largo más adelante.
  2. --reset porque tailscale up se niega a cambiar ajustes sin que vuelvas a mencionar todas las banderas no-default. Cualquier intento anterior deja banderas guardadas.
  3. --hostname porque el default es el hostname de EC2, que cambia en cada reemplazo y te deja un nombre inservible en la tailnet.

Aun así necesitas una sección ssh en la política. Sin tag, apunta a tus propios dispositivos:

"ssh": [
  {
    "action": "accept",
    "src": ["autogroup:member"],
    "dst": ["autogroup:self"],
    "users": ["appuser", "autogroup:nonroot"]
  }
]
Enter fullscreen mode Exit fullscreen mode

Usa accept, no check. El check pide re-autenticar en el navegador cada cierto tiempo, que es incómodo desde una tableta.

Desde la tableta:

mosh appuser@agent-box
tmux new -A -s main
Enter fullscreen mode Exit fullscreen mode

Todo vive dentro de tmux. iPadOS mata una app en segundo plano sin preguntar, y lo va a hacer a media tarea. mosh más tmux new -A -s main te devuelve la sesión exactamente como estaba, a través de la suspensión, un cambio de Wi-Fi y un traspaso de hotspot. El SSH pelón te devuelve un socket muerto y trabajo perdido. Esa sola regla es la mayor parte de la diferencia entre que esto se sienta profesional o se sienta como una concesión.

La -A importa más de lo que parece: entra si la sesión existe y la crea si no, así un solo comando sirve para conectar y para reconectar. Con tmux new -s main pelado el reconectar falla y acabas con main, main-1, main-2.

Y una trampa que va a parecer un bug de tmux y no lo es. Blink invoca ~/.local/blink/mosh-server antes del del sistema, y si no está, ese intento sale 127, Blink reintenta, y la sesión que acaba de morir se lleva tu servidor de tmux recién creado. El cliente entonces reporta:

error connecting to /tmp/tmux-1000/default (No such file or directory)
Enter fullscreen mode Exit fullscreen mode

que te manda a depurar tmux, los permisos de /tmp y los locales, y ninguno es el problema. Un symlink elimina el intento fallido:

mkdir -p ~/.local/blink
ln -sf "$(command -v mosh-server)" ~/.local/blink/mosh-server
Enter fullscreen mode Exit fullscreen mode

3. Session Manager en el navegador, como rompe-cristal

La consola de AWS da un shell en la instancia desde Safari, sin nada instalado en la tableta y sin VPN en el camino. Solo necesita el agente de SSM y el instance profile que ya creaste.

Es el camino que sigue funcionando cuando la configuración de la VPN está mal, y en la ventana justo después de que un reemplazo borró lo que hayas configurado a mano.

Verifícalo desde la tableta antes de necesitarlo, incluyendo el paso de MFA. Si el segundo factor vive nada más en la laptop que ahora está apagada en casa, este camino es decorativo. Son cinco minutos que no sirven de nada si los dejas para después.

Por qué las tres

Camino Configuración Da un TTY Sobrevive un reemplazo
claude.ai/code Ninguna No Sí
VPN de malla más mosh Los dos lados, una vez Sí Solo si la instalación de la VPN está en el bootstrap
Session Manager Nada más allá del instance profile Sí Sí

La parte 2 terminó en una caja que estaba active y sin registrar. Recuperar una sesión de Claude Code en ese estado necesita una terminal interactiva, así que el camino cómodo es justo el que no puede. Dos de estos tres no son opcionales.

El editor

En la caja:

curl -Lk 'https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-arm64' \
  --output vscode_cli.tar.gz
tar -xf vscode_cli.tar.gz
./code --version
./code tunnel --accept-server-license-terms
Enter fullscreen mode Exit fullscreen mode

El primer arranque imprime un código y una URL que abres en la tableta. Después de eso tienes VS Code con tus extensiones reales, la de Claude Code entre ellas, porque el extension host corre en la caja.

Corre la descarga como el usuario de la caja, no como root. Hecha desde un shell de root, el binario queda en el home de ese usuario con dueño root y todo lo de después falla de formas que nunca mencionan los permisos.

Luego déjalo como servicio, en este orden:

sudo loginctl enable-linger appuser
./code tunnel service install --accept-server-license-terms
systemctl --user is-active code-tunnel
Enter fullscreen mode Exit fullscreen mode

El enable-linger no es opcional y va primero. service install crea un servicio de usuario, y un servicio de usuario muere con el último login si el usuario no tiene linger. El síntoma sin eso es "el túnel desaparece cuando me desconecto", que no apunta a systemd.

Cuando el servicio esté arriba, mata el ./code tunnel que dejaste en primer plano en el paso anterior. Si lo dejas, quedan dos procesos peleando por el mismo nombre de túnel, y el que sobrevive una desconexión es el del servicio, no el tuyo.

Cuatro cosas que si no, te van a costar tiempo:

  1. La carpeta tiene que ir en la URL. https://vscode.dev/tunnel/<nombre> abre un editor sin archivos y parece roto. Lo que quieres es https://vscode.dev/tunnel/<nombre>/home/appuser/myapp. La forma relativa, /tunnel/<nombre>/myapp, funciona en unas versiones y en otras no; la de ruta completa falla menos. O abre la URL pelada y usa File, Open Folder una vez, y queda en Recent.
  2. code status siempre va a decir No installation of Visual Studio Code stable was found. Ese comando busca un VS Code de escritorio en la máquina, que no es lo que un túnel necesita ni algo que deba estar ahí. No es un error. Para revisar el túnel usa code tunnel service log o systemctl --user is-active code-tunnel.
  3. Diez túneles por cuenta. Pasando eso, el CLI borra uno sin usar al azar, así que limpia con code tunnel unregister.
  4. El build de ARM es cli-alpine-arm64 y corre en Ubuntu. Verificado sobre glibc, code 1.140.0; no hace falta un userland musl ni una variante linux-arm64. Aun así corre ./code --version justo después de extraer, porque una arquitectura equivocada falla ahí y no después, dentro de algo que parece un problema de túnel.

Desde Blink en lugar de Safari. El comando code de Blink abre el mismo editor sin salir de la app de terminal:

code <tunnel_url>
Enter fullscreen mode Exit fullscreen mode

También tiene un modo SFTP que no necesita túnel, usando la extensión de filesystem de Blink:

code appuser@agent-box:~/myapp
Enter fullscreen mode Exit fullscreen mode

Práctico para una edición rápida, con una cosa que conviene saber: en modo SFTP el extension host corre en el navegador, así que recibes solo web extensions y la de Claude Code no está entre ellas. El túnel es la ruta que te da el editor real.

Lo único que no se puede automatizar es la autenticación por dispositivo del túnel. El binario se instala desde un script, el token no, así que un reemplazo de instancia significa volver a registrarlo a mano. Al menos es un paso que sí se puede hacer desde la tableta.

Un servidor de VS Code más su extension host más Claude Code en 2 GB va apretado incluso con swap. Si el editor del navegador va a ser la interfaz principal y no algo ocasional, dimensiona la instancia un escalón arriba.

El trabajo pesado va en otro lado

La caja es chica a propósito. Las suites de pruebas que necesitan base de datos, los builds de contenedor y las pruebas de navegador van en CI, así que un push es la forma de correrlas. Si el proyecto ya se despliega por pipeline y no con builds locales, nada cambia cuando viajas, salvo quién levanta el contenedor.

Lo que no funciona

  • Contenedores, una base de datos local, una suite de pruebas contra un Postgres real. iPadOS no da virtualización. No es un problema de permisos ni de encontrarle la vuelta.
  • Una segunda pantalla. El escritorio extendido necesita M1 o posterior; todos los demás iPads espejan, así que un monitor te da una copia con barras negras de la tableta.
  • Tres pestañas del navegador haciendo todo esto a la vez. Con 6 GB de RAM las pestañas se desalojan. Escoge un cliente principal y deja el trabajo real en tmux del otro lado.

La configuración está terminada cuando puedes reparar la caja desde la tableta, no cuando puedes programar en ella.

Top comments (1)