Um Linux a sério no bolso: o iSH+ no iPhone
O iSH+ corre um kernel Linux a sério no iPhone e no iPad, numa VM com JIT. SSH, tmux e sessões de Claude Code no bolso, com YubiKey.
O meu filho Johnny construiu o iSH+, um fork do iSH que arranca um kernel Linux a sério no iPhone e no iPad, dentro do QEMU, com JIT. Corre Ubuntu, Arch, Fedora e mais uma dúzia de distribuições, e até programas x86. Uso-o para entrar nas minhas sessões de Claude Code nos servidores de casa a partir do telemóvel, com a YubiKey encostada às costas dele.
Na terça-feira o Johnny instalou uma coisa no meu telemóvel e devolveu-mo. "É Ubuntu", disse ele. E era: Ubuntu 26.04 num kernel Linux 6.18, com apt, compiladores e tudo o resto que vem com isso.
Nessa noite estava no sofá a escrever cc-super, a escolher uma sessão de tmux com as setas e a falar com o Claude Code no meu servidor.
Ele construiu isto em cerca de um dia.
Índice
- Não é um emulador de Linux, é o kernel a sério
- O que dá para fazer
- O que eu construiria em cima dele
- Porque importa se vives no tmux e no Claude Code
- Como o Johnny o construiu num dia
- O que correu mal
- Instalar
- Como ajudar
Não é um emulador de Linux, é o kernel a sério
O iSH original é um trabalho engenhoso. Emula um processador x86 e traduz as chamadas de sistema do Linux para as do iOS, uma a uma. Na maior parte das vezes funciona. Quando um programa precisa de uma chamada de sistema que o iSH não implementou, não funciona, e o programa falha de maneiras difíceis de explicar.
O iSH+ vai pelo outro caminho. Corre o QEMU dentro da app, arranca um kernel Linux arm64 verdadeiro e deixa o kernel fazer o que os kernels fazem. Os programas veem um sistema Linux genuíno, porque estão a correr num.
Sobretudo frustração com o iSH original, e também queria ter outras distros a correr nos meus dispositivos.
Foi a resposta do Johnny quando lhe perguntei porquê. Começou por acrescentar funcionalidades ao iSH e depois decidiu transformá-lo numa máquina virtual completa.
O senão é o JIT. O QEMU só é rápido quando pode gerar código máquina em tempo de execução, e o iOS só permite isso a apps com um debugger ligado. A App Store não o permite de todo, por isso o iSH+ é instalado por sideload e liga um debugger a si próprio para ativar o JIT. Sem computador.
O que dá para fazer
Quase tudo o que farias numa máquina Linux:
- Escolher a distribuição. Alpine, Debian, Ubuntu, Arch, Fedora, openSUSE, Void, Kali, Rocky e mais, descarregadas dentro da app, cada uma com a sua conta de utilizador.
- Instalar pacotes a sério. No meu iPhone,
apt install build-essentialdemorou 27 segundos e compilar um pequeno programa em C demorou um. - Correr programas x86_64. O FEX vem incluído:
apt-x86 install <pacote>ex86 <comando>. Um ciclo em shell que demorava 5,5 segundos nativo demorou 13,5 com emulação x86, melhor do que eu esperava de um telemóvel. - Abrir os teus servidores no Safari. Arranca um servidor de desenvolvimento no Linux e ele fica em
localhost:<porta>no dispositivo, ou na tua rede se partilhares a porta. - Usá-lo com o iOS.
~/iOSé a pasta do iSH+ na app Ficheiros,pbcopyepbpasteusam a área de transferência do iOS, e os Atalhos podem correr comandos no Linux. - Ficar na tua VPN. O Tailscale funciona dentro do Linux, nomes do MagicDNS incluídos.

O terminal é o SwiftTerm, com várias sessões, temas, suporte de rato e teclados externos bem tratados.
O que eu construiria em cima dele
Uma lista de funcionalidades não lhe faz justiça. Com um Linux a sério lá dentro, o telemóvel deixa de ser só um ecrã à frente dos teus servidores. Passa a ser um pequeno servidor que andas a levar contigo. Isto é o que eu pediria ao Claude Code. Algumas já experimentei, a maioria são ideias, e todas assentam em coisas que o iSH+ já faz.
Primeiro, uma limitação honesta. É o iOS que decide quando as apps correm. Com "Keep Running in Background" ligado, o Linux continua a correr enquanto usas outras apps, mas o iOS pode fechar o iSH+ quando precisar da memória. Pensa em "serviço enquanto preciso dele", não em "servidor com cinco noves".

