child_process module

Updated March 15, 2026 · Node.js Modules
node child-process process modules exec spawn

The child_process module is a core Node.js module that enables you to spawn child processes, execute shell commands, and run external programs. It is essential for automating tasks, running build scripts, communicating with system utilities, and creating child processes that share the Node.js runtime. This module provides both asynchronous and synchronous APIs for process management.

Syntax

const { exec, execFile, spawn, fork } = require('child_process');  // CommonJS
import { exec, execFile, spawn, fork } from 'child_process';       // ES modules

exec()

Executes a shell command and buffers the output. The command string is passed to the system shell (/bin/sh on Unix, cmd.exe on Windows), which means you can use shell features like pipes, environment variable expansion, and globbing.

Syntax

exec(command[, options], callback)

Parameters

ParameterTypeDefaultDescription
commandstring(required)The shell command to execute.
optionsobject{}Configuration object (see below).
callbackfunction(required)Called with (error, stdout, stderr) when complete.

Options object:

OptionTypeDefaultDescription
cwdstringprocess.cwd()Current working directory.
envobjectprocess.envEnvironment variables.
shellstring'/bin/sh'Shell to use.
timeoutnumber0Timeout in milliseconds (0 = no timeout).
maxBuffernumber1024 * 1024Max stdout/stderr size in bytes.
encodingstring'utf8'Output encoding.

Example

const { exec } = require('child_process');

exec('ls -la', { cwd: '/tmp' }, (error, stdout, stderr) => {
  if (error) {
    console.error('Execution error:', error.message);
    return;
  }
  console.log('Output:', stdout);
});

Return Value

Returns a ChildProcess instance. The callback receives stdout and stderr as strings (or buffers if encoding is ‘buffer’).


execFile()

Executes a file directly without spawning a shell. This is safer than exec() when you do not need shell features because it avoids shell injection vulnerabilities. The first argument should be the executable path or filename that will be searched in PATH.

Syntax

execFile(file[, args][, options], callback)

Parameters

ParameterTypeDefaultDescription
filestring(required)The executable to run.
argsstring[Global_Objects::eval][Global_Objects::eval]Command-line arguments.
optionsobject{}Configuration object.
callbackfunction(required)Called with (error, stdout, stderr).

Example

const { execFile } = require('child_process');

execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    console.error('Failed to run node:', error);
    return;
  }
  console.log('Node version:', stdout.trim());
});

Return Value

Returns a ChildProcess instance. Unlike exec(), no shell is involved, so features like pipes or globbing will not work.


spawn()

Spawns a new child process without buffering output. Data is streamed via event listeners, making it ideal for long-running processes or when you need to process output incrementally. This is the most flexible method in the module.

Syntax

spawn(command[, args][, options])

Parameters

ParameterTypeDefaultDescription
commandstring(required)The command to run.
argsstring[Global_Objects::eval][Global_Objects::eval]Command-line arguments.
optionsobject{}Configuration object.

Common options:

OptionTypeDefaultDescription
cwdstringprocess.cwd()Working directory.
envobjectprocess.envEnvironment variables.
stdioarray['pipe', 'pipe', 'pipe']Standard I/O configuration.
detachedbooleanfalseRun child independently of parent.
shellbooleanfalseExecute through shell.

Example

const { spawn } = require('child_process');

const child = spawn('grep', ['-r', 'TODO', './src']);

child.stdout.on('data', (data) => {
  console.log('stdout:', data.toString());
});

child.stderr.on('data', (data) => {
  console.error('stderr:', data.toString());
});

child.on('close', (code) => {
  console.log('Process exited with code:', code);
});

Return Value

Returns a ChildProcess instance with stdout, stderr, and stdin as streams. You listen to ‘data’, ‘close’, and ‘error’ events.


fork()

A special case of spawn() specifically for spawning Node.js modules. The forked process runs as a separate Node.js instance and includes a built-in communication channel (IPC) for message passing between parent and child.

Syntax

fork(modulePath[, args][, options])

Parameters

ParameterTypeDefaultDescription
modulePathstring(required)Path to the Node.js module.
argsstring[Global_Objects::eval][Global_Objects::eval]Command-line arguments.
optionsobject{}Configuration object.

Key options:

OptionTypeDefaultDescription
execArgvstring[Global_Objects::eval]process.execArgvNode.js flags to pass.
silentbooleanfalsePipe stdin/stdout to parent.
stdioarray(see docs)Standard I/O configuration.

Example

// parent.js
const { fork } = require('child_process');

const child = fork('./child.js');

child.on('message', (msg) => {
  console.log('Received from child:', msg);
});

child.send({ action: 'start' });

// child.js
process.on('message', (msg) => {
  console.log('Received from parent:', msg);
  process.send({ status: 'running' });
});

Return Value

Returns a ChildProcess with an additional send() method and ‘message’ event for IPC communication.


Synchronous Variants

The synchronous variants block the event loop until the child process completes. Use them for simple scripts where async is not necessary.

execSync()

const { execSync } = require('child_process');

const output = execSync('ls -la', { encoding: 'utf8' });
console.log(output);

execFileSync()

const { execFileSync } = require('child_process');

const version = execFileSync('node', ['--version'], { encoding: 'utf8' });
console.log(version);

spawnSync()

const { spawnSync } = require('child_process');

const result = spawnSync('node', ['-e', 'console.log("hello")']);
console.log('stdout:', result.stdout.toString());
console.log('stderr:', result.stderr.toString());
console.log('status:', result.status);

All synchronous variants return a Buffer or string (based on encoding option) and throw on error. Check the status property for exit codes.


Common Patterns

Running a Python script and capturing output

const { execFile } = require('child_process');

execFile('python3', ['script.py', '--input', 'data.txt'], 
  { encoding: 'utf8' },
  (error, stdout, stderr) => {
    if (error) {
      console.error('Script failed:', error.message);
      return;
    }
    console.log('Result:', stdout);
  }
);

Long-running process with streaming

const { spawn } = require('child_process');

const nginx = spawn('nginx');

nginx.on('error', (err) => {
  console.error('Failed to start nginx:', err);
});

process.on('SIGTERM', () => {
  nginx.kill();
  process.exit(0);
});

Handling timeouts

const { exec } = require('child_process');

const child = exec('sleep 10', { timeout: 2000 }, (error) => {
  if (error && error.killed) {
    console.log('Process timed out and was killed');
  }
});

See Also

  • Stream – Stream-based data processing
  • Process – Process module for runtime info
  • Events – Event emitter pattern