Stop 02 · Node.js FundamentalsTopics · 17/18

Child Processes

Part of the Backend Developer Roadmap

In short

Sometimes the best tool for a job isn't JavaScript: git, ffmpeg, a Python script. Child processes let your Node app run other programs and read what they print.

Node's ability to spawn separate OS processes — to run shell commands, other scripts, or CPU-heavy work — without blocking the main event loop.

The mascot head chef hands a shopping bag to a young helper heading out while stirring a pot.

Think of it like this

The head chef sends a helper

The head chef doesn't leave the stove to buy coriander. She sends a helper with a bag and a list, keeps cooking, and the helper comes back with the goods or with bad news. A child process is that helper: a separate program your app starts and waits on.

Watch it happen

Running git from Node

Node app
OS
git (child)

spawn("git", ["log"])

1/6Node asks the OS to start git as a separate process with its own memory.

The big ideas

What you need to know

spawn streams output

spawn gives you stdout and stderr as streams. Good for long-running commands or lots of output.

execFile collects it

execFile waits and hands you all the output at once. Handy for short commands like git log.

Avoid the shell with user input

exec runs a shell, so ; or && in input can start extra commands. Prefer execFile or spawn with an argument array.

fork for Node scripts

fork starts another Node script with a built-in message channel, using send() and the 'message' event.

See it in code

Walk through the code

js
1import { spawn, execFile } from "node:child_process";2import { promisify } from "node:util";3 4const run = promisify(execFile);5const { stdout } = await run("git", ["log", "--oneline", "-5"]);6console.log(stdout);7 8const child = spawn("ping", ["-c", "3", "example.com"]);9child.stdout.on("data", (chunk) => process.stdout.write(chunk));10child.stderr.on("data", (chunk) => process.stderr.write(chunk));11child.on("close", (code) => console.log("ping exited with code", code));

1/4execFile, promisified: run git, wait for it to finish, get all of stdout as one string.

Save as child.mjs inside any Git repo and run it. ping -c works on macOS and Linux; on Windows use ping -n 3 instead.

Save yourself the pain

Common mistakes

Oops

Building a command string from user input, like exec("convert " + req.query.file + " out.png").

Do this instead

A file name like a.png; rm -rf ~ runs a second command. Use execFile or spawn with an arguments array, which skips the shell.

Oops

Ignoring the exit code and assuming the command worked.

Do this instead

Check the code in the 'close' event. Promisified execFile throws automatically when the code isn't 0.

Your mission

A git stats endpoint

~25 min

Quick check

Why is execFile("ls", [userInput]) safer than exec("ls " + userInput)?

Go deeper

  1. 1Use `child_process.exec` to run a shell command from a Node script.
  2. 2Learn the difference between `spawn`, `exec`, and `fork`.
  3. 3Understand when to offload CPU-intensive work to a child process instead of blocking the event loop.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge