O Watch Mode no Node.js reinicia uma aplicação ou repete testes quando arquivos relevantes são alterados. Esse fluxo reduz o tempo entre editar, salvar e verificar o resultado, dispensando ferramentas externas em muitos projetos simples.
O Node.js oferece watch mode para executar scripts e também integração com o Test Runner. Na documentação atual do Node.js 26.5.0, o watch mode do Test Runner continua marcado como experimental. Por isso, projetos que dependem do comportamento devem fixar a versão do runtime e validar mudanças antes de atualizar.
Neste guia, você aprenderá a iniciar scripts em watch, executar testes automaticamente, controlar arquivos observados, lidar com processos, sinais, portas, caches, TypeScript, containers, consumo de recursos e diferenças entre desenvolvimento e produção.
O que é watch mode?
Watch mode observa alterações no filesystem e reinicia ou repete a execução. A documentação oficial da opção –watch descreve o comportamento para scripts. A documentação oficial de watch mode do Test Runner explica a repetição de testes afetados.
Para entender os testes nativos, consulte Node Test Runner. Para CLIs e opções, veja Objeto Process no Node.js. O artigo sobre File System no Node.js ajuda a compreender watchers e paths.
Executando um script em watch
node --watch server.jsQuando o arquivo principal ou uma dependência observada muda, o processo atual é encerrado e uma nova execução começa.
Script no package.json
{
"scripts": {
"dev": "node --watch src/server.js"
}
}Assim, a equipe usa:
npm run devWatch Mode no Test Runner
node --test --watchO Test Runner acompanha arquivos de teste e dependências, repetindo os testes afetados quando detecta mudanças.
Status experimental
Na documentação do Node.js 26.5.0, o watch mode do Test Runner possui Stability 1, classificado como experimental. A interface pode mudar. Fixe o runtime no CI e não trate uma opção experimental como contrato permanente.
Desenvolvimento versus CI
Watch mode é feito para desenvolvimento local. No CI, execute a suíte uma vez:
node --testUm processo em watch não termina por conta própria e pode deixar o pipeline aguardando indefinidamente.
Dependências observadas
O runtime tenta acompanhar o grafo de módulos carregados. Se um arquivo não é importado durante a execução, sua mudança pode não provocar reinício.
Imports dinâmicos
Dependências carregadas apenas após uma condição podem entrar no grafo somente depois que o caminho é executado. Teste cenários reais antes de confiar na observação automática.
Arquivos de configuração
Se a aplicação lê um JSON ou YAML por fs.readFile(), esse arquivo pode não ser descoberto como dependência de módulo. Use uma opção de path adicional quando suportada ou importe a configuração de forma compatível.
–watch-path
Versões compatíveis oferecem uma opção para observar caminhos específicos:
node \
--watch \
--watch-path=src \
--watch-path=config \
src/server.jsO suporte e as limitações podem variar por sistema operacional. Consulte a documentação da versão.
Ignorando arquivos
Nem todas as versões oferecem filtros completos de ignore no watch nativo. Organize saídas de build, logs e uploads fora dos diretórios observados para evitar reinícios em loop.
Loop de reinicialização
Este fluxo é perigoso:
- a aplicação inicia;
- gera um arquivo dentro de src;
- o watcher detecta a mudança;
- reinicia;
- gera o arquivo novamente.
Separe arquivos gerados do código-fonte.
Preservando a saída
A opção --watch-preserve-output, quando disponível, evita limpar a tela entre reinícios:
node \
--watch \
--watch-preserve-output \
server.jsIsso ajuda a comparar logs de execuções anteriores, mas pode deixar o terminal muito grande.
Porta ainda ocupada
Se o processo não fecha o servidor corretamente, a nova execução pode receber EADDRINUSE. Implemente shutdown:
const server = app.listen(3000);
process.on('SIGTERM', () => {
server.close(error => {
if (error) {
process.exitCode = 1;
}
});
});Consulte Graceful Shutdown no Node.js.
Sinais durante reinício
O controlador do watch precisa encerrar a execução anterior. Não assuma que apenas Ctrl+C dispara o shutdown. Trate os sinais relevantes de forma idempotente.
Shutdown idempotente
let shuttingDown = false;
async function shutdown() {
if (shuttingDown) return;
shuttingDown = true;
await closeServer();
await closeDatabase();
}
Conexões de banco
Feche pools durante reinício. Uma execução antiga que demora a terminar pode manter conexões e aumentar o total no banco.
Filas e jobs
Durante desenvolvimento, o watch pode interromper uma tarefa no meio. Use ambiente e dados de teste. Não execute jobs críticos reais em um processo que reinicia ao salvar arquivo.
Variáveis de ambiente
Alterar um arquivo .env nem sempre reinicia automaticamente. Inclua o caminho na observação ou reinicie manualmente.
Veja Variáveis de Ambiente no Node.js.
ES Modules
O grafo de imports ESM ajuda a identificar dependências. Imports dinâmicos e arquivos lidos manualmente ainda precisam de atenção.
Consulte ES Modules no Node.js.
CommonJS
Require e seu cache são descartados quando o processo inteiro é reiniciado. Isso evita muitos problemas de hot reload parcial.
Reinício versus hot reload
- Reinício: encerra o processo e começa outro.
- Hot reload: tenta substituir módulos dentro do mesmo processo.
O watch nativo prioriza reinício, que é mais previsível e limpa estado global.
Estado em memória
Caches, sessões locais e dados não persistidos desaparecem a cada reinício. Isso é esperado. Use armazenamento externo quando o estado precisa sobreviver.
TypeScript
Versões modernas do Node.js podem executar parte da sintaxe TypeScript diretamente. Em projetos que transpilem, observe o diretório fonte e execute o artefato correto.
Build separado
Um fluxo comum é ter um processo para compilar e outro para executar:
tsc --watchnode --watch dist/server.jsEvite observar src no processo que executa dist se cada mudança provoca dois reinícios desnecessários.
Source maps
Ative source maps para stacks apontarem para a fonte. Veja Module API no Node.js.
Testes afetados
No Test Runner, watch mode tenta repetir arquivos relacionados às mudanças. Se uma dependência global não for detectada, alguns testes podem não rodar.
Suíte completa periódica
Mesmo usando watch, execute a suíte completa antes do commit:
npm testFiltrando testes
Combine patterns para trabalhar em um conjunto específico:
node \
--test \
--watch \
--test-name-pattern='user service'Ao terminar, rode todos os testes.
Snapshots
Não use atualização automática de snapshots em um loop de watch sem revisão. Consulte Snapshot Tests no Node.js.
Cobertura
Watch com cobertura pode consumir mais CPU e produzir relatórios parciais. Gere cobertura oficial em execução completa e limpa.
Mocks e estado global
O processo de teste pode ser reiniciado, mas dentro de uma execução os mocks ainda precisam ser restaurados. O watch não corrige isolamento ruim.
Containers
Eventos de filesystem em volumes montados podem se comportar de forma diferente. Em Docker Desktop, polling ou configurações da plataforma podem ser necessários.
Docker Compose
Monte apenas os fontes necessários. Não monte node_modules do host sobre um container de outra plataforma.
Kubernetes
Watch mode não é indicado para pods de produção. Imagens devem ser imutáveis e atualizadas por novo deployment.
WSL
Projetos armazenados no filesystem do Windows e acessados pelo WSL podem ter eventos e desempenho diferentes. Manter os arquivos dentro do filesystem Linux costuma melhorar o fluxo.
Network filesystems
NFS e pastas sincronizadas podem não emitir eventos confiáveis. Teste a plataforma e considere uma ferramenta com polling configurável se necessário.
Consumo de CPU
Observar diretórios enormes aumenta custo. Limite o escopo ao código e configuração relevantes.
Muitos arquivos
Dependências, caches, cobertura e artefatos não devem estar na árvore observada. Isso reduz descritores e eventos.
Debounce
Um editor pode salvar vários arquivos em sequência. O runtime agrupa ou repete reinícios conforme a implementação. Ferramentas externas podem oferecer debounce configurável quando isso for necessário.
Comparação com nodemon
O watch nativo cobre o caso básico sem dependência. Nodemon e ferramentas semelhantes podem oferecer:
- globs de ignore avançados;
- extensões específicas;
- comandos customizados;
- delay;
- eventos de lifecycle;
- configuração madura por plataforma.
Escolha a solução mais simples que atende ao projeto.
Comparação com tsx
Ferramentas focadas em TypeScript podem oferecer transformação e watch integrados. O Node nativo reduz dependências, mas pode não cobrir toda a sintaxe ou ergonomia desejada.
Comparação com bundlers
Vite, esbuild e outros bundlers possuem watch voltado a build e frontend. O watch do Node executa processos backend.
Logs de reinício
Inclua PID e horário:
console.log({
event: 'application_started',
pid: process.pid,
time: new Date().toISOString()
});Isso ajuda a distinguir execuções.
Erros de sintaxe
Se uma alteração causa erro de sintaxe, o processo termina. O controlador continua observando e tenta novamente após outra mudança.
Falha no startup
Não crie um loop externo que reinicia imediatamente sem aguardar nova mudança. O watch nativo deve controlar o ciclo.
Depuração
Combine watch com Inspector quando suportado:
node --watch --inspect server.jsConfirme se o debugger reconecta após reinício. Veja Inspector no Node.js.
Testes do shutdown
Crie testes para a função de cleanup. Não dependa apenas de observar manualmente se a porta foi liberada.
Segurança
Watch mode executa código automaticamente após mudanças. Não use em diretórios onde usuários não confiáveis conseguem gravar arquivos.
Ambiente de produção
Em produção, use supervisor, systemd, container orchestrator ou gerenciador de processos. Reinícios devem ocorrer por falha ou deployment, não por alteração local do filesystem.
Arquivos enviados por usuários
Não observe diretórios de upload. Um arquivo enviado poderia provocar reinício repetido ou execução indireta de código.
Testes
Valide:
- mudança no arquivo principal;
- mudança em dependência;
- arquivo de configuração;
- shutdown do servidor;
- liberação de porta;
- erro de sintaxe;
- TypeScript ou build;
- container e volume;
- Ctrl+C;
- suíte completa após watch.
Erros comuns
- Usar no CI: o job nunca termina.
- Não fechar servidor: a porta permanece ocupada.
- Observar artefatos: ocorre loop de reinício.
- Confiar só em testes afetados: uma dependência pode não ser detectada.
- Usar em produção: mudanças locais controlam reinícios.
- Não fixar Node: comportamento experimental pode mudar.
- Observar uploads: usuários provocam reinícios.
Boas práticas
- Use apenas em desenvolvimento.
- Fixe a versão do Node.js.
- Implemente shutdown idempotente.
- Separe arquivos gerados.
- Limite diretórios observados.
- Execute a suíte completa antes do commit.
- Não atualize snapshots automaticamente.
- Teste containers e WSL.
- Use saída preservada quando necessário.
- Mantenha produção imutável.
Conclusão
O Watch Mode no Node.js acelera o desenvolvimento ao reiniciar scripts e repetir testes depois de mudanças no filesystem.
O fluxo funciona melhor com shutdown correto, diretórios pequenos e separação entre fonte e artefatos. Como o watch mode do Test Runner continua experimental no Node.js 26.5.0, projetos devem fixar o runtime e sempre executar a suíte completa fora do watch antes de integrar alterações.