Uma app privada que nunca sai do telemóvel
Pede ao Claude para fazer vibe coding de uma pequena app web: um serviço em FastAPI ou Node com SQLite, uma ou duas páginas de HTML. Corre-a no iSH+ e abre localhost:8000 no Safari, ou adiciona-a ao ecrã principal.
Um diário, um registo de hábitos, um dashboard sobre os teus próprios exports CSV em ~/iOS, uma ferramenta para um só cliente. Sem revisão da App Store, sem alojamento, sem conta, e os dados ficam num ficheiro no teu telemóvel. Quando a quiseres noutro dispositivo, partilha a porta pelo Tailscale.

Um backend de testes para a app iOS que estás a construir
As outras apps no dispositivo chegam ao Linux por localhost. Por isso a API com que a tua app iOS fala pode correr ao lado dela: um servidor de mocks com respostas fixas, uma cópia do teu backend real num processo simples de Python ou Node, ou um recetor de webhooks que acompanhas com tail -f.
Testar fluxos offline, respostas lentas ou códigos de erro num dispositivo real deixa de precisar de um portátil na mesma rede Wi-Fi.
Uma verificação de dispositivo para a tua app web
É a que não me sai da cabeça. Imagina que tens uma ferramenta interna, um painel de administração ou um dashboard, e o teu pior cenário é um cookie de sessão roubado. Queres que a sessão só seja válida enquanto um dispositivo específico o confirmar.
No servidor, a app emite um desafio. No telemóvel, um pequeno serviço no iSH+ guarda uma chave, assina o desafio e responde pelo Tailscale. Sem resposta, sem sessão. Se quiseres mais rigor, a assinatura vem da YubiKey: o iSH+ expõe o leitor NFC ao Linux como um dispositivo FIDO, por isso o fido2-assert e a libfido2 funcionam para qualquer coisa, não só para o ssh. Um login, ou uma ação sensível, passa a precisar do telemóvel e de um toque.
Os browsers estão a ganhar um standard para este tipo de ligação, as Device Bound Session Credentials, e para sites públicos é essa a ferramenta certa. Para as tuas ferramentas internas, um fim de semana com o Claude Code e um telemóvel que já andas a levar contigo resolvem a maior parte.
Atalhos que correm ferramentas Unix a sério
A ação Run Command nos Atalhos envia um comando para o Linux e recebe o output de volta. Isso põe a caixa de ferramentas inteira do Linux ao alcance da Siri, do menu de partilha e das automações.
Redimensionar um lote de fotografias e tirar-lhes os metadados com o ImageMagick. Converter um vídeo com o ffmpeg. Passar o jq por uma resposta de uma API e deixar o resultado na área de transferência com pbcopy. Lançar um script de deploy por voz, se gostares de viver perigosamente.
Um kit de operações no bolso
kubectl, terraform, ansible, psql, os teus próprios scripts, no Tailscale. Alguns CLIs de fornecedores só têm builds Linux x86_64; com o FEX correm na mesma. Quando alguma coisa avaria num sábado, o telemóvel chega para ver, e às vezes chega para resolver.
Um sítio seguro para aprender
Todas as distribuições, um disco que podes aumentar, apagar e começar de novo. Estraga uma instalação de Arch, aprende units de systemd no Fedora, pratica a parte de redes de que só te lembras a meias, no comboio. Nada do que fizeres lá toca nas tuas máquinas a sério.
Porque importa se vives no tmux e no Claude Code
O meu trabalho com o Claude Code não corre no portátil. Corre num servidor em casa, em sessões de tmux com nome que sobrevivem a eu fechar a tampa. Já escrevi sobre encontrar sessões perdidas e sobre não perder o fio aos separadores; as sessões são a unidade de trabalho.
O que eu sempre quis foi espreitá-las do telemóvel sem abrir o portátil. As apps de SSH para iOS chegam perto, mas são apps de SSH. Não dava para correr os meus próprios scripts.
Com um Linux a sério no telemóvel, o meu setup veio quase tal como está:
cc-superdá-me um seletor fzf das sessões de tmux no meu servidor. Setas, enter, e estou na sessão de Claude Code onde a deixei.- Um cabeçalho no login lista as minhas máquinas, e
ssh mega,ssh spark,ssh super,ssh maclevam-me a cada uma. - O meu Mac também chega ao telemóvel: o iSH+ partilha a porta SSH do Linux na rede, por isso
ssh iphonevai direto pelo Tailscale.

