Child Processes
Overview
Sometimes Node.js needs to do something that JavaScript is terrible at, like executing a Python machine learning script, running a bash shell command (like ls or grep), or converting a video file using FFmpeg. Node handles this using the child_process module. It allows Node to physically spawn a completely separate Operating System process, execute a command in the terminal, capture the stdout (standard output) stream, and bring the result back into your JavaScript application.
Syntax
const { exec, spawn } = require('child_process');
// --- 1. EXEC (For small, quick commands) ---
// It buffers the entire output into memory and returns a string.
// GREAT for small tasks, TERRIBLE for massive outputs.
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error(`Fatal OS Error: ${error.message}`);
return;
}
console.log("Terminal Output:\n", stdout);
});
// --- 2. SPAWN (For massive, continuous data streams) ---
// It creates streams! Perfect for long-running processes like video encoding.
const pythonTask = spawn('python3', ['machine_learning.py', '--data', 'input.csv']);
pythonTask.stdout.on('data', (chunk) => {
console.log(`Python says: ${chunk.toString()}`);
});
pythonTask.on('close', (code) => {
console.log(`Python script finished with exit code ${code}`);
});Common Pitfalls
- Using
execwith User Input (Command Injection). If you useexec('ls ' + req.body.folder), a hacker can pass; rm -rf /as the folder name. Node will literally executels ; rm -rf /in your server's terminal, instantly deleting your entire hard drive. NEVER use string concatenation withexec. Always usespawnwith argument arrays to prevent shell injection. - Buffer Limits with
exec.execstores the terminal output in a local Buffer. By default, this buffer is limited to 1MB. If the terminal command outputs 2MB of text, Node violently crashes with aMaxBufferExceedederror. Always usespawnfor large or unknown outputs.
Interview Questions
exec() and spawn() in Node.js?exec spins up a complete OS Shell (like bash or zsh), buffers the entire standard output into memory, and returns it all at once via a callback. spawn executes the binary directly (without a shell) and returns a Node.js Stream, allowing you to process massive outputs chunk-by-chunk.
Real-World Example
Using spawn to run FFmpeg and dynamically stream the compressed video back to the user's browser, without ever saving the new video to disk.
const { spawn } = require('child_process');
app.get('/video', (req, res) => {
// Spawn FFmpeg to compress the video on the fly
const ffmpeg = spawn('ffmpeg', ['-i', 'raw_video.mp4', '-f', 'mp4', 'pipe:1']);
// Pipe the raw binary stdout directly into the Express Response stream!
ffmpeg.stdout.pipe(res);
});Check Your Knowledge
Test your understanding of Child Processes with these quick questions.