stamatios
← Voltar ao feed
App desktop comprimido em caixinha ao lado de caixote enorme do Chromium, representando os 6 MB do TinyJS
Dev & Engenharia

TinyJS empacota apps desktop em cerca de 6 MB usando webviews nativos

resumo de ~3 min

O que é o tinyjs

tinyjs é uma ferramenta open source (licença MIT) para criar aplicativos desktop para macOS, Windows e Linux com cerca de 6 MB. A proposta é eliminar o Electron e o Chromium embutido: o aplicativo roda em um backend JavaScript com acesso total ao sistema e exibe a interface em um webview nativo fornecido pelo próprio sistema operacional - WebKit no macOS, WebView2 no Windows e WebKitGTK no Linux. Não há servidor HTTP nem portas abertas; a comunicação entre página e backend acontece por RPC sobre um Unix socket em um diretório temporário privado (named pipe no Windows).

Como o tamanho fica pequeno

Dos ~6 MB, 5,6 MB correspondem ao runtime txiki.js (QuickJS + libuv, com sqlite e wasm), ~380 KB ao processo de janela e o restante ao HTML/CSS/JS do desenvolvedor. Em comparação, o Electron fica em 150 MB ou mais porque empacota um Chromium e um Node completos em cada app, e o Tauri fica em ~10 MB. O próprio site reconhece que um runtime sem wasm e sqlite economizaria cerca de 2 MB, mas isso é descrito como direção medida, não promessa.

Comparação com Electron, Tauri e Neutralino

Em relação ao Electron, o que se abre mão é um motor de renderização idêntico em todas as plataformas, addons nativos de Node e uma década de ferramentas do ecossistema Electron; o que se mantém é escrever todo o app, backend incluído, em JavaScript puro.

Em relação ao Tauri, as diferenças apontadas são duas: o backend é JavaScript, não Rust, eliminando a etapa de compilação e a segunda linguagem no projeto; e a superfície do sistema operacional (diálogos, menus, tray, clipboard, keychain, notificações, atalhos globais, auto-update) já vem como API nativa, em vez de plugins que se adicionam um a um. O texto admite que o ecossistema do Tauri, os alvos móveis e o empacotamento multiplataforma estão mais avançados - e recomenda Tauri para quem quer Rust ou mobile.

Quanto ao Neutralino, que é menor (~3 MB), a diferença é que ele não tem backend: o código roda na página e a API do sistema é proxyada por um servidor websocket localhost, com porta real protegida por token. O tinyjs oferece um processo JavaScript real com acesso a arquivos, sockets, subprocessos, FFI e sqlite.

Recursos e fluxo de desenvolvimento

O toolkit inclui hot reload (alterações no frontend entram na janela ativa; no backend o processo reinicia), menu bar nativo real, painéis de arquivo, compilação de bundles assinados e prontos para notarização no macOS, e um modo de embrulhar um site hospedado como janela de navegador, com uma política de capacidades por origem definida em tinyjs.json decidindo o que aquela página pode chamar. Cada projeto vem com um arquivo de skill para que agentes de código conheçam a API.

Para quem usa React, Vue, Svelte, Solid ou TypeScript, há templates Vite (ex.: react-ts) com HMR dentro da janela nativa; backends TypeScript passam por esbuild, o que permite usar pacotes npm. O template padrão é zero dependências. Node e npm só são necessários para os templates Vite, em tempo de desenvolvimento e build - nada disso vai no app final.

Limitações assumidas

O texto é explícito sobre contrapontos. Como cada plataforma usa seu próprio motor, o app não fica idêntico nos três sistemas; o Linux tem as arestas mais visíveis, como codecs de mídia dependentes dos plugins GStreamer instalados e estalos no Web Audio via WebKitGTK (aplicações de áudio tocam pelo elemento diretamente ali). Não é possível compilar um app Windows a partir de um Mac - o build usa o launcher e as ferramentas de assinatura da plataforma hospedeira, contornável com uma matriz de CI.

O macOS é a plataforma principal e estável; Windows e Linux estão em beta, com uma lista curta de chamadas não portadas, majoritariamente exclusivas do macOS (Quick Look, OCR, AppleScript, IA on-device). Não há iOS nem Android - é um runtime desktop. O atualizador embutido verifica sha256 e assinatura de código, substitui in place e faz rollback em caso de falha.