A parte que eu não esperava é a YubiKey. Todos os logins SSH no meu lab precisam de uma chave física, e essa regra costuma deixar os telemóveis de fora. O iSH+ liga o leitor NFC do iPhone ao Linux como um dispositivo FIDO, por isso o ssh dentro do Ubuntu pede a chave e eu encosto-a às costas do telemóvel. Nenhuma chave de software no telemóvel.
Não conheço outro terminal para iOS que faça isto.
Como o Johnny o construiu num dia
O Johnny construiu o iSH+ com o Claude Code. A primeira versão que arrancou levou cerca de um dia, e as partes mais difíceis não foram onde eu teria apostado.
A primeira tentativa usava um fork do QEMU feito por ele. Mudar para o fork do UTM, que já traz anos de trabalho para pôr o QEMU a portar-se bem no iOS, acelerou tudo, e a partir daí o kernel finalmente arrancou.
Depois veio o JIT.
Havia imensos problemas de alocação de memória, e tive de ir buscar muitos truques ao UTM para o pôr a arrancar como deve ser. O pairing em si não foi muito difícil.
Como funciona agora: um pequeno helper dentro da app usa o StikJIT para ligar um debugger ao iSH+ através do LocalDevVPN, e serve os pedidos de memória executável do QEMU. No iOS 27 a app faz o pairing com o próprio dispositivo, por isso não há computador envolvido. As ideias vêm do Madeira e do StikDebug, e o README dá crédito a todos.
O resto é canalização que o faz parecer nativo. O init da distribuição não corre; o iSH+ arranca o seu a partir de um disco de suporte. Canais virtio levam a área de transferência, os comandos dos Atalhos e as portas abertas entre o Linux e o iOS, e o DNS passa pelo resolver do iOS para os nomes da VPN funcionarem.
O que correu mal
Fui o primeiro utilizador a sério, por isso a maioria dos primeiros bugs veio do meu telemóvel. Cada um virou uma issue no GitHub, e cada um ficou resolvido em poucas horas.
A minha primeira instalação não via a YubiKey. O painel do NFC nunca aparecia, e o ssh dizia "device not found". A app estava assinada sem a capability NFC Tag Reading, de que o iOS precisa para uma app poder falar com uma chave de segurança.
O segundo login falhava sempre. O primeiro toque funcionava, o host seguinte falhava. O iOS recusa uma sessão NFC nova se a abrires pouco depois de a anterior fechar. Mandei um pull request que espera esse intervalo, e saiu na 0.2.2.
Desligar a Automatic Memory congelava a app. Uma tabela das definições a recarregar-se em ciclo. Tirei o crash log por USB, abri a issue, e ficou resolvido na mesma manhã.
Pedi uma funcionalidade que ele decidiu não fazer. O iSH+ precisa do LocalDevVPN no momento em que ativa o JIT, e eu uso o Tailscale, por isso pedi um túnel embutido. O Johnny pesou-o contra o que custaria aos utilizadores: mais um perfil de VPN, mais um entitlement. Em vez disso lançou um Atalho que troca as VPNs. Tinha razão.
Montei um túnel SSH reverso de que não precisava. O meu primeiro setup fazia o telemóvel abrir um túnel para o Mac, para eu conseguir voltar a entrar. O iSH+ já partilha portas na rede. Depois de uma reinstalação apaguei o túnel e a chave dele.
Instalar
O iSH+ instala-se por sideload. A forma mais fácil é adicionar a fonte dele ao SideStore, que também te traz as atualizações:
https://raw.githubusercontent.com/johnnydevelops/ish-plus/main/source.json
O README tem um link de um toque, e a mesma fonte funciona no AltStore e no Feather. Também podes descarregar o .ipa das releases e usar qualquer sideloader.
Depois:
- Instala o LocalDevVPN e liga o Modo de Programador.
- Abre o iSH+, faz o pairing com o dispositivo (no iOS 27 ele trata disso sozinho), escolhe uma distribuição e cria a tua conta.
- Se usas o Tailscale ou outra VPN, adiciona o atalho iSH+ JIT durante a configuração. Muda para o LocalDevVPN enquanto o JIT liga, e depois volta.
O iSH+ precisa do iOS 26 ou posterior. Duas funcionalidades precisam de uma conta paga de programador Apple: mais memória para o Linux, e chaves de segurança por NFC. Para o NFC, o README sugere um sideloader que mantenha os entitlements da app, como o Sideloadly ou o Feather com o teu próprio perfil de provisionamento. Funciona. Também podes ativar NFC Tag Reading no app ID na tua conta de programador e reinstalar, que foi o que eu fiz com o iloader.
Como ajudar
O iSH+ é open source, sob a GPL, e o Johnny aceita tudo: issues, pull requests e testes.
Se encontrares um bug, a issue mais útil tem os passos para o reproduzir, o dispositivo e a versão do iOS, e o log da app. Se quiseres uma funcionalidade, diz o que estás a tentar fazer, não só o que queres que seja feito; o meu pedido do túnel para o JIT é um bom exemplo do porquê. Se tens um iPad ou um iPhone mais antigo, testar nele ajuda mais do que pensas.
O repositório tem as instruções de build, se quiseres ir mais fundo.
Já usei muitas apps de terminal no iOS. Esta é a primeira em que me esqueço de que estou num telemóvel.
Links: iSH+ no GitHub · Johnny no GitHub · iSH · UTM · QEMU · FEX · StikDebug · SideStore
Tags: iOS, Linux, Claude Code, ferramentas de developer, tmux