Executando verificação de segurança...
12

Passou da hora de migrar scripts em Node para GO

Durante esses últimos anos, o Node virou a escolha padrão para scripts e ferramentas de linha de comando (substituindo Python e Bash). É conveniente, todo mundo já tem npm instalado e todo mundo sabe programar em Javascript, o que traz muitos contribuidores para o projeto.

Node carrega uma runtime inteira para executar coisas que muitas vezes, poderiam ser só um binário simples. Tempo de inicialização maior, consumo de memória alto e dependência de ambiente configurado corretamente. Em projeto pequeno isso passa despercebido. Em CI rodando dezenas de vezes por dia, não.

Opinião pessoa: Linguagem interpretada (JS, Java) não deveria ser usada para criar scripts CLI ou automações

Não é coincidência que ferramentas focadas em performance tenham ido por outro caminho. O esbuild é escrito em Go e usa concorrência para processar arquivos em paralelo, Pulumi, mesmo permitindo múltiplas linguagens na camada de uso, mantém sua engine principal em Go para garantir previsibilidade e leveza.

Outro ponto ignorado com frequência é portabilidade. Um script em Node depende da versão correta do Node instalada (as vezes não). Já um programa em Go vira um único executável. Você compila para a arquitetura desejada e acabou. Sem runtime externa, sem gerenciador de pacotes, sem surpresas (dependência circular).

Ferramentas que já estão no limite

Algumas ferramentas do ecossistema frontend claramente já estão sofrendo com o peso da escolha original.

Angular Language Service
Ele roda junto com o editor, analisando templates e tipos em tempo real. É pesado, consome memória e impacta a experiência do desenvolvedor em projetos grandes. Uma engine escrita em Go poderia manter a análise estática com menor consumo e melhor tempo de resposta.

Experiencia própria, o lsp do Angular é incrível, mas terrivelmente pesado. Quando eu tinha apenas 8Gb e usava Windows + wsl, esse peso me atrapalhava.

ESLint
Lint é basicamente análise de AST em larga escala. Em projetos grandes, rodar ESLint pode virar um gargalo real na pipeline. Um motor em Go, compilado e concorrente, poderia reduzir drasticamente o tempo de execução. esbuild é bastante eficiente, e isso prova meu ponto

Prettier
Formatação é processamento puro de texto e AST. Não precisa de runtime dinâmica nem de ambiente complexo. Um formatter compilado tende a inicializar mais rápido e executar com menos overhead.

Spell-checker de código e documentação
Ferramentas de correção ortográfica que rodam em CI ou no editor analisam grandes volumes de texto. É I/O e processamento simples. Perfeito para um binário leve, portátil e rápido (GO e Rust seriam perfeitos para essas ferramentas)
Esses casos têm algo em comum: são ferramentas de sistema, não aplicações web. Não precisam de uma runtime JavaScript completa para existir.

Concorrência sem contorcionismo

O modelo de event loop do Node funciona muito bem para aplicações web. Mas para ferramentas que precisam paralelizar processamento de arquivos, chamadas de rede ou tarefas intensas de I/O, a abordagem de goroutines em Go é mais direta. Não exige arquitetura pensada para contornar limitações do runtime.
E tem a tipagem. Em Go ela é parte da linguagem e validada em tempo de compilação. Não é uma camada adicional. O erro aparece antes de virar problema em produção.

Conclusao

Node continua excelente onde nasceu para brilhar: backend web orientado a I/O.
Mas para ferramentas locais, análise estática, formatação, linting e automação pesada, carregar uma runtime inteira começa a parecer excesso.
Infelizmente, o JIT do Node não é suficiente para otimizar recursão em leitura de arquivos que mudam o tempo todo.

