npm Scripts - Environment Variable Not Expanding (Cross-Platform) in CI
npm scripts run in a shell, and variable-expansion syntax differs between shells/OSes. A script that sets or reads a variable with the wrong syntax ends up with the literal token instead of its value.
What this error means
A build behaves as if an env var is unset, or logs show a literal $VAR/%VAR%. Often the script sets NODE_ENV=production cmd (works on POSIX) but runs on Windows, or uses $VAR where the shell does not expand it.
> 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.Common causes
POSIX inline env syntax on Windows
VAR=value cmd is POSIX shell syntax. On Windows cmd it is not understood, so the variable is not set and the command errors or runs without it.
Wrong expansion token for the shell
Using %VAR% in bash or $VAR in cmd yields the literal text because each shell expands differently.
How to fix it
Set env vars cross-platform with cross-env
Use cross-env so the same script works on every OS.
// package.json
"scripts": {
"build": "cross-env NODE_ENV=production webpack"
}Standardize the CI shell
- Pin a single shell in CI (e.g. bash) so expansion is predictable.
- Pass values via the job
env:block instead of inline shell syntax where possible. - Avoid mixing
%VAR%and$VARstyles in scripts.
How to prevent it
- Use cross-env for inline env vars in package scripts.
- Set a consistent CI shell.
- Prefer the workflow env block over shell-specific syntax.