← Todos os posts
06 de out. de 2026BUILD LOGJoyChromium8 min

JoyChromium: por que navegar na web com um controle é mais difícil do que parece

O JoyChromium está sendo um dos projetos mais desafiadores que eu já tentei levar adiante.

No papel, a ideia parece simples: pegar Chromium, colocar dentro de uma interface feita para TV e permitir que praticamente tudo seja controlado por um gamepad.

Na prática, descobri que existe uma diferença enorme entre rodar um site e fazer a web inteira parecer natural usando um controle.

E é exatamente nessa diferença que estou gastando a maior parte do tempo.

A inspiração: a experiência do Edge no Xbox

A principal referência do JoyChromium é a experiência do Microsoft Edge no Xbox.

Não é sobre copiar visualmente o Edge. É sobre a sensação de estar no sofá, abrir um navegador na TV e continuar usando o mesmo controle que já estava na sua mão.

No Windows temos excelentes navegadores desktop, mas a experiência continua sendo construída principalmente para mouse, teclado e uma pessoa sentada perto do monitor.

O JoyChromium tenta atacar outro cenário:

TV + sofá + controle.

Ele também nasceu para se encaixar no Console Mode.

Se o PC já consegue entrar em um “modo console”, faltava uma peça importante: conseguir navegar na web sem quebrar completamente essa experiência e precisar voltar para mouse e teclado.

Usar Chromium não significa ganhar um navegador pronto

Hoje o JoyChromium é feito em Electron, então o motor por baixo dele é Chromium.

Isso resolve uma parte enorme do problema.

Compatibilidade com a web moderna, JavaScript, CSS, TLS, sandbox e um motor atualizado já vêm de um ecossistema extremamente maduro.

Mas o Chromium sozinho não cria a experiência que eu quero.

Abas, histórico, favoritos, permissões, downloads, atualização, páginas internas, sessão, interface e toda a lógica ao redor da página continuam sendo responsabilidade do JoyChromium.

E depois vem a parte realmente complicada:

o controle.

D-pad não é Tab

Esse talvez seja o problema que melhor resume o projeto.

A solução mais óbvia seria transformar o D-pad em Tab e Shift+Tab.

Funciona.

Até você realmente tentar navegar por um site assim.

Uma interface de TV precisa parecer espacial.

Se existe um botão acima de mim, quero apertar para cima.

Se existe um card à direita, quero apertar para a direita.

A ordem em que esses elementos aparecem no HTML não deveria decidir para onde meu foco vai.

Por isso o JoyChromium hoje injeta um sistema próprio de navegação espacial nas páginas.

Ele procura elementos interativos — links, botões, inputs, menus, tabs e outros controles — analisa onde eles estão na tela e tenta encontrar o elemento mais coerente na direção que você apertou.

Na teoria é simples.

O problema é que estamos falando da web.

Cada site parece um sistema operacional diferente

Não existe uma regra universal de como uma página deve se comportar.

Um botão pode ser literalmente um button.

Ou pode ser um div.

Ou alguma coisa com um atributo ARIA.

Ou um componente feito em React.

Ou um elemento dentro de um overlay.

Ou uma interface inteira desenhada de uma maneira completamente customizada.

Então um algoritmo que parece perfeito em uma página pode parecer completamente errado em outra.

E essa provavelmente é uma das maiores dificuldades que estou enfrentando com o JoyChromium.

Eu não estou criando uma interface que eu controlo.

Estou tentando criar uma camada de navegação em cima de interfaces de milhares de outras pessoas.

A solução está virando três soluções

Depois de bastante tentativa, comecei a aceitar que talvez não exista uma maneira única de controlar toda a web.

Por isso o JoyChromium hoje trabalha com três modos diferentes.

Spatial

É o modo que eu gostaria que funcionasse na maior quantidade possível de sites.

O D-pad ou analógico pula entre elementos da página de acordo com a posição deles na tela.

É o que mais se aproxima da sensação de uma interface realmente construída para TV.

Cursor

Algumas páginas simplesmente funcionam melhor com mouse.

Então existe um cursor virtual.

O analógico esquerdo move o ponteiro, o D-pad permite movimentos mais precisos, o botão A clica e o analógico direito faz scroll.

Não é tão elegante quanto o modo espacial, mas é uma saída importante quando um site simplesmente não coopera.

Arrows

E existe um terceiro cenário interessante.

Alguns serviços já fizeram o trabalho.

YouTube e Twitch, por exemplo, possuem interfaces que conseguem responder bem a setas e Enter.

Nesses casos, tentar impor nossa própria navegação pode deixar tudo pior.

Então o JoyChromium pode simplesmente repassar esses comandos e deixar o próprio site controlar o foco.

E o modo escolhido fica salvo por site.

Essa acabou virando uma filosofia importante do projeto:

em vez de obrigar toda a web a se comportar igual, tentar entender como cada site prefere ser controlado.

O input do controle atravessa muita coisa

Outra coisa que subestimei foi quantas camadas existem entre apertar um botão e alguma coisa acontecer na página.

O controle precisa ser detectado.

