What are child processes in Node.js?
Child Processes in Node.js
The child_process module allows Node.js to spawn new OS processes, enabling you to run shell commands, execute other programs, or distribute workloads across multiple processes.
Four Main Methods
| Method | Description | Use Case |
|---|---|---|
exec() | Runs shell command, buffers output | Simple commands with small output |
execFile() | Runs a file directly (no shell) | Safer, slightly faster than exec |
spawn() | Spawns process with streams | Large output, real-time data |
fork() | Spawns Node.js child with IPC channel | Node-to-Node communication |
exec() — Shell Commands
const { exec } = require('child_process');
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error('Error:', error.message);
return;
}
if (stderr) console.warn('Stderr:', stderr);
console.log('Output:', stdout);
});exec() uses a shell (beware of shell injection!) and buffers entire output in memory.
execFile() — Direct File Execution
const { execFile } = require('child_process');
// Safer — no shell, no injection risk
execFile('node', ['--version'], (error, stdout) => {
console.log('Node version:', stdout.trim()); // v20.0.0
});spawn() — Streaming Output
const { spawn } = require('child_process');
const child = spawn('ffmpeg', ['-i', 'input.mp4', 'output.gif']);
// Real-time stdout
child.stdout.on('data', data => {
process.stdout.write(data);
});
child.stderr.on('data', data => {
process.stderr.write(data);
});
child.on('close', code => {
console.log(`Process exited with code ${code}`);
});Best for large output or long-running processes.
fork() — Node.js Child with IPC
// child.js
process.on('message', (data) => {
const result = heavyCompute(data.n);
process.send({ result });
});
// parent.js
const { fork } = require('child_process');
const child = fork('./child.js');
child.send({ n: 1000000 });
child.on('message', ({ result }) => {
console.log('Result:', result);
child.kill();
});fork() is like spawn() but specialized for Node.js files and adds a built-in IPC channel (process.send() / process.on('message')).
execSync / spawnSync (Blocking)
const { execSync } = require('child_process');
// Blocks event loop — use only in scripts, not servers!
const output = execSync('git status').toString();
console.log(output);Promisified Version
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
async function getGitLog() {
const { stdout } = await execAsync('git log --oneline -5');
return stdout;
}Or use child_process/promises (Node.js 15+):
const { exec } = require('child_process/promises');
const { stdout } = await exec('ls -la');Child Process vs Worker Threads
| Child Process | Worker Threads | |
|---|---|---|
| Memory | Separate | Shared (optional) |
| Language | Any (shell, Python, etc.) | JavaScript only |
| Communication | Slow IPC / stdin/stdout | Fast MessagePort |
| Crash isolation | High | Lower |
| Best for | Shell commands, non-Node programs | CPU tasks in JS |
Summary
Child processes let Node.js escape its single-thread limitation and interact with the OS. Use exec for simple commands, spawn for streaming large output, and fork for Node.js-to-Node.js communication with IPC.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.