# 📎 Windows
Although each OS implements subprocesses very differently, Execa makes them cross-platform, except in a few instances.
## Shebang
On Unix, executable files can use [shebangs](https://en.wikipedia.org/wiki/Shebang_(Unix)).
```js
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.
## File extensions
On Windows, executables have a file extension, such as `.exe`, `.cmd`, `.bat` or `.com`. When the file is passed without any extension, Execa resolves it using the [`PATHEXT`](https://ss64.com/nt/path.html#pathext) environment variable, just like the OS does when looking up commands.
```js
import {execa} from 'execa';
// Runs `npm.cmd`
await execa`npm run build`;
```
This means `.cmd` and `.bat` files can be run directly. Unlike Node.js, Execa does not require a [shell](shell.md) (nor a `cmd.exe /c` prefix) for this. Relative paths (such as `./folder/executable`) and files whose path contains spaces also work without a shell, just like on Unix. Execa handles this automatically.
## Signals
Only few [signals](termination.md#other-signals) work on Windows with Node.js: [`SIGTERM`](termination.md#sigterm), [`SIGKILL`](termination.md#sigkill), [`SIGINT`](https://en.wikipedia.org/wiki/Signal_(IPC)#SIGINT) and [`SIGQUIT`](termination.md#sigquit). Also, sending signals from other processes is [not supported](termination.md#signal-name-and-description). Finally, the [`forceKillAfterDelay`](api.md#optionsforcekillafterdelay) option [is a noop](termination.md#forceful-termination) on Windows.
## Asynchronous I/O
The default value for the [`stdin`](api.md#optionsstdin), [`stdout`](api.md#optionsstdout) and [`stderr`](api.md#optionsstderr) options is [`'pipe'`](output.md#stdout-and-stderr). This returns the output as [`result.stdout`](api.md#resultstdout) and [`result.stderr`](api.md#resultstderr) and allows for [manual streaming](streams.md#manual-streaming).
Instead of `'pipe'`, `'overlapped'` can be used instead to use [asynchronous I/O](https://learn.microsoft.com/en-us/windows/win32/fileio/synchronous-and-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'`.
## Escaping
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](shell.md) is used.
When not using any shell, Execa performs that quoting automatically. This ensures files and arguments are split correctly.
```js
await execa`npm run ${'task with space'}`;
```
When using a [shell](shell.md), the user must manually perform shell-specific quoting, on both Unix and Windows. When the [`shell`](api.md#optionsshell) option is `true`, [`cmd.exe`](https://en.wikipedia.org/wiki/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.
```js
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`](api.md#optionswindowsverbatimarguments) option.
```js
if (isWindows) {
await execa({windowsVerbatimArguments: true})`wsl ...`;
}
```
## Console window
If the [`windowsHide`](api.md#optionswindowshide) option is `false`, the subprocess is run in a new console window. This is necessary to make [`SIGINT` work](https://github.com/nodejs/node/issues/29837) on Windows, and to [clean up](termination.md#current-process-exit) subprocesses which spawn their own subprocesses, such as when [running an npm script through a shell](https://github.com/sindresorhus/execa/issues/433).
## UID and GID
By default, subprocesses are run using the current [user](https://en.wikipedia.org/wiki/User_identifier) and [group](https://en.wikipedia.org/wiki/Group_identifier). The [`uid`](api.md#optionsuid) and [`gid`](api.md#optionsgid) 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](bash.md)\
[**Previous**: 🐛 Debugging](debugging.md)\
[**Top**: Table of contents](../readme.md#documentation)