O shell precisa interpretar o input.

Precisa descobrir o que aquele botão significa naquele contexto.

Precisa saber qual aba está ativa.

Depois precisa decidir se o input pertence à interface do JoyChromium ou ao site.

E, se pertencer ao site, ainda precisa chegar até a página dentro do Chromium.

Ao mesmo tempo, eu não posso simplesmente abrir uma ponte irrestrita entre qualquer site da internet e o processo principal do aplicativo.

É aí que entram sandbox, preload, IPC e isolamento.

Electron facilita absurdamente o desenvolvimento de muita coisa.

Mas construir um navegador em Electron é diferente de construir um aplicativo comum em Electron.

Uma gambiarra que seria aceitável em outro app pode virar uma superfície de ataque quando seu aplicativo executa código vindo da internet o dia inteiro.

Privacidade não pode depender do usuário instalar cinco coisas

Outra decisão que eu tomei desde o começo foi que eu não queria criar um navegador para TV e depois pedir para o usuário instalar extensões, configurar DNS, bloquear tracker e alterar vinte opções antes de usar.

A experiência precisa começar razoavelmente protegida.

Hoje o JoyChromium já possui bloqueio nativo de anúncios e rastreadores usando o engine da Ghostery com listas como EasyList, EasyPrivacy e listas do ecossistema uBlock.

As listas são atualizadas periodicamente.

Também estou tentando manter alguns defaults mais rígidos:

  • navegação HTTPS-first;
  • erros de certificado bloqueados;
  • controle de permissões de câmera, microfone e localização;
  • bloqueio de esquemas de URL perigosos;
  • recusa de downloads considerados arriscados;
  • limitação de popups;
  • abas privadas;
  • senhas e autofill desligados por padrão;
  • DNS-over-HTTPS opcional.

Não quero vender o JoyChromium como “o navegador mais privado do mundo”.

A intenção é bem mais simples:

o usuário não deveria precisar entender segurança de navegador para começar com configurações minimamente decentes.

Um navegador não pode ficar parado

Outra coisa que esse projeto me fez perceber é o quanto um browser precisa continuar se movimentando.

Se eu faço um aplicativo normal e passo alguns meses sem atualizar uma dependência, provavelmente ele continua funcionando.

Com um navegador, você está distribuindo um motor que interpreta conteúdo não confiável vindo da internet.

Deixar Chromium envelhecer não é uma opção muito boa.

Inclusive o primeiro protótipo do JoyChromium não era Electron.

Ele começou com WPF + WebView2.

Funcionava, mas deixava o projeto muito preso ao Windows.

A migração para Electron permitiu manter uma base única para Windows e Linux e acompanhar o Chromium através das atualizações do próprio Electron.

Hoje o projeto já possui automações para acompanhar versões do Electron, rodar CI em Windows e Linux, executar testes e gerar releases.

As próprias listas usadas pelo bloqueador conseguem se atualizar separadamente.

A ideia é simples:

aquilo que muda rápido não deveria depender de eu lembrar de publicar uma versão nova manualmente.

O problema está longe de estar resolvido

Existe uma armadilha fácil nesse projeto.

Você testa Wikipedia.

Funciona.

Testa Google.

Funciona.

Testa mais dois sites.

Funciona.

E começa a pensar:

“pronto, resolvi navegação por controle na web.”

Aí você abre o quinto site.

E tudo quebra.

Um navegador precisa lidar com uma quantidade absurda de interfaces que eu nunca vi e que eu nunca vou conseguir testar individualmente.

Ainda quero melhorar bastante coisa:

  • teclado virtual pensado para controle;
  • sugestões durante digitação;
  • glifos específicos para Xbox, PlayStation e Switch;
  • múltiplos controles;
  • overscan e escala para TVs;
  • controles de mídia;
  • comportamento com serviços que dependem de DRM;
  • e principalmente a navegação espacial em páginas reais.

Essa última provavelmente nunca vai ser uma feature que eu simplesmente marco como “pronta”.

Vai ser um processo constante de teste e ajuste.

Então por que continuar?

Porque quando funciona, faz muito sentido.

Existe algo estranho em configurar um PC inteiro para funcionar como console, sentar no sofá, abrir Steam ou Playnite com o controle, jogar, navegar pelas interfaces sem tocar no teclado…

…e de repente precisar levantar porque alguém mandou um link.

É exatamente esse buraco que quero que o JoyChromium preencha.

O objetivo não é competir com Chrome, Edge ou Firefox.

Eles são navegadores desktop excelentes.

O JoyChromium está tentando resolver outro contexto:

um PC conectado a uma TV, visto a alguns metros de distância e controlado por um gamepad.

Eu ainda não sei até onde vou conseguir aproximar essa experiência daquela que me inspirou no Xbox.

Mas justamente por estar encontrando tantos problemas que eu não esperava, o JoyChromium acabou se tornando um projeto muito mais interessante de construir do que eu imaginava.

E provavelmente ainda vou ter bastante coisa para escrever enquanto tento convencer a web inteira a aceitar um D-pad.