Although each OS implements subprocesses very differently, Execa makes them cross-platform, except in a few instances.
On Unix, executable files can use shebangs.
import {execa} from 'execa';
// If script.js starts with #!/usr/bin/env node
await execa`./script.js`;
// Then, the above is a shortcut for:
await execa`node ./script.js`;
Although Windows does not natively support shebangs, Execa adds support for them.
Only few signals work on Windows with Node.js: SIGTERM
, SIGKILL
, SIGINT
and SIGQUIT
. Also, sending signals from other processes is not supported. Finally, the forceKillAfterDelay
option is a noop on Windows.
The default value for the stdin
, stdout
and stderr
options is 'pipe'
. This returns the output as result.stdout
and result.stderr
and allows for manual streaming.
Instead of 'pipe'
, 'overlapped'
can be used instead to use asynchronous I/O under-the-hood on Windows, instead of the default behavior which is synchronous. On other platforms, asynchronous I/O is always used, so 'overlapped'
behaves the same way as 'pipe'
.
Windows requires files and arguments to be quoted when they contain spaces, tabs, backslashes or double quotes. Unlike Unix, this is needed even when no shell is used.
When not using any shell, Execa performs that quoting automatically. This ensures files and arguments are split correctly.
await execa`npm run ${'task with space'}`;
When using a shell, the user must manually perform shell-specific quoting, on both Unix and Windows. When the shell
option is true
, cmd.exe
is used on Windows and sh
on Unix. Unfortunately, both shells use different quoting rules. With cmd.exe
, this mostly involves double quoting arguments and prepending double quotes with a backslash.
if (isWindows) {
await execa({shell: true})`npm run ${'"task with space"'}`;
} else {
await execa({shell: true})`npm run ${'\'task with space\''}`;
}
When using other Windows shells (such as PowerShell or WSL), Execa performs cmd.exe
-specific automatic quoting by default. This is a problem since Powershell uses different quoting rules. This can be disabled using the windowsVerbatimArguments: true
option.
if (isWindows) {
await execa({windowsVerbatimArguments: true})`wsl ...`;
}
If the windowsHide
option is false
, the subprocess is run in a new console window. This is necessary to make SIGINT
work on Windows, and to prevent subprocesses not being cleaned up in some specific situations.
By default, subprocesses are run using the current user and group. The uid
and gid
options can be used to set a different user or group.
However, since Windows uses a different permission model, those options throw.
Next: 🔍 Differences with Bash and zx
Previous: 🐛 Debugging
Top: Table of contents