Eu como um dev mais experiente, tenho um tempo de digitação muito acelerado, então o debounce de algumas ferramentas mantém a folga do analisador, mas durante minhas pausas para renomear variáveis, fazer micro alterações enquanto penso na lógica, o analisador vai rodar e ficar acusando erros, ai um overhead começa a acontecer e aí começa o ciclo: CPU sobe, memória sobe, a IDE engasga, o build roda de novo.

O ponto aqui, são ferramentas de desenvolvimento, que TODAS elas são absurdamente pesada, desde o vscode até o build. E sinceramente, as vezes a integração de múltiplas ferramentas é a formula do comedor de recursos.

O problema não é uma ferramenta isolada, era o conjunto.

VSCode.
Language Server.
Spell checker.
ESLint.
Prettier.
Auto-fix.
Build em watch.
Backend rodando.
Frontend rodando.
Docker com banco e Redis.
Túnel externo aberto.

Por exemplo, em 2024, eu costumava usar auto-save do vscode, Code Spell Checker, Angular Language Server, Eslit, Prettier, etc.
Meu vscode era configurado para formatar o código, fazer auto fix e ao mesmo tempo, eu tinha o build em modo watch rodando no terminal, back, front e Docker com Redis + DB (as vezes tinha ngrok rodando junto).

Chegou uma hora que eu pensei, "Porque diabos eu uso essas coisas? Por que eu preciso de tanta coisa para escrever código?".
E assim, eu removi todas essas coisas, fiquei só com o essencial. Comecei a usar apenas o padrão, docker + eslint e o servidor local, build manual e menos watchers, e a diferença foi gritante.

Curiosamente, isso só era um problema real nos projetos em JavaScript. Em C++, Dart ou Go, análise, formatação e build raramente passavam de alguns segundos. O ambiente parecia mais leve, mais previsível.
Quando voltei a usar o Biome, ficou evidente que o problema não era o conceito das ferramentas, era a runtime (Node).

Opinião pessoal: Talvez o futuro das ferramentas de desenvolvimento não esteja em mais abstração sobre JavaScript, mas em menos runtime e mais binário. Porque no final do dia, a melhor ferramenta é aquela que trabalha em silêncio enquanto você pensa.

Porque GO?

Ferramentas deveriam migrar para Go porque elas não são aplicações web, são infraestrutura de desenvolvimento. Elas precisam iniciar rápido, consumir pouca memória, rodar de forma previsível e funcionar em qualquer ambiente sem depender de uma runtime externa. Go entrega binário único, concorrência simples, tipagem nativa e performance consistente. Para esse tipo de problema, ele não é uma alternativa estilística. Ele é tecnicamente mais adequado (na minha opinião).

Além disso, Go é uma linguagem pensada para times grandes manterem código por anos. A linguagem é pequena, a sintaxe é direta e a padronização é forte. Isso reduz bikeshedding, reduz complexidade acidental e facilita onboarding de novos contribuidores. Em ferramentas que viram padrão de mercado, previsibilidade de código importa tanto quanto performance.

A manutenção também tende a ser mais simples. Sem camadas de abstração excessivas, sem dependências profundas e sem ecossistema fragmentado de plugins e loaders competindo entre si. O resultado é menos acoplamento implícito e menos efeito cascata quando algo muda.
Migrar não é trivial, mas também não é impossível. O TypeScript mostrou isso ao reescrever partes críticas do compilador para ganhar desempenho significativo. Quando o gargalo está claro e o custo operacional é alto, reescrever o núcleo em uma linguagem mais adequada deixa de ser radical.

Opinião pessoal: Ferramentas de desenvolvimento criada por desenvolvedores para desenvolvedores, não devem nunca ficarem presas ao mesmo ecossistema. Estamos na era da IA, a tecnologia está evoluindo em um ritmo humanamente impossível de acompanhar!

Carregando publicação patrocinada...
5

Eu comecei a migrar ferramentas locais em node e em python para GoLang. Ainda tem algumas coisas que preciso dar mais atenção, mas na maioria das coisas que uso que troquei para GoLang foi uma maravilha.

