Introduction
zx is a tool from Google that makes writing shell scripts in JavaScript painless. It provides useful wrappers around child_process, adds built-in support for template literal shell commands, and bundles common utilities so you can replace Bash scripts with type-safe, cross-platform JavaScript.
What zx Does
- Executes shell commands via tagged template literals using the
$function - Bundles globby, chalk, fs-extra, fetch, and YAML parsing out of the box
- Supports top-level await and runs .mjs files directly
- Provides pipe operators and stdin/stdout stream handling between commands
- Offers a REPL mode for interactive shell scripting in JavaScript
Architecture Overview
zx wraps Node.js child_process.spawn under the hood, parsing tagged template literals into shell commands that are executed in a spawned process. Each $ call returns a ProcessPromise that resolves with stdout and stderr. Pipes are chained by connecting the stdout stream of one process to the stdin of another, all managed through native Node.js streams.
Self-Hosting & Configuration
- Install globally with
npm install -g zxor per-project withnpm install zx - Scripts use the
.mjsextension for native ES module support - Set
$.shellto change the default shell (e.g.,/bin/bash,powershell.exe) - Use
$.verbose = falseto suppress command echoing in production scripts - Configure
$.cwdto set the working directory for all subsequent commands
Key Features
- Tagged template literal syntax for shell commands with automatic escaping
- Built-in utilities: chalk for colors, globby for globs, fetch for HTTP
- Cross-platform execution works on Linux, macOS, and Windows
- TypeScript support with full type definitions included
- Markdown script support: write scripts inside fenced code blocks in .md files
Comparison with Similar Tools
- ShellJS — synchronous, older API; zx is async-first with modern ES module syntax
- Execa — focused on process execution; zx adds shell scripting ergonomics and built-in utilities
- Bash — not cross-platform and lacks type safety; zx runs on any OS with Node.js
- Bun Shell — Bun-specific; zx works with any Node.js runtime
- ts-node scripts — requires more boilerplate; zx scripts are concise and run directly
FAQ
Q: Can I use TypeScript with zx? A: Yes. zx supports .ts files natively and ships with TypeScript definitions.
Q: Does zx handle errors like set -e in Bash? A: Yes. By default, a non-zero exit code throws a ProcessOutput error that you can catch with try/catch.
Q: Can I use zx without installing it globally?
A: Yes. Use npx zx script.mjs to run scripts without global installation.
Q: Is zx suitable for production automation? A: Yes. It is widely used for CI/CD scripts, build automation, and DevOps tooling where JavaScript is preferred over Bash.