typescriptintermediate

Child Process: exec and spawn

Execute shell commands and spawn processes with exec, execFile, spawn, and fork in Node.js.

typescript
import { exec, execFile, spawn, fork } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

// exec: run shell command, buffer output
async function runCommand(cmd: string): Promise<string> {
  const { stdout, stderr } = await execAsync(cmd);
  if (stderr) console.error('stderr:', stderr);
  return stdout.trim();
}

// execFile: safer, no shell interpolation
function listFiles(dir: string): Promise<string> {
  return new Promise((resolve, reject) => {
    execFile('ls', ['-la', dir], (error, stdout) => {
      if (error) reject(error);
      else resolve(stdout);
    });
  });
}

// spawn: streaming output (for long-running processes)
function streamProcess(cmd: string, args: string[]): Promise<number> {
  return new Promise((resolve, reject) => {
    const child = spawn(cmd, args, { stdio: 'pipe' });

    child.stdout.on('data', (data: Buffer) => {
      process.stdout.write(`[stdout] ${data}`);
    });

    child.stderr.on('data', (data: Buffer) => {
      process.stderr.write(`[stderr] ${data}`);
    });

    child.on('close', (code) => {
      resolve(code ?? 1);
    });

    child.on('error', reject);
  });
}

// spawn with inherit (pass through stdio)
function runInteractive(cmd: string, args: string[]): Promise<number> {
  return new Promise((resolve, reject) => {
    const child = spawn(cmd, args, {
      stdio: 'inherit', // inherit parent's stdio
      shell: true,
    });
    child.on('close', (code) => resolve(code ?? 1));
    child.on('error', reject);
  });
}

// Usage
const nodeVersion = await runCommand('node --version');
console.log('Node:', nodeVersion);

const gitBranch = await runCommand('git branch --show-current');
console.log('Branch:', gitBranch);

await streamProcess('echo', ['Hello from spawn']);

// Run npm install with inherited output
// await runInteractive('npm', ['install']);

Use Cases

  • Running shell commands from Node.js
  • Build tool orchestration
  • Process management and scripting

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.