From source

May 5, 2026 · View on GitHub

 ███████╗███████╗██╗  ██╗██████╗ ███████╗
 ╚══███╔╝██╔════╝██║  ██║██╔══██╗██╔════╝
   ███╔╝ ███████╗███████║██████╔╝███████╗
  ███╔╝  ╚════██║██╔══██║██╔══██╗╚════█��║
 ███████╗███████║██║  ██║██║  ██║███████║
 ╚══════╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝

CI Crates.io Downloads Docs.rs Docs License: MIT

[THE FIRST COMPILED UNIX SHELL]

"No fork, no problems."

[PATENT PENDING]

The first Unix shell to compile to bytecodes and execute on a purpose-built virtual machine with fused superinstructions. Since the Bourne shell at Bell Labs in 1970, every Unix shell has been an interpreter. zshrs is the first to be a compiler. A drop-in zsh replacement written in Rust — 190k+ lines, 267 source files, 80 core modules, 100% ZLE widget coverage (193/193 entries from zsh's Src/Zle/iwidgets.list — history navigation, vi find/repeat/marks, undo/redo, isearch, yank-pop, shell-aware word motion, region/visual mode, text objects, completion menu, $zle_highlight parsing), 48 fish-ported builtins, persistent worker pool, AOP intercept, rkyv-backed bytecode images (mmap hot path; the only shell bytecode cache), read-only SQLite mirrors beside them for dbview / SQL inspection only (no cache semantics), and full zsh compatibility.

Docs · Reference · Coverage Report · strykelang · fusevm · compsys


Table of Contents


[0x00] OVERVIEW

zshrs replaces fork + exec with a persistent worker thread pool, compiles every command to fusevm bytecodes, and persists compiled chunks only in rkyv shards under ~/.zshrs/images/ (single-directory rule — every zshrs file lives under $ZSHRS_HOME / ~/.zshrs/; see docs/DAEMON.md). Beside that tree, catalog.db and related SQL views are read-only mirrors for inspection (dbview, ad-hoc SQL): daemon-hydrated, never authoritative for cache hit/miss or execution. They are not a second shell cache. history.db holds history only — it is unrelated to bytecode caching. The result: shell startup, command dispatch, globbing, completion, and autoloading are all faster by orders of magnitude.


[0x01] INSTALL

# From crates.io
cargo install zshrs

# From source — lean build, pure shell, no stryke dependency
git clone https://github.com/MenkeTechnologies/zshrs
cd zshrs && cargo build --release
# binary: target/release/zshrs

# Set as login shell
sudo sh -c 'echo ~/.cargo/bin/zshrs >> /etc/shells'
chsh -s ~/.cargo/bin/zshrs

[0x02] NO-FORK ARCHITECTURE

Every operation that zsh forks for runs in-process. Zero forks for builtins.

Operationzshzshrs
$(cmd)fork + pipeIn-process stdout capture via dup2
<(cmd) / >(cmd)fork + FIFOWorker pool thread + FIFO
cat filefork + exec /bin/catBuiltin — zero fork
head/tail/wcfork + execBuiltin — zero fork
sort/find/uniqfork + execBuiltin — zero fork
date/hostname/unamefork + execBuiltin — direct syscall
sleep/mktemp/touchfork + execBuiltin — zero fork
xattr operationsfork + exec xattrDirect syscall — zero fork
pmap/pgrep/peachfork N timesVM execution — zero fork
**/*.rsSingle-threaded opendirParallel walkdir per-subdir on pool
*(.x) qualifiersN serial stat callsOne parallel metadata prefetch
rehashSerial readdir per PATH dirParallel scan across pool
compinitSynchronous fpath scanBackground scan + bytecode compilation
History writeSynchronous fsyncFire-and-forget to pool
AutoloadRead file + parse every timeBytecode mmap + zero-copy load from rkyv
Plugin sourceParse + execute every startupDelta replay from rkyv image

Coreutils Builtins (Anti-Fork)

23 coreutils commands run in-process with zero fork overhead:

cat  head  tail  wc  sort  find  uniq  cut  tr  seq  rev  tee
basename  dirname  touch  realpath  sleep  whoami  id  hostname
uname  date  mktemp

Speedup: 2000-5000x per invocation (2-5ms fork overhead → 0.001ms builtin call).


[0x03] BYTECODE COMPILATION

Every command compiles to fusevm bytecodes via a faithful port of zsh's lexer + parser:

Interactive command  ──► ZshLexer ──► ZshParser ──► ZshCompiler ──► fusevm::Op ──► VM::run()
                         (port of    (port of      (original;
                          Src/lex.c)  Src/parse.c)  ~1.4k LOC)
Script file (first)  ──► ZshLexer ──► ZshParser ──► ZshCompiler ──► VM::run() ──► persist rkyv shard
Script file (cached) ──► index.rkyv + mmap shard ──► deserialize Chunk ──► VM::run()
                         (no lex, no parse, no compile)
Autoload function    ──► rkyv shard ──► deserialize Chunk ──► VM::run()
                         (microseconds)

The lexer and parser are direct ports from zsh's C source (Src/lex.c, Src/parse.c); only the bytecode compiler is original Rust. The 4-tier ZshProgram → ZshList → ZshSublist → ZshPipe → ZshCommand AST is preserved verbatim from zsh, ensuring per-construct behavior parity. The bytecode compiler targets the same Op enum that strykelang uses. Both frontends share fused superinstructions, extension dispatch, and the Cranelift JIT path.

Execution Pipeline

┌─────────────────────────────────────────────────────────────────────────┐
│  Script file                                                            │
│       │                                                                 │
│       ▼                                                                 │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │ rkyv bytecode cache (images/*.rkyv + index.rkyv)                 │   │
│  │   lookup(path, mtime) → mmap'd fusevm::Chunk                     │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│       │                                                                 │
│       ├─── HIT (100x faster) ────────────────────────┐                 │
│       │                                               │                 │
│       ▼ MISS                                          ▼                 │
│  ZshLexer → ZshParser → ZshCompiler ────────► fusevm::Chunk            │
│                         │                             │                 │
│                         ▼                             │                 │
│                  persist_shard()                      │                 │
│                                                       │                 │
│       ┌───────────────────────────────────────────────┘                │
│       ▼                                                                 │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                    fusevm::VM::run()                            │   │
│  │                                                                 │   │
│  │  ┌───────────────────────────────────────────────────────────┐ │   │
│  │  │ JIT eligibility check                                     │ │   │
│  │  └───────────────────────────────────────────────────────────┘ │   │
│  │       │                                                         │   │
│  │       ├─── Block JIT (loops, branches) ──► Cranelift ──► x86-64│   │
│  │       │                                                         │   │
│  │       ├─── Linear JIT (straight-line) ──► Cranelift ──► x86-64 │   │
│  │       │                                                         │   │
│  │       ▼ Fallback                                                │   │
│  │  ┌───────────────────────────────────────────────────────────┐ │   │
│  │  │ Interpreter: jump table dispatch + fused superinstructions│ │   │
│  │  └───────────────────────────────────────────────────────────┘ │   │
│  └─────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘
TierWhatWhen
rkyv image hitSkip lex/parse/compileWarm script runs
Block JITNative x86-64 via CraneliftLoops, conditionals
Linear JITNative x86-64 via CraneliftStraight-line arithmetic
InterpreterJump table + superinstructionsBuiltins, I/O, strings

Benchmark: 100x warm start speedup

Cold (cache miss):  717ms  — lex + parse + compile + cache write + execute
Warm (cache hit):     7ms  — deserialize + execute

[0x04] CONCURRENT PRIMITIVES

Full parallelism in the lean binary. No stryke dependency needed.

# Async/await
id=$(async 'sleep 5; curl https://api.example.com')
result=$(await $id)

# Parallel map — ordered output
pmap 'gzip {}' *.log

# Parallel filter
pgrep 'grep -q TODO {}' **/*.rs

# Parallel for-each — unordered, fire as completed
peach 'convert {} {}.png' *.svg

# Barrier — run all, wait for all
barrier 'npm test' ::: 'cargo test' ::: 'pytest'

[0x05] AOP INTERCEPT

First shell with aspect-oriented programming:

# Before — log every git command
intercept before git { echo "[$(date)] git $INTERCEPT_ARGS" >> ~/git.log }

# After — timing
intercept after '_*' { echo "$INTERCEPT_NAME took ${INTERCEPT_MS}ms" }

# Around — memoize
intercept around expensive_func {
    local cache=/tmp/cache_${INTERCEPT_ARGS// /_}
    if [[ -f $cache ]]; then cat $cache
    else intercept_proceed | tee $cache; fi
}

[0x06] WORKER THREAD POOL

Persistent pool of [2-18] threads. Configurable:

# ~/.zshrs/zshrs.toml  (single-directory rule; configurable via $ZSHRS_HOME)
[worker_pool]
size = 8

[completion]
bytecode_cache = true

[history]
async_writes = true

[glob]
parallel_threshold = 32
recursive_parallel = true

[0x07] RKYV CACHE LAYOUT

Compiled bytecode and plugin/autoload payloads live in rkyv under ~/.zshrs/images/:

PathPurpose
index.rkyvTop-level index: fq_name → shard id, generation, byte offset
images/{hash8}-*.rkyvMmap-ready shards (system, completions, plugins, scripts, .zshrc, …)

SQLite (read-only mirrors) — same directory, different job: daemon-maintained copies you can query with SQL or dbview. They are not the bytecode cache and are not read when deciding cache hit/miss or when running compiled code.

StorePurpose
catalog.dbJoinable mirror of catalog metadata (human / tooling reads only)
history.dbCommand history persistence (orthogonal to bytecode caching — not a cache layer for compiled chunks)
Mirror / FTS viewsOptional SQL-side views of names and paths for dbview — read-only; see docs/DAEMON.md

Browse mirrors without SQL:

dbview                        # list tables + row counts
dbview autoloads _git         # single function: source, body, bytecode status
dbview comps git              # search completions
dbview history docker         # search history

[0x08] EXCLUSIVE BUILTINS

Parallel Primitives (VM-executed, zero fork)

BuiltinDescription
async / awaitShip work to pool, collect result
pmapParallel map with ordered output — runs on VM, not fork
pgrepParallel filter — runs on VM, not fork
peachParallel for-each, unordered — runs on VM, not fork
barrierRun all commands in parallel, wait for all

AOP / Debugging

BuiltinDescription
interceptAOP before/after/around advice on any command
intercept_proceedCall original from around advice
doctorFull diagnostic: pool metrics, cache stats, bytecode coverage
dbviewRead-only browse of SQLite mirrors (not the rkyv cache)
profileIn-process command profiling with nanosecond accuracy

Coreutils (Anti-Fork)

BuiltinDescription
catConcatenate files — no fork
head / tailFirst/last N lines — no fork
wcLine/word/char count — no fork
sort / uniqSort and dedupe — no fork
findWalk directories — no fork
cut / tr / revText manipulation — no fork
seqNumber sequences — no fork
teeCopy stdin to files — no fork
dateCurrent date/time — direct syscall
sleepDelay — no fork
mktempCreate temp file/dir — no fork
hostname / uname / id / whoamiSystem info — direct syscall
touch / realpath / basename / dirnameFile ops — no fork
zgetattr / zsetattr / zdelattr / zlistattrxattr ops — direct syscall

[0x09] SHELL LANGUAGE FEATURES

Every shell construct compiles to fusevm bytecode — no tree-walker dispatch lives in zshrs. The full reference documents each entry with a runnable example.

Control flow

# Standard POSIX/zsh control structures — all compile to fusevm bytecode
if [[ -d $dir ]]; then; elif [[ -f $dir ]]; then; else; fi
while (( i < 10 )); do; done
until ping -c1 host >/dev/null; do sleep 1; done
for f in *.rs; do echo "$f"; done
for ((i=0; i<10; i++)); do; done
case $cmd in start) ;; stop) ;; *) ;; esac
select choice in build test deploy; do done   # interactive numbered menu
coproc { while read l; do echo "ECHO: $l"; done } # bidirectional pipe

