Skip to main content
Deno 2 is finally here ๐ŸŽ‰๏ธ
Learn more

BAZX

๐Ÿš๏ธ zx on ๐Ÿ’Š๏ธ steroids

asciicast

Main differences with ZX

  • Written from scratch
  • 0 dependencies by default
  • Plateform-agnostic (not limited to Deno or NodeJS)
  • Extensible (enables remote command execution and thus browser support)
  • Streams at the core for better performances (no streaming support with zx)
  • Tree-shakable (usefull for bundling)
  • Modern (TypeScript, Deno, ES2020)
  • MIT vs Apache license
  • Library only

Streams

Unlike zx, bazx doesnโ€™t gather outputs into possibly big strings by default. The main reason for that is to avoid out of memory, especially on embedded devices and with โ€œloudโ€ commands (for instance, await $`yes`; with zx will crash the process, but not with bazx).

Support

  • Deno: ๐Ÿฅ๏ธ (working)
  • NodeJS: ๐Ÿฅš๏ธ (not started yet)
  • QuickJS: ๐Ÿฅš๏ธ (not started yet)
  • Browser: ๐Ÿฅš๏ธ (not started yet)

Setup

Deno

import { $ } from 'https://deno.land/x/bazx/mod.ts';

As of now, only the --allow-run command is required at runtime.

(Bring Your Own Runtime)

import { create } from 'https://deno.land/x/bazx/index.ts'; // `index.ts` is isomorphic, `mod.ts` is Deno only

const $ = create({
  exec(
    cmd: [string, ...string[]],
    streams: {
      stdin: ReadableStream<Uint8Array>,
      stdout: WritableStream<Uint8Array>,
      stderr: WritableStream<Uint8Array>
    }
  ): PromiseLike<{ success: boolean, code: number }> {
    // Insert runtime-dependant code here
  }
}, { /* Default options */ });

Usage

See the test folder

The $ tagged template function

Prepare a command. The process will spawn only when the returned object will be awaited (then called). The returned object as stdin, stdout and stderr properties, that are streams the user can use to communicated with the process. Also, it is possible to call the pipe(cmdOrTransfertStream: NativeCommand | PipeCommand | TransformStream) function to pipe the this command into the provided cmdOrTransfertStream stream, or to stdin stream of the provided command.

$`echo Never called`; // (never executed - missing `await`)

await $`echo Hi!`; // $ echo Hi!

const cmd = $`echo Only invoked once`;
(await cmd) === (await cmd); // => true

await $`env`.pipe($`grep PATH`); // $ env | grep PATH

The $ function can be obtained using the create function, or from a third party module that wrap this function. For instance, the deno.ts module expose a createDeno function, which is a wrapper function around create.

See test/debug.js for a pratical overview.

stdout, stderr and collect exports

Utilities to read respectively stdout, stderr and both from the command passed as argument:

console.log(await stdout($`echo Hello world!`));

// => { success: true, code: 0, stdout: "Hello world!" }

WIP

This project is work in progress for now; bugs and API change are expected.

Please fill an issue for any bug you encounter and open a discussion for any question or enhancement. :wink:

TODO

  • Rollup for NodeJS and browser builds
  • Improve docs
  • Add more runtime support (NodeJS at least)
  • Fix bugs (some complex use case doesnโ€™t work yet)

FAQ

Why is it called bazx?

Just like bash built from sh, there should be a bazx built from zx ๐Ÿ˜๏ธ

How do you prononce bazx?

Just like basic but with a x instead of a c at the end: basix

License

Inspired by zx

MIT License

Copyright 2021 Minigugus