child_process
child_process executa programas externos a partir do Node - prefira spawn com arrays de argumentos explícitos, entenda os modos stdio e evite injeção de shell ao envolver ferramentas CLI.
Busque em todas as páginas da documentação
child_process executa programas externos a partir do Node - prefira spawn com arrays de argumentos explícitos, entenda os modos stdio e evite injeção de shell ao envolver ferramentas CLI.
import { spawn } from 'node:child_process';
const child = spawn('git', ['rev-parse', 'HEAD'], { stdio: ['ignore', 'pipe', 'pipe'] });import { promisify } from 'node:util';
import { execFile } from 'node:child_process';
const execFileAsync = promisify(execFile);
const { stdout } = await execFileAsync('node', ['--version']);Quando usar isso:
ffmpeg CLIimport { spawn } from 'node:child_process';
import { once } from 'node:events';
async function runGitHash(): Promise<string> {
const child = spawn('git', ['rev-parse', 'HEAD'], {
stdio: ['ignore', 'pipe', 'pipe'],
});
let stdout = '';
child.stdout.on('data', (chunk: Buffer) => {
stdout += chunk.toString('utf8');
});
const [code] = await once(child, 'exit');
if (code !== 0) throw new Error(`git saiu com código ${code}`);
return stdout.trim();
}
// Perigoso - não faça isso com entrada do usuário:
// spawn(`git rev-parse ${userBranch}`, { shell: true });import { pipeline } from 'node:stream/promises';
import { spawn } from 'node:child_process';
import { createWriteStream } from 'node:fs';
async function compressWithGzip(input: string, output: string): Promise<void> {
const gzip = spawn('gzip', ['-c', input], { stdio: ['ignore', 'pipe', 'inherit'] });
await pipeline(gzip.stdout, createWriteStream(output));
const code = await new Promise<number>((res) => gzip.on('exit', res));
if (code !== 0) throw new Error(`gzip falhou ${code}`);
}O que isso demonstra:
execve sem interpretação do shellexec para saída grandepipeline para backpressureshell: true apenas para comandos fixos confiáveis - nunca com strings de usuáriospawn - streams stdio, retorna imediatamente, evento exit com código.exec - bufferiza stdout/stderr, invoca o shell por padrão - risco de injeção.execFile - sem shell, saída bufferizada com maxBuffer padrão de 1MB.fork - child especial do Node com canal IPC - padrão legado antes de worker_threads.| API | Shell | Saída | Uso |
|---|---|---|---|
| spawn | Não (padrão) | Stream | Saída longa, pipes |
| exec | Sim (padrão) | Bufferizada | Comandos pequenos e confiáveis |
| execFile | Não | Bufferizada | Argumentos em array pequenos |
| fork | Não | IPC | Workers Node-only (legado) |
import type { ChildProcess } from 'node:child_process';
export function killProcessTree(child: ChildProcess): void {
if (child.pid) process.kill(-child.pid, 'SIGTERM');
}Específico da plataforma - grupos de processos Linux precisam de detached: true no spawn.
shell: true + entrada do usuário - injeção de comando. Correção: spawn(cmd, [arg1, arg2]) sem shell.exec maxBuffer excedido - lança erro em stdout grande. Correção: spawn com streams.exit ou aguarde a saída em supervisores de longa duração.stdio: 'ignore' para jobs em background.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| worker_threads | JS de CPU no mesmo runtime | Precisa de binário separado ou processo OS sandbox |
| Biblioteca Node pura | ffmpeg wasm, sharp vs CLI | CLI madura já scriptada |
| Container exec | Job K8s por tarefa | Script local simples |
Mocks de teste node:child_process | Testes unitários | Orquestração de produção |
spawn para streaming e segurança; exec para one-liners rápidos e pequenos de shell confiáveis apenas em scripts de desenvolvimento.
O child compartilha o console do pai - bom para ferramentas CLI que mostram saída ao vivo no terminal.
spawn(cmd, args, { env: { ...process.env, FOO: 'bar' } }).
Sim - stdio: ['pipe', 'pipe', 'pipe'] e escreva para child.stdin.
code é nulo e signal é definido ao matar - manipule SIGTERM em scripts child.
setTimeout + child.kill('SIGKILL') com limpeza - ou use timers/promises + padrões AbortSignal em wrappers.
Não removido - prefira worker_threads para CPU; fork para código legado de IPC Node.
Procure por shell: true e comandos concatenados em strings em PRs.
Faça pipe do stderr para o logger - stdio: ['ignore', 'pipe', 'pipe'] e marque as linhas de stderr do child.
cluster faz fork de workers Node; spawn executa executáveis arbitrários.
execFile('git', ['diff', '--name-only']) - seguro e determinístico.
Arquivos .cmd podem precisar de shell: true - prefira node/npm com caminhos explícitos documentados para a equipe.
Versões do Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, e NestJS 11.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026