A GitHub reconstruiu o runtime que sustenta o GitHub Copilot CLI, o aplicativo Copilot e o Copilot SDK, que antes dependia de TypeScript, Node.js e do mecanismo V8. O resultado, de acordo com o material publicado no blog da GitHub, é de mais de 800.000 linhas de Rust específicas para produção, a maior parte desenvolvida com a ajuda de agentes de inteligência artificial por meio de 128 pull requests integradas gradualmente ao branch principal.
O autor afirma que o trabalho foi concluído ao longo de alguns meses, principalmente com a participação de um único desenvolvedor, enquanto o restante da equipe continuava desenvolvendo recursos do runtime e ampliando seu uso. A GitHub afirma que o desempenho melhorou “em grandes proporções” após a migração, sem apresentar números detalhados na parte disponível do material para medir essa melhoria.
O problema não estava apenas na interface de linha de comando
O runtime do Copilot não se limita a executar a CLI. Ele é uma camada compartilhada usada por várias versões e produtos, incluindo o GitHub Copilot CLI, o aplicativo Copilot e o Copilot SDK, além do VS Code, Visual Studio, Cloud Agent, Copilot Code Review, Copilot Cowork, Copilot Studio e dos aplicativos Excel, Outlook, PowerPoint e Word.
No design anterior, o runtime e a interface da CLI eram amplamente interligados. Quando os produtos precisavam de acesso programático, o SDK era construído, na prática, sobre a CLI, com a execução de um processo Node.js separado e a comunicação com ele por meio de JSON-RPC. Essa abordagem era rápida e flexível, mas impunha um custo operacional a cada aplicativo consumidor.
Criar um novo CopilotClient significava iniciar um processo adicional que hospedava Node.js e V8, analisar o código JavaScript gerado a partir de TypeScript e arcar com a memória associada ao mecanismo. Além disso, falhas no Node.js podiam encerrar a sessão, enquanto os aplicativos precisavam monitorar pelo menos dois processos. De acordo com o material, os pacotes de SDK escritos em C#, TypeScript, Python, Rust, Go e Java consumiam cerca de 100 megabytes do conjunto de memória de trabalho, no mínimo, para o runtime adicional, mesmo quando não precisavam do Node.js para outra finalidade.
Por que Rust foi escolhida?
A GitHub definiu objetivos claros para a nova camada: separar o runtime da interface TUI, reduzir dependências e custos operacionais, permitir a integração no próprio processo e melhorar a escalabilidade e a confiabilidade. Ela também precisava de uma interface C ABI que permitisse usar o runtime nas seis versões do SDK por meio dos diferentes mecanismos de FFI.
O material afirma que Rust ajudou a cumprir esses requisitos, além de oferecer uma cadeia de ferramentas que proporciona um modo de segurança mais moderno, reduz os riscos da cadeia de suprimentos e oferece maior suporte a código correto por construção. Ao mesmo tempo, ressalta que a experiência não é uma recomendação para converter todo projeto grande em TypeScript para Rust; a escolha resultou de requisitos específicos relacionados à inicialização, à memória, à incorporação e à previsibilidade do consumo de recursos.
Substituição gradual em vez de uma reescrita abrangente
A GitHub não executou o projeto por meio de um branch de longa duração nem de uma única conversão ao final do processo. Escolheu uma abordagem dentro do branch principal, na qual cada componente TypeScript é substituído individualmente por um componente Rust. Cada pull request adiciona uma fina camada de ligação que chama Rust e remove a implementação antiga na mesma alteração, mantendo o branch pronto para lançamento e permitindo testar o novo código diretamente dentro do sistema.
- O trabalho habitual dos demais desenvolvedores continuou sem interromper o projeto.
- Cada alteração se tornou menor e mais fácil de revisar do que uma reescrita abrangente.
- Os testes de ponta a ponta específicos da CLI e do SDK foram executados a cada etapa.
- As regressões foram detectadas e corrigidas durante a migração, em vez de serem adiadas até o momento da conversão final.
A GitHub também rejeitou manter duas versões paralelas de cada componente por um longo período. O repositório recebia centenas de pull requests por semana, e manter duas implementações em linguagens diferentes e dois conjuntos de dependências aumentaria a complexidade. A comparação entre duas versões se torna mais difícil nos componentes que gerenciam estado mutável, como o gerenciamento de sessões, porque eles lidam com callbacks e se conectam a partes amplas do sistema.
O que os números revelam?
A estimativa inicial, em maio de 2026, era de cerca de 130.000 linhas de TypeScript, mas não refletia o volume real de trabalho. Os componentes que haviam sido contabilizados na camada TUI foram posteriormente transferidos para o runtime, enquanto novo código TypeScript continuava sendo adicionado em paralelo à migração. Por isso, cerca de 430.000 linhas de TypeScript passaram efetivamente pelo processo de transferência.
No mesmo período, aproximadamente 300.000 linhas de produção de TypeScript foram adicionadas ao projeto e cerca de 430.000 foram removidas, enquanto aproximadamente 1.200.000 linhas de Rust foram adicionadas e cerca de 365.000 foram removidas. Esses números mostram que a estabilidade do volume aparente de TypeScript no repositório não significava ausência de progresso, mas ocultava um grande movimento de adições, remoções e redistribuição de responsabilidades.
Por que esta notícia é importante?
O valor prático da experiência não está apenas no uso de Rust, mas na forma de gerenciar a reescrita de uma camada fundamental compartilhada por um grande número de produtos. A substituição atômica de cada componente, mantendo o branch pronto para lançamento e executando os testes continuamente, reduz os riscos da “grande conversão” e torna mais claro o processo de reversão ou de localização da origem de um problema.
Por outro lado, o material não prova que essa abordagem seja adequada para toda organização nem que agentes de inteligência artificial sejam capazes, sozinhos, de garantir a qualidade de uma reescrita desse porte. A parte disponível também não apresenta medições publicadas do consumo antes e depois, nem esclarece o custo humano detalhado da revisão, dos testes ou do tratamento das regressões. Portanto, a lição mais clara está relacionada à engenharia incremental e à separação de camadas, e não à consideração de Rust ou dos agentes como uma solução geral para todos os processos de migração.