Node.js6 min read

Child Processes in Node.js

Run shell commands and external programs from Node.js.

Michael Torres
December 19, 2025
0.0k0

Child Processes

Need to run shell commands from Node.js? Use child processes.

exec() - Simple Commands

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

exec('ls -la', (error, stdout, stderr) => {
  if (error) {
    console.error('Error:', error.message);
    return;
  }
  console.log(stdout);
});

Use case: Running simple commands like git status, ls, pwd

spawn() - For Large Output

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

const ls = spawn('ls', ['-la', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`${data}`);
});

ls.on('close', (code) => {
  console.log(`Exited with code ${code}`);
});

Difference:

  • exec() buffers entire output in memory
  • spawn() streams output in chunks

fork() - Run Node.js Files

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

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

worker.send({ task: 'calculate', numbers: [1,2,3,4,5] });

worker.on('message', (result) => {
  console.log('Result:', result);
});
// worker.js
process.on('message', (msg) => {
  const sum = msg.numbers.reduce((a, b) => a + b, 0);
  process.send({ sum });
});

Use case: Heavy computations that would block main thread

Real Example: Image Processing

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

function compressImage(input, output) {
  return new Promise((resolve, reject) => {
    const convert = spawn('convert', [
      input,
      '-quality', '80',
      output
    ]);
    
    convert.on('close', (code) => {
      if (code === 0) resolve();
      else reject(new Error('Failed'));
    });
  });
}

await compressImage('photo.jpg', 'photo-small.jpg');

Real Example: Git Operations

const { exec } = require('child_process');
const { promisify } = require('util');
const execPromise = promisify(exec);

async function getGitStatus() {
  const { stdout } = await execPromise('git status');
  return stdout;
}

async function commitChanges(message) {
  await execPromise('git add .');
  await execPromise(`git commit -m "${message}"`);
}

const status = await getGitStatus();
console.log(status);

Security Warning

const userInput = req.query.filename;
exec(`cat ${userInput}`);

Never do this! User can inject: file.txt; rm -rf /

Safe version:

const { spawn } = require('child_process');
const cat = spawn('cat', [userInput]);

When to Use What

exec()   → Simple commands, small output
spawn()  → Large output, streaming data
fork()   → Heavy Node.js computations

Key Takeaway

Child processes let you run external commands from Node.js. Use spawn for large outputs, fork for Node.js scripts, exec for simple commands. Always validate user input to prevent command injection.

#Node.js#Child Process#System#CLI