Indexed arrays

arr=(alpha beta gamma)            # literal
arr+=(delta epsilon)              # append
echo ${arr[1]}                    # alpha (1-based)
echo ${arr[-1]}                   # epsilon (negative from end)
echo ${arr[@]}                    # splice — N argv slots
echo ${#arr[@]}                   # length
for x in ${arr[@]}; do; done    # iterate (flattens via BUILTIN_ARRAY_FLATTEN)

Associative arrays

typeset -A m                      # declare
m[name]=Jacob; m[role]=eng        # set
echo "${m[name]}"                 # lookup
for k in "${(k)m}"; do echo $k; done   # keys
for v in "${(v)m}"; do echo $v; done   # values

Parameter expansion flags (zsh-style)

echo ${(L)var}                    # lowercase
echo ${(U)var}                    # uppercase
echo ${(j: :)arr}                 # join with space
echo ${(s:,:)scalar}              # split on comma → array
echo ${(f)$(cmd)}                 # split on newlines
echo ${(o)arr}                    # sort ascending
echo ${(O)arr}                    # sort descending
echo ${(P)ref}                    # indirect lookup
echo ${(jL)arr}                   # stack: join then lowercase
echo ${(s:,:U)scalar}             # stack: split then uppercase

Parameter expansion forms

${var:-default}                   # default if unset/empty
${var:=default}                   # assign default
${var:?msg}                       # error if unset
${var:+alt}                       # alternate if set
${#var}                           # length
${var:offset:length}              # substring
${var#pat} / ${var##pat}          # strip shortest/longest prefix
${var%pat} / ${var%%pat}          # strip shortest/longest suffix
${var/pat/repl} / ${var//pat/repl} # replace first/all
${var:u} / ${var:l}               # upper/lower case (zsh postfix)

Background, async, coprocesses

sleep 30 &                        # fork + setsid; parent gets Status(0)
jobs; fg %1; wait $!              # job control
async 'expensive-task' | xargs await   # worker-pool, no fork
coproc { body }                   # bidirectional pipe; $COPROC=[rd_fd, wr_fd]
echo hi >/dev/fd/${COPROC[2]}     # write to coproc stdin
read line </dev/fd/${COPROC[1]}   # read from coproc stdout

Eval, dynamic dispatch, AOP

eval 'echo $x'                    # single-quoted args defer expansion correctly
cmd=ls; $cmd -la                  # dynamic command name routes through host intercepts
intercept before git {; }       # AOP advice fires for both literal and dynamic invocations

[0x0A] COMPATIBILITY

  • Full zsh script compatibility — runs existing .zshrc
  • Full bash compatibility via emulation
  • Fish-style syntax highlighting, autosuggestions, abbreviations
  • 180+ builtins (150 zsh + 23 coreutils + parallel primitives) — see the Reference for the full catalog
  • ZWC precompiled function support
  • Glob qualifiers, parameter expansion flags, completion system
  • zstyle, ZLE widgets, hooks, modules
  • --posix mode for strict POSIX compliance

Test corpus parity

SuiteTestsCoverage
zsh_construct_corpus392Every sh/zsh construct outside modules
zsh_corpus_via_new_pipeline123Native ZshLexer+ZshParser+ZshCompiler path
no_tree_walker_dispatch158Behavioral pins for the no-tree-walker invariant
compile_zsh_smoke28Per-construct bytecode-level smoke
tree_walker_absent8Source-level absence checks (anti-regression)
zsh_parser_probe91AST-shape probes for every construct
ztst_runner70Real .ztst files from upstream zsh
Total876All green on the new (default) pipeline

[0x0B] ARCHITECTURE

                  ┌──────────────────────────────────────────┐
                  │              zshrs binary                 │
                  ├──────────────┬───────────────────────────┤
                  │   src/ (80)  │      fish/ (48 builtins)  │
                  │   lexer      │      reader + line editor  │
                  │   parser     │      syntax highlighting   │
                  │   compiler   │      autosuggestions        │
                  │   exec       │      abbreviations          │
                  │   jobs       │      env dispatch           │
                  │   signals    │      history backend        │
                  │   params     │      process control        │
                  │   glob       │      event system           │
                  │   zle/ (26)  │                             │
                  ├──────────────┴───────────────────────────┤
                  │             compsys (27 files)            │
                  │   rkyv mmap · read-only SQL mirror · zstyle │
                  ├────────���─────────────────────────────────┤
                  │           fusevm (bytecode VM)            │
                  │   129 opcodes · fused loops · JIT path   │
                  └──────────────────────────────────────────┘

[0xFF] LICENSE

MIT — Copyright (c) 2026 MenkeTechnologies

Original-authorship record + portability stance: CREATORS.md. Maintainer governance + protected invariants: MAINTAINERS.md.

This is a legacy, not a battle. The synthesis (compiled-shell architecture, 90/10 daemon split, recorder-owns-rebuild AOP intercept, single ~/.zshrs/ rule, session-persistent supervised jobs with bidirectional ptmx attach, cross-shell pub/sub + named-lock builtins, auto-derived OpenAPI surface, flat-text history + sibling FTS5 index) is prior art for the shell-design commons under the MIT grant. Future shells — bash, fish, nushell, elvish, oil, xonsh, murex, projects that don't exist yet — should inherit any of it. The protected invariants in MAINTAINERS.md guard upstream identity, not the ideas.

Ports must credit zshrs as the invention source in their docs — a one-line attribution in your README / design doc / release notes. Suggested wording:

Inspired by / ported from zshrs by Jacob Menke (MenkeTechnologies).

Ideas can't be copyrighted so this is an ask, not an MIT-enforced clause; honoring it keeps the legacy traceable. See CREATORS.md § Legacy + § Attribution expectation for the full list + suggested forms.