Skip to content
Eugene Lazutkin edited this page Feb 20, 2026 · 9 revisions

$ is a set of helper functions to run OS-specific commands and/or use them in stream pipelines.

This function is similar to $$ but it uses different default spawn options related to streams and different (simpler) return values.

Usage

import $ from 'dollar-shell';

// or:
// import {$} from 'dollar-shell';

Docs

The TypeScript declaration:

interface DollarResult {
  code: number | null;
  signal: string | null;
  killed: boolean;
}

interface DuplexPair<R = any> {
  readable: ReadableStream<R>;
  writable: WritableStream<R>;
}

interface DollarImpl<R = any> extends Dollar<Promise<DollarResult>> {
  from: Dollar<ReadableStream<R>>;
  to: Dollar<WritableStream<R>>;
  through: Dollar<DuplexPair<R>>;
  io: Dollar<DuplexPair<R>>;
}

declare const $: DollarImpl;

Dollar is defined in $$.

The API is:

  • $ — all streams are ignored. It returns a promise that resolves to an object with the following properties:
    • code — the exit code of the process. See spawn()'s exitCode above for more details.
    • signal — the signal code of the process. See spawn()'s signalCode above for more details.
    • killed — a boolean. It is true when the process has been killed and false otherwise. See spawn()'s killed above for more details.
  • $.from — sets stdout to pipe and returns stdout of the process. It can be used to process the output. See spawn()'s stdout above for more details.
  • $.to — sets stdin to pipe and returns stdin of the process. It can be used to pipe the input. See spawn()'s stdin above for more details.
  • $.io AKA $.through — sets stdin and stdout to pipe and returns stdin and stdout of the process as a {readable, writable} pair. It can be used to create a pipeline where an external process can be used as a transform step.

Just like $$ all $ functions support two signatures: they can be used as tag functions spawning processes with default spawn options, or they can take an options object and produce a tag function.

When $ function is used to update defaults it still copies its own properties to the new object unchanged:

const $custom = $({stdout: 'inherit', stderr: 'inherit'});

const result = await $custom`ls -l .`;

typeof $custom.from === 'function';
typeof $custom.to === 'function';
typeof $custom.through === 'function';
typeof $custom.io === 'function';my-util --foo --bar ${'b a z'}

Examples

A pipeline from ls -l to grep LICENSE to wc to tee output.txt:

import $ from 'dollar-shell';
import chain from 'stream-chain';

chain([
  $.from`ls -l .`,
  $.io`grep LICENSE`,
  $.io`wc`,
  $.to({stdout: 'inherit'})`tee output.txt`
]);

A combined pipeline:

import $ from 'dollar-shell';
import chain from 'stream-chain';
import lines from 'stream-json/utils/lines.js';

chain([
  $.from`ls -l .`,
  new TextDecoderStream(),
  lines(),
  line => console.log(line)
]);

Just run a command with default spawn options:

import $ from 'dollar-shell';

const result = await $`my-util --foo --bar ${'b a z'}`;

if (result.code || result.signal) {
  console.error(
    'Process exited with code',
    result.code,
    'or signal',
    result.signal
  );
}
if (result.killed) {
  console.error('Process was killed');
}

Clone this wiki locally