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
Ligações
Apoia-se em
Citado por
Contexto
Seção intitulada “Contexto”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).
Opções consideradas
Seção intitulada “Opções consideradas”1. Node + npm
Seção intitulada “1. Node + npm”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
2. Node LTS + pnpm + Vite+
Seção intitulada “2. Node LTS + pnpm + Vite+”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 envfixa 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
4. Deno
Seção intitulada “4. Deno”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
Decisão
Seção intitulada “Decisão”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 únicovite.config.ts - Versões fixadas por projeto em
.node-versionepackageManager(vp env pin); ovp envresolve-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.
Consequências
Seção intitulada “Consequências”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 envacabam 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, corrervp 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.

