A tool for writing better scripts by bridging JavaScript and shell commands with cross-platform wrappers around child_process
npx @tessl/cli install tessl/npm-zx@8.8.0ZX provides useful cross-platform wrappers around Node.js child_process, enabling developers to write more complex automation scripts with the convenience of JavaScript while maintaining direct access to shell operations. It bridges JavaScript and shell commands with automatic argument escaping, sensible defaults, and Promise-based asynchronous execution.
npm install zximport { $ } from "zx";For CommonJS:
const { $ } = require("zx");For global script usage:
import "zx/globals";
// Now $ and all other functions are available globallyimport { $, echo, sleep } from "zx";
// Execute shell commands
const result = await $`echo "Hello World"`;
echo`Server response: ${result}`;
// With configuration
const output = await $({ quiet: true })`git status`;
// Concurrent execution
await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
]);
// Safe argument handling
const name = 'foo bar';
await $`mkdir /tmp/${name}`;ZX is built around several key components:
$ function for executing shell commands with configuration optionsProcessPromise and ProcessOutput classes for handling command execution and resultsCore shell command execution with the $ function, process management, and output handling.
interface Shell<S = false, R = S extends true ? ProcessOutput : ProcessPromise> {
(pieces: TemplateStringsArray, ...args: any[]): R;
<O extends Partial<Options>>(opts: O): Shell;
sync: Shell<true>;
}
type $ = Shell & Options;
declare const $: $;Advanced process control including promises, output handling, piping, and process lifecycle management.
class ProcessPromise extends Promise<ProcessOutput> {
run(): this;
kill(signal?: NodeJS.Signals): Promise<void>;
abort(reason?: string): void;
nothrow(v?: boolean): this;
quiet(v?: boolean): this;
verbose(v?: boolean): this;
timeout(d?: Duration, signal?: NodeJS.Signals): this;
get pid(): number | undefined;
get exitCode(): Promise<number | null>;
get stdin(): Writable;
get stdout(): Readable;
get stderr(): Readable;
json<T = any>(): Promise<T>;
text(encoding?: Encoding): Promise<string>;
lines(delimiter?: string | RegExp): Promise<string[]>;
buffer(): Promise<Buffer>;
blob(type?: string): Promise<Blob>;
}
class ProcessOutput extends Error {
readonly exitCode: number | null;
readonly signal: NodeJS.Signals | null;
readonly stdout: string;
readonly stderr: string;
readonly stdall: string;
readonly duration: number;
readonly ok: boolean;
json<T = any>(): T;
text(encoding?: Encoding): string;
lines(delimiter?: string | RegExp): string[];
buffer(): Buffer;
blob(type?: string): Blob;
}File and directory manipulation utilities for temporary files, directory navigation, and file system operations.
function tempdir(prefix?: string, mode?: Mode): string;
function tempfile(name?: string, data?: string | Buffer, mode?: Mode): string;
function cd(dir: string | ProcessOutput): void;
// Re-exports
export { default as path } from "node:path";
export * as os from "node:os";
export { fs } from "./vendor";Interactive utilities for user input, output formatting, and visual feedback.
function echo(...args: any[]): void;
function question(
query?: string,
options?: {
choices?: string[];
input?: NodeJS.ReadStream;
output?: NodeJS.WriteStream;
}
): Promise<string>;
function stdin(stream?: Readable): Promise<string>;
function spinner<T>(title: string, callback: () => T): Promise<T>;HTTP operations with fetch API and piping support for data streaming.
function fetch(
url: RequestInfo,
init?: RequestInit
): Promise<Response> & {
pipe: {
(dest: TemplateStringsArray, ...args: any[]): ProcessPromise;
<D>(dest: D): D;
};
};General-purpose utilities for common scripting tasks including argument parsing, retry logic, and async utilities.
function sleep(duration: Duration): Promise<void>;
function retry<T>(count: number, callback: () => T): Promise<T>;
function retry<T>(
count: number,
duration: Duration | Generator<number>,
callback: () => T
): Promise<T>;
function expBackoff(max?: Duration, delay?: Duration): Generator<number>;
function parseArgv(
args?: string[],
opts?: ArgvOpts,
defs?: Record<string, any>
): minimist.ParsedArgs;
declare const argv: minimist.ParsedArgs;Command line interface specific functionality available from zx/cli import.
function transformMarkdown(content: string): string;Access to package version and dependency information.
declare const VERSION: string;
declare const version: string;
declare const versions: Record<string, string>;interface Options {
cwd?: string;
env?: NodeJS.ProcessEnv;
shell?: string | true;
stdio?: StdioOptions;
verbose?: boolean;
quiet?: boolean;
nothrow?: boolean;
timeout?: Duration;
timeoutSignal?: NodeJS.Signals;
killSignal?: NodeJS.Signals;
prefix?: string;
postfix?: string;
detached?: boolean;
preferLocal?: boolean | string | string[];
sync?: boolean;
input?: string | Buffer | Readable | ProcessOutput | ProcessPromise;
signal?: AbortSignal;
ac?: AbortController;
}
type Duration = string | number;
interface ArgvOpts extends minimist.Opts {
camelCase?: boolean;
parseBoolean?: boolean;
}
/**
* Chalk instance for terminal string styling
*/
interface ChalkInstance {
(text: string): string;
// Color functions
black: ChalkInstance;
red: ChalkInstance;
green: ChalkInstance;
yellow: ChalkInstance;
blue: ChalkInstance;
magenta: ChalkInstance;
cyan: ChalkInstance;
white: ChalkInstance;
gray: ChalkInstance;
// Style functions
bold: ChalkInstance;
dim: ChalkInstance;
italic: ChalkInstance;
underline: ChalkInstance;
strikethrough: ChalkInstance;
// Background colors
bgBlack: ChalkInstance;
bgRed: ChalkInstance;
bgGreen: ChalkInstance;
bgYellow: ChalkInstance;
bgBlue: ChalkInstance;
bgMagenta: ChalkInstance;
bgCyan: ChalkInstance;
bgWhite: ChalkInstance;
}
/**
* YAML parsing and serialization interface
*/
interface YAML {
parse(text: string): any;
stringify(object: any): string;
}
/**
* Glob options for file pattern matching
*/
interface GlobbyOptions {
absolute?: boolean;
baseNameMatch?: boolean;
braceExpansion?: boolean;
caseSensitiveMatch?: boolean;
concurrency?: number;
cwd?: string;
deep?: number;
dot?: boolean;
expandDirectories?: boolean;
extglob?: boolean;
followSymbolicLinks?: boolean;
gitignore?: boolean;
globstar?: boolean;
ignore?: string[];
markDirectories?: boolean;
objectMode?: boolean;
onlyDirectories?: boolean;
onlyFiles?: boolean;
stats?: boolean;
suppressErrors?: boolean;
throwErrorOnBrokenSymbolicLink?: boolean;
unique?: boolean;
}
/**
* HTTP request types
*/
type RequestInfo = string | URL;
interface RequestInit {
method?: string;
headers?: HeadersInit;
body?: BodyInit | null;
signal?: AbortSignal;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
mode?: RequestMode;
credentials?: RequestCredentials;
cache?: RequestCache;
integrity?: string;
keepalive?: boolean;
window?: any;
}