# Porting run-stack to Rust
The shell version lives in `../run` and stays the shipping one until this
reaches parity. Nothing here affects that package.
## Why
`bin/cli.js` costs ~600ms per command before any work happens, and `init.sh`
is 1,969 lines of bash 3.2 faking a hash map with `PRE_*`/`ANS_*` variable
indirection — the two bugs found on 2026-09-13 (a port handed to two apps, and
`--update` walking the whole setup again) both lived in that machinery.
Measured on the author's machine:
| `rst --version` through `bin/cli.js` | 647 ms |
| `bash run.sh --help`, same work | 35 ms |
| a Rust binary | ~2 ms |
| `rst ps` end to end | 1,749 ms, ~97% of it docker |
So speed is the reason to drop Node, not the reason to choose Rust. Rust is
for the single binary (no bash, no python3, no node on the user's machine) and
for making the config and prompt machinery typed.
## Order of work
1. **Config** — `run.config.json` in both shapes, the section grouping. *(done,
with tests)*
2. **Workspace** — walking up to `.run/`. *(done)*
3. **Env render** — `.env` from `.env.example` plus the settings.
4. **Compose** — the `dc()` equivalent: which `-f` files, which profiles.
5. **Plain commands** — up, down, ps, logs, shell, restart, rebuild, clean.
6. **Generators** — the three `docker-compose.*.yml` overlays.
7. **init** — the big one. `inquire` replaces the hand-rolled menus.
8. **Release** — cross-compiled binaries, and an npm wrapper so
`npm i -g @dev-ahmed/run-stack` and `rst self-update` keep working.
## Parity rule
The shell tests in `../run/tests` are the specification. A command is done when
it produces the same output and the same files as the shell one for the same
workspace.