cross-env
Cross-platform CLI for setting environment variables in npm scripts without worrying about Windows vs POSIX syntax.
Repository Health
Technical Analysis
cross-env solves a specific, annoying cross-platform problem: Windows command prompts choke on NODE_ENV=production node script.js-style variable assignment, and Windows uses %VAR% where POSIX shells use $VAR. Rather than maintaining separate win and posix npm scripts, or wrapping every script in a shell-detection hack, cross-env lets you write a single command that works identically everywhere.
It ships as a tiny CLI (cross-env and cross-env-shell) that parses KEY=value pairs off the front of a command, builds the right environment, and then hands the rest of the command off to cross-spawn for execution — translating $VAR/${VAR} references and PATH-style list delimiters to their Windows equivalents when needed. The maintainers consider the feature set complete: the README explicitly states cross-env is “done” and isn’t accepting new features, only maintenance.
What You Get
- A single
cross-envbinary that prefixes any command, parsing leadingKEY=valueassignments before spawning the real process - A
cross-env-shellvariant that runs the command through a shell, useful when the underlying script itself needs$VARsubstitution - Automatic
$VAR/${VAR}to%VAR%conversion so command bodies work undercmd.exewithout rewriting them - Bash-style default-value expansion (
${VAR:-default}) resolved before the command runs - PATH-like list-delimiter translation (
:to;) for whitelisted variables such asPATHandNODE_PATH - Correct signal forwarding (SIGTERM/SIGINT/SIGBREAK/SIGHUP) and exit-code propagation from the spawned child process
Common Use Cases
- Setting
NODE_ENV=production(or any other var) in apackage.jsonbuild/start script that has to run on both CI (Linux) and Windows developer machines - Chaining a variable-setting script into a downstream script via
cross-env-shellso the child script can still use$VARsyntax - Passing multiple environment variables to a single command without per-OS branching logic
- Normalizing PATH-style variables that use OS-specific list separators inside a script
Under The Hood
Architecture
cross-env is intentionally small and linear: src/bin/cross-env.ts and src/bin/cross-env-shell.ts are one-line entry points that call the single exported crossEnv() function in src/index.ts with process.argv. crossEnv() does all the real work in three phases — parseCommand() walks the argument list with a regex (envSetterRegex) to split leading KEY=value assignments from the actual command and its arguments (including careful handling of escaped quotes), getEnvVars() builds the child environment by running each assignment’s value through varValueConvert(), and the resulting command/args/env triple is handed to cross-spawn’s spawn() with stdio: 'inherit'. Platform-specific string rewriting is isolated in two small modules, command.ts (converts $VAR references and normalizes paths for Windows) and variable.ts (converts value-level $VAR references and PATH-style delimiters), both gated by the single isWindows() check in is-windows.ts. Nothing else in the codebase branches on platform, so the Windows/POSIX difference is fully contained to those two files.
Tech Stack
The project is plain TypeScript (type: module, ES modules only, no CommonJS build) with a single runtime dependency, cross-spawn, used for its more reliable cross-platform child-process spawning versus Node’s built-in child_process.spawn. It builds with zshy (a thin TypeScript-to-dual-output bundler), type-checks with tsc --noEmit, and targets Node.js 20+. Dev tooling is the @epic-web/config shared ESLint/Prettier config, and tests run under Vitest with @vitest/coverage-v8 for coverage and @vitest/ui for interactive runs.
Code Quality
The src/__tests__/ directory has dedicated unit-test files for every module (index, command, variable, is-windows, plus a focused command-default-values suite for the ${VAR:-default} expansion path) totaling roughly 600 lines of test code against ~250 lines of source — a high test-to-source ratio for a project this size. A separate e2e/ directory runs the built CLI end-to-end via plain Node scripts. CI (.github/workflows/validate.yml) runs the full validate script — build, typecheck, lint, format check, and test — and a second workflow auto-formats on push. Error handling is minimal but intentional (e.g. parseCommand throws a clear Error('Command is required') when no command is given); the small surface area means there’s little room for swallowed errors.
What Makes It Unique
cross-env doesn’t try to be a general shell-compatibility layer — it solves exactly one problem (environment variable assignment syntax differing between POSIX and Windows shells) and stops there, which is why the maintainers call it feature-complete. Its narrow scope is the differentiator: alternatives that try to emulate a full POSIX shell on Windows are heavier and slower, while cross-env’s regex-based rewriting of just the variable-reference syntax keeps it a near-zero-overhead prefix to any existing script.
Used by 118 apps in this directory
authentik
Authentication · Security
The self-hosted Identity Provider that replaces Okta, Auth0, and Entra ID with a unified SSO platform supporting SAML, OAuth2/OIDC, LDAP, RADIUS, and WebAuthn.
AutoGPT
AI Assistants · Automation · Productivity
Build, deploy, and run autonomous AI agents that automate complex multi-step workflows using a visual block-based graph editor.
Banana Slides
AI Design Tools · Productivity
AI-native PPT generator with Vibe editing, multi-LLM support, and fully editable PPTX export
Bigcapital
Invoicing Finance
Self-hostable double-entry accounting platform with invoicing, inventory, multi-currency, and real-time financial reporting for small and medium businesses.
Blinko
Knowledge Management · Note Taking
A self-hosted, AI-powered card note-taking tool that lets you capture fleeting thoughts instantly and retrieve them with natural language search.
browserless
Automation · Developer Tools
Run headless Chrome, Firefox, and WebKit as a managed Docker service — drop-in Puppeteer and Playwright support with no infrastructure overhead.
Bugsink
Developer Tools · Monitoring
Self-hosted error tracking that accepts Sentry SDKs out of the box, so you keep your instrumentation and drop the monthly bill.
Cap
Team Chat · Video Conferencing
Open source Loom alternative with GPU-accelerated recording, instant share links, AI summaries, and full self-hosting via Docker Compose.
Cherry Studio
AI Assistants
All-in-one AI desktop client with 300+ assistants and multi-model support