class Process
implements Closer

Wrapper for Deno.ChildProcess with enhanced error handling and stream management.

This class provides a lower-level interface than run. It converts streams to AsyncIterables, handles errors properly, and manages resource cleanup automatically.

Most users should use run instead, which provides a simpler, more composable API. Use Process directly only when you need fine-grained control over process lifecycle.

Why this is better than Deno.Command:

  • Automatic resource cleanup (no leaked processes)
  • Proper error propagation from stderr
  • AsyncIterable streams (easier to work with)
  • Custom error handlers
  • Buffered input option for performance

Examples

Basic process execution

import { Process, enumerate } from "jsr:@j50n/proc";

const proc = new Process(
  { stdout: "piped", stdin: "null", stderr: "inherit" },
  "echo",
  ["hello"]
);

for await (const chunk of proc.stdout) {
  console.log(new TextDecoder().decode(chunk));
}

Custom error handling

import { Process, ExitCodeError } from "jsr:@j50n/proc";

const proc = new Process(
  {
    stdout: "piped",
    stdin: "null",
    stderr: "inherit",
    fnError: (error) => {
      if (error instanceof ExitCodeError && error.code === 1) {
        // Suppress expected error
        return;
      }
      throw error;
    }
  },
  "sh",
  ["-c", "exit 1"]
);

Constructors

new
Process(
cmd: string | URL,
args: readonly string[],
)

Constructor.

Type Parameters

Properties

private
_isClosed: boolean
private
_passError: Error | undefined
private
_stderr: AsyncIterable<Uint8Array> | undefined
private
_stdin: WritableIterable<
Uint8Array
| Uint8Array[]
| string
| string[]
> | undefined
private
_stdout: AsyncIterable<Uint8Array> | undefined
readonly
id: `${string}-${string}-${string}-${string}-${string}`
readonly
isClosed: boolean

Indicates close has been called.

readonly
pid: number

Process PID.

The wrapped process.

readonly
status: Promise<Deno.CommandStatus>

Process status.

readonly
stderr: AsyncIterable<Uint8Array>

stderr of the process.

private
stderrResult: Promise<S> | undefined
readonly
stdin: Writable<
Uint8Array
| Uint8Array[]
| string
| string[]
>

stdin as a WritableIterable.

This property is here to make the interface philosophically compatible with stdin of the wrapped process, but uses a mechanism that JavaScript does not optimize very well. Recommend using writeToStdin instead if that is possible.

readonly
stdout: AsyncIterable<Uint8Array>

stdout of the process.

Methods

close(): Promise<void>

Do all necessary normal steps to close the process. This does not kill the process but attempts a normal close.

writeToStdin(iter: AsyncIterable<
Uint8Array
| Uint8Array[]
| string
| string[]
>
): Promise<void>

This is the "backdoor" way to write directly to the underlying process stdin without the overhead of a WritableIterable. Use instead of stdin for streamed data.

stdin is the way to go if you are passing ad-hoc, non-continuous data to process stdin. However, it adds a substantial amount of overhead, and it is very slow for processing small data. Using this function instead of stdin greatly improves performance where small data is a factor.