Execa aims to be the best way to run commands on Node.js. It is very widely used, battle-tested and has a bunch of features.
However, this means it has a relatively big package size: . This should not be a problem in a server-side context, such as a script, a server, or an app. But you might be in an environment requiring small packages, such as a library or a serverless function.
If so, you can use nano-spawn. It is similar, is maintained by the same people, has no dependencies, and a smaller package size: .
On the other hand, please note nano-spawn
lacks many features from Execa: scripts, template string syntax, synchronous execution, file input/output, binary input/output, advanced piping, verbose mode, graceful or forceful termination, IPC, shebangs on Windows, and much more.
import spawn from 'nano-spawn';
const result = await spawn('npm', ['run', 'build']);
Both Execa and nano-spawn are built on top of the node:child_process
core module.
If you'd prefer avoiding adding any dependency, you may use node:child_process
directly. However, you might miss some basic features that both Execa and nano-spawn provide: proper error handling, full Windows support, local binaries, piping, lines iteration, interleaved output, and more.
import {execFile} from 'node:child_process';
import {promisify} from 'node:util';
const pExecFile = promisify(execFile);
const result = await pExecFile('npm', ['run', 'build']);
Next: 🤓 TypeScript
Previous: 🔍 Differences with Bash and zx
Top: Table of contents