Pular para o conteúdo

ADR-0006 Runtime e toolchain

Padrão da empresa — runtime Node LTS, gestor de pacotes pnpm, toolchain unificada Vite+ (vp).

Decisão
Node LTS + pnpm + Vite+Entregar e operar
Estado
SubstituídaSubstituída por ADR-0035
Data
Âmbito
Predefinição da empresa para todas as apps e ferramentas

Cada app precisa de um runtime JavaScript para executar código de servidor, de um gestor de pacotes para instalar dependências e de uma toolchain de desenvolvimento (servidor de dev, build, testes, lint, formatação). A maioria das equipas herda uma toolchain fragmentada: Node aqui, pnpm ou npm ali, mais configurações separadas de Vite/Vitest/ESLint/Prettier que se vão afastando umas das outras com o tempo.

Queremos uma toolchain coerente em dev, CI e produção — o mesmo runtime e o mesmo ponto de entrada em local, na pipeline e dentro do contentor Docker de produção (ADR-0003).

A opção predefinida.

Prós

  • O runtime de referência; tudo é testado primeiro contra ele
  • O npm vem com o Node — sem qualquer configuração

Contras

  • O npm é o gestor de pacotes mais lento e mais fraco dos candidatos (lockfile instável, ruído nas auditorias)
  • Sem uma história de toolchain — dev/build/test/lint continuam a ser ferramentas separadas com configurações separadas

Node LTS como runtime, pnpm como gestor de pacotes e Vite+ (vp, da VoidZero) como toolchain unificada: um único ponto de entrada que combina Vite (dev), Rolldown (build), Vitest (testes), Oxlint + Oxfmt (lint/formatação) e um executor de tarefas com cache — tudo configurado a partir de um único vite.config.ts. O vp env fixa a versão do Node e o gestor de pacotes por projeto.

Prós

  • Compatibilidade com o runtime de referência — o Node LTS é aquilo contra que o ecossistema (TanStack Start, Vite, Hono, Drizzle) testa primeiro; zero trabalho de compatibilidade
  • pnpm: rápido, eficiente em disco, com resolução estrita que apanha dependências fantasma
  • O Vite+ reduz a toolchain a uma dependência e um ficheiro de configuração — dev, build, testes, lint, formatação, tarefas
  • O vp env fixa Node LTS + pnpm por projeto → sem o “na minha máquina funciona” entre dev e CI (a imagem Docker fixa a sua própria tag equivalente)
  • Sair é barato: o Vite+ envolve ferramentas que usaríamos de qualquer forma (Vite, Vitest, pnpm), por isso largá-lo mais tarde é uma alteração de configuração, não uma reescrita

Contras

  • O Vite+ é jovem (1.x, licença MIT) — aceitamos mais volatilidade do que as ferramentas que envolve em troca da consolidação; mitigado pela saída barata
  • Três componentes versionados (Node, pnpm, vp) em vez de um único binário — mitigado pelo vp env, que os gere

Toolkit tudo-em-um: runtime, gestor de pacotes, bundler, executor de testes.

Prós

  • Um único binário para tudo; instalações e arranque muito rápidos
  • A compatibilidade com o Node cobre a maior parte do ecossistema npm

Contras

  • Não é o runtime de referência: casos limite ocasionais de compatibilidade com o Node em pacotes exóticos passam a ser problema nosso
  • A vantagem do tudo-em-um é igualada pelo Vite+, mantendo a compatibilidade do Node e a rigidez do pnpm
  • As ferramentas do Vite/TanStack visam primeiro o Node

Runtime seguro por predefinição, com APIs de standards web.

Prós

  • Excelente modelo de segurança; TS, formatador e linter integrados

Contras

  • A compatibilidade com Node/npm é mais irregular do que se anuncia para a nossa stack
  • Pior encaixe do ecossistema com as ferramentas do Vite/TanStack

Node LTS (runtime) + pnpm (gestor de pacotes) + Vite+ (toolchain) é o padrão da empresa — em dev local, em CI e dentro da imagem Docker de produção (ADR-0003).

Em concreto:

  • Node LTS — apenas linhas LTS, nunca Current. As novas apps começam no Active LTS: 24.x até a 26.x entrar em Active LTS (2026-10-28), e depois 26.x. As atualizações são agendadas antes do EOL. A partir do Node 27, todas as versões major passam a ser LTS (uma versão por ano), pelo que “número par” deixa de significar alguma coisa
  • pnpm para as dependências — pnpm-lock.yaml é o único lockfile; nunca misturar lockfiles de npm/yarn/bun num repositório
  • Vite+ (vp) como único ponto de entrada: vp dev, vp build, vp check (lint + formatação + tipos), vp test — configurado a partir de um único vite.config.ts
  • Versões fixadas por projeto em .node-version e packageManager (vp env pin); o vp env resolve-as em portáteis e em CI. A tag da imagem base do Docker é fixada em separado e tem de coincidir
  • O lint/formatação (Oxlint/Oxfmt) fica resolvido aqui como parte da toolchain; os testes usam o Vitest incluído (ADR-0014)

Os fatores decisivos: compatibilidade com o runtime de referência (zero trabalho de manutenção), a rigidez e a velocidade do pnpm, e o Vite+ a dar-nos a consolidação de toolchain ao estilo do Bun sobre o Node, sólido e fiável — com uma saída barata se o próprio Vite+ nos desiludir.

Mais fácil:

  • Um único ficheiro de configuração governa dev, build, testes, lint e formatação — chega de divergência de configuração entre cinco ferramentas
  • .node-version + vp env acabam com o “na minha máquina funciona” entre portáteis e CI; a tag do Dockerfile cobre os contentores
  • Instalações rápidas e estritas em CI com o content-addressable store do pnpm
  • Onboarding: instalar o vp, correr vp env, pronto

Mais difícil:

  • Acompanhamos uma ferramenta jovem (Vite+ 1.x) — esperar alterações frequentes nas atualizações; fixamos versões e atualizamos de forma deliberada
  • As atualizações do Node são um evento agendado, a nível da empresa (cadência LTS), não uma reflexão tardia

Do que abdicamos: da simplicidade de binário único e da velocidade bruta de instalação do Bun. Aceite — o Vite+ dá-nos a mesma consolidação sobre o runtime de referência, com a rigidez do pnpm como bónus.