Não tem que rodar npm install, pasta node_modules gigante, ou par o Python com o pip install e ativar o ambimente virtual (venv).

É arquivo único, é fácil de distribuir ou transportar (para outros lugares).

4

Simplesmente sensacional a percepção e ideias.!

e Se essas ferramentas de analise de codigo para javascript fossem mais perfomaticas e acertivas?
E se o editor fosse uma light IDE que já ofereça esses serviços para go, python, javascript ?

Bora criar uma IDE basiquinha para resolver esse problema? se topar me pinga ai!

Muito bom seu artigo, me deu uma percepção e ideias legais! Parabéns.

1

Eu pensei em criar uma IDE que não rodasse em cima de uma engine, como Jetbrains (java) e vscode (javascript).
Mas o meu tempo está extremamente curto. Eu estou criando nesse momento, um cliente http que não usa electron. Estou usando Flutter. Eu acredito que passamos da hora de parar de criar coisas em cima do Javascript, não tem essa necessidade.

2

Concordo muito sobre criar coisas sobre javascript...

Hahaha você tá lendo meus pensamentos... tenho um projeto desse de http cliente bem básicão em node... ( até o motivo das minhas indignações ) até pensei em recria-lo em Golang.

esse http client você tá criando em flutter?

não seria melhor em Go( com html Imbutido? ) acho que ficaria mais leve e multiplataforma!

1

Eu pensei em criar em Flutter, porque é mais simples de dar manutenção. E também, eu preciso estudar esse framework, faz um tempo que não toco nele e preciso reaprender a usar. Estou dedicando + ou - 2h por semana e o projeto ainda não está usável, mas pretendo criar uma versão alpha dele o mais breve possível.

https://github.com/GkIgor/gk_http_client

1
0
0
2

Concordo em partes, mas Go também tem GC (meu calcanhar de Aquiles). Prefiro uma migração pra Zig ou Rust, apesar da dificuldade.

Algumas dependências que preciso, refiz em Zig, mas creio que são mais casos isolados.

Se for Go, já vai melhorar muito xD

2

Só uma correção, Java não é interpretado, é compilado e pode ser compilado tanto para bytecode quanto para um nativo exatamente como o GO, eu amo Golang e com certeza uma aplicação Java mesmo no nativo ainda perde para o Go, mas achei necessário fazer essa correção, dito isto, concordo com todo o restante.

1
1

O bun ta ai pra resolver grande parte dos problemas que vc citou sem precisar mudar de linguagem. Ele compila seu codigo javascript para um binario unico tbm.

1

Mas eu ainda vai precisar subir uma engine para cada ferramenta. Por mais que o node/bun faça alguns compartilhamentos, se tu startar 5 scripts ao mesmo tempo, é um GC, um event loop e um processo Node/bun para cada um.

1

Tecnicamente acho massa a ideia!

Porém, vale olhar pelo ângulo mercadológico também, deixo aqui alguns pontos de reflexão(não verdades, conhecturas, pontos de vista):

  • gestão da mudança;
  • custo de desenvolvedor Js x go (nos próximos 5 anos);
  • IA resolvendo problemas que acreditamos que ainda precisamos resolver;
  • adoção corporativa python > outras tecnologias, aqui entra fatia de mercado.
  • mercados adeptos de js/ts em crise econômica devido ao preço do dinheiro (o que favorece a migração por eficiência operacional ou a morte do negócio no meio do caminho)

E O mais importante, a avaliação tem o olhar de dev para dev, enquanto a aprovação de algo assim passa pelo olhar do impacto positivo no cliente final...

1

Isso faz sentido, para o mundo corporativo. Por exemplo, reescrever o Cypress em GO. As empresas não fariam a troca.
Mas ferramentas para devs, temos milhões de devs no mundo, só precisamos de uma dezena para migrar. Não precisa migrar 100%, apenas pequenos pedaços críticos.