The node:child_process module lets Node.js launch external system binaries—such as git, ffmpeg, python, or mysqldump—in separate OS processes and stream their output. Choosing execFile() or spawn() instead of exec() prevents shell injection vulnerabilities and handles large outputs efficiently.
execFile(), spawn(), and exec()Pick the child-process API based on security, output size, and whether you need a shell.
| Method | Spawns Shell? | Output Handling | Best Use Case |
|---|---|---|---|
execFile(cmd, args) |
No (safe) | Buffered callback / Promise | Short CLI commands returning small output |
spawn(cmd, args) |
No (safe) | Streams stdout / stderr |
Long-running tasks or large output (video, builds) |
exec(commandString) |
Yes (/bin/sh) |
Buffered callback / Promise | Avoid with any user input (shell injection risk) |
fork(modulePath) |
No | IPC message channel | Spawning another Node.js process with messaging |
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileAsync = promisify(execFile);
async function getNodeVersionSafely() {
const { stdout } = await execFileAsync('node', ['--version'], {
timeout: 5000,
});
console.log('Child reported Node:', stdout.trim());
}
getNodeVersionSafely().catch(console.error);
Never pass user input into exec(\convert ${userFile}`)or set{ shell: true }. An attacker passing photo.jpg; rm -rf /can execute arbitrary shell commands. Always useexecFile()orspawn() and pass arguments as a separate string array (['--format', 'png', safePath]`) so arguments are never interpreted by a shell.
exec() on large outputs: exec() buffers output in memory and crashes once output exceeds maxBuffer (default 1 MB). Use spawn() and stream child.stdout instead.timeout and error listeners: External tools can hang forever or fail to spawn (ENOENT). Always pass a timeout and listen to child.on('error', ...).spawnSync() inside an HTTP server: Synchronous child processes freeze the entire Node.js event loop until the child finishes.child_process vs worker_threads?Use child_process when running non-JavaScript binaries (ffmpeg, git, python). Use worker_threads for CPU-heavy JavaScript work inside the same Node process.
Use fork('./worker-script.js'), which opens an IPC channel letting parent and child exchange JSON objects via child.send() and process.on('message').
spawn('npm', ...) fail with ENOENT on Windows?On Windows, npm is a .cmd batch wrapper (npm.cmd). Resolve the proper executable or handle Windows binary names cleanly without passing untrusted arguments to a shell.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.