Unix utilities, in one Rust binary.

A BusyBox-style multi-call binary in Rust — 78 Unix utilities, one ~2 MB executable, native on Linux, Windows, and macOS. Functional port of Real-Fruit-Snacks/mainsail with verified parity.

jib
$ jib seq 100 | jib sort -rn | jib head -3
100
99
98

$ jib find . -name '*.rs' -size +1k -mtime -7
./src/applets/sed.rs
./src/applets/awk.rs
./src/applets/jq.rs

$ jib tar -czf src.tgz src/
$ jib sha256sum src.tgz
d4f2a8b1c3e7… *src.tgz
0
Applets
0
Parity Tests
0
Binary
0
Targets
0
Runtime

Everything you reach for, in one place

A familiar POSIX surface. Real flag coverage, not stubs. Same behavior on Windows, macOS, and Linux — and the same bytes the Python original produces.

One Binary, 78 Utilities

Every common shell tool dispatched through a single executable — POSIX coreutils plus jq, http, dig, nc, archives, hashing, and the BusyBox parity gap-fillers. Symlink it as cat, ls, grep and the multi-call dispatcher takes over.

$ jib --list | wc -l
78
$ ln -s jib cat && ./cat README.md
2MB
Native Binary

Native Windows

Runs on bare Windows — no WSL, no Cygwin, no git-bash. Recognizes dir, type, copy, del, where as native aliases.

Real Applets

find with -exec, -prune, parens, boolean ops. sed with addresses and in-place edit. awk with BEGIN/END, patterns, arrays, gsub. jq with pipes, select, map, 20+ built-ins.

Pipeline-Grade I/O

Binary-safe through cat/tee/gzip. tail -f with rotation detection. xargs -0 for paths with backslashes.

76
Parity Cases

Verified Parity

The tests/parity harness runs both this binary and the Python original against the same fixtures and asserts byte-for-byte equality of stdout and exit codes. Behavior drift gets caught the next time CI runs — no manual cross-checking.

$ python tests/parity/run.py
76/76 matched (0 skipped)

Hackable

One Rust file per applet — most are 100–300 lines. Add a new one by dropping a module under src/applets/ exposing pub const APPLET: Applet and an entry in the registry's ALL slice.

Cargo Features

Pick exactly the surface you ship. --features slim drops engines and archives down to 34 POSIX coreutils — a 545 KB binary. Or compose "slim,hashing,archives" à la carte.

Six Native Targets

Linux × x86_64 / ARM64 (glibc), Windows × x86_64 / ARM64, macOS ARM64, plus a separate musl-linked Linux x64 binary — runs on Alpine, distroless containers, and any musl-libc Linux.

All 78, organized

Each applet implements common POSIX flags. Run jib <applet> --help for per-applet usage. The markers flag known parity gaps tracked in PARITY.md.

File operations
lsdir
cpcopy
mvmove
rmdel
mkdirmd
touch
find
chmod
ln
stat
truncate
mktemp
dd
Text processing
cattype
tac
rev
grep
head
tail
wc
nl
sort
uniq
cut
paste
tr
sed
awk
tee
xargs
printf
echo
expand
unexpand
split
cmp
comm
diff
join
fmt
fold
column
od
hexdump
base64
JSON & data
jq
Network
http
dig
nc
Hashing & integrity
md5sum
sha1sum
sha256sum
sha512sum
Archives
tar
gzip
gunzip
zip
unzip
Filesystem & paths
du
df
basename
dirname
realpath
pwd
whichwhere
System & control
uname
hostname
whoami
id
groups
date
env
sleep
getopt
true
false
yes
seq

Four-layer dispatch

Same shape as the Python original — clean separation between entry point, dispatch logic, applet registry, and per-applet implementations. Adding an applet means dropping one file.

1

Entry

main.rs collects env::args and hands them to cli::run. The exit code is clamped to a u8 ExitCode.

2

Dispatch

cli.rs resolves the applet from argv[0]'s lowercased stem (multi-call) or argv[1] (subcommand). Intercepts --help only — -h stays free for applet flags like df -h.

3

Registry

registry.rs builds a BTreeMap<&str, &'static Applet> once via OnceLock, indexing every canonical name and alias.

4

Applets

78 modules in src/applets/, ranging from ~10 lines (true) to ~1100 (awk). Read bytes via io::stdin().lock(); write via io::stdout().lock(). Return 0 / 1 / 2 (success / runtime / usage).

Install or build

Pre-built binaries on the releases page. Build from source for the slim feature set or to add applets.

install.sh
# From a release
$ curl -LO https://github.com/Real-Fruit-Snacks/jib/\
       releases/latest/download/jib-linux-x64
$ chmod +x jib-linux-x64
$ ./jib-linux-x64 --version
jib 0.1.0

# From source — Rust 1.75+
$ git clone https://github.com/Real-Fruit-Snacks/jib.git
$ cd jib && cargo build --release
→ target/release/jib (~2 MB)

# Slim build — POSIX coreutils only, no engines/archives
$ cargo build --release \
    --no-default-features --features slim
→ 545 KB, 34 applets

# Custom à la carte
$ cargo build --release \
    --no-default-features --features "slim,hashing"
usage.sh
# Daily pipelines (find + awk + jq, all in one binary)
$ jib find . -name '*.rs' -mtime -7
$ jib awk -F, '{s+=$3} END{print s/NR}' data.csv

# jq subset
$ jib jq '.servers[] | select(.region) | .name' inv.json

# DNS without dig installed
$ jib dig MX gmail.com +short

# Cross-platform integrity
$ echo -n abc | jib sha256sum
ba7816bf8f01cfea414140de5dae2223…

# Verify parity against the Python original
$ python tests/parity/run.py
76/76 matched (0 skipped)