The child_process module in Node.js has some methods that let us execute external applications and commands on the hosting system from our application. The main methods on that module are exec, spawn, execFile, and fork. These methods are asynchronous and will return an instance object of the ChildProcess class.

One of the benefits of using the child_process module is that it will allow us to overcome the limitation of Node.js single-thread and that is by running multiple processes at the same time using the previously mentioned methods.

exec Method

This method executes a passed command in the shell and has the results back to the application as a callback function to the exec method. It also takes some options in the form of an object. The syntax of the method looks like the following.

child_process.exec(command[, options][, callback])

Some of the options that are available:

  • cwd: the current working directory of the child process.
  • encoding: the default is 'utf8'.
  • maxBuffer: the largest amount of data in bytes allowed on stdout or stderr (on the callback).
  • timeout.

And much more that could be found on the documentation page.

The callback takes three parameters: error, stdout, and stderr respectively. Let's take an example.

Running the examples on a Unix based OS.

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

exec('ls');

The previous example will just return a list of the directories and files in the current directory; plain directory listing in Unix based systems. Let's add a callback function to that method.

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

exec('ls', (error, stdout) => {
    if (err) throw err;

    console.log(`STDOUT: ${stdout}`);
});

We emitted out the stderr as it is not necessary.

This method is useful when we need to utilize the shell functionalities.

spawn Method

The spawn method spawns an external application in a new process and returns a streaming interface for I/O. Like the exec method, it takes a command as a first parameter, a list of args as an array, and finally an option object that is exactly like the one mentioned in the exec above. The syntax looks like the following.

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

Let's take an example.

const { spawn } = require('child_process');
const ls = spawn('ls', ['-la', '/usr']);

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

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

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

So the command is ls, directory listing, which takes -la and /usr as arguments. It is such if we are running ls -la /usr in bash.

Unlike exec, the spawn method does not have callback, so in order to work with it, it utilize Streams and EventEmitter.

Because spawn returns a stream based object, it’s suitable for dealing with applications and commands that produce extensive amounts of data or while working with data as it is streamed in.