npm Script Fails on Shell Differences - Fix POSIX vs Windows in CI
npm runs scripts through a shell, and that shell differs by platform. A script using POSIX FOO=bar cmd inline env syntax works on Linux/macOS but breaks on a Windows runner’s default shell.
What this error means
A script that sets an env var inline (e.g. NODE_ENV=production webpack) passes on Linux CI but fails on a Windows runner with the variable "not recognized" or treated as a command. The reverse can happen with Windows-specific syntax on Linux.
> app@1.0.0 build
> NODE_ENV=production webpack
'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.
npm error code 1Common causes
Inline POSIX env syntax on a non-POSIX shell
FOO=bar cmd is POSIX shell syntax. The default Windows shell does not understand it, so it treats NODE_ENV=... as a command and fails.
Shell operators that differ by platform
Quoting, path separators, and some operators behave differently across shells, so a script tuned for one platform breaks on another in a matrix build.
How to fix it
Set env vars cross-platform
Use cross-env (or the tool’s own config) so env vars work on every runner.
npm install --save-dev cross-env
// package.json
"scripts": {
"build": "cross-env NODE_ENV=production webpack"
}Avoid platform-specific shell features
- Prefer Node-based scripts over shell one-liners for cross-platform steps.
- Pin the shell in CI (e.g. set
shell: bashon Windows runners) if you must use POSIX syntax. - Keep path separators and quoting portable, or compute them in a Node script.
How to prevent it
- Use cross-env for inline env vars in package.json scripts.
- Prefer portable Node scripts over shell-specific one-liners.
- Pin the shell explicitly in cross-platform CI matrices.