niubash — real Bash, native on Windows, Linux, and macOS.

> **Real Bash, native on Windows, Linux, and macOS.** "Windows-only" is the > old story: five platforms build from this tree now, and Windows remains > the flagship — no WSL. No VM. No `/mnt/c`. No cmdlet dialect. One binary: > the shell your fingers already know, and the one your AI agent actually > speaks.
[English](README.md) · [中文](README-zh.md) Docs & downloads: [unixwin.dev](https://unixwin.dev) [![niubash CI](https://github.com/unixwin/niubash/actions/workflows/ci.yml/badge.svg)](https://github.com/unixwin/niubash/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/unixwin/niubash)](https://github.com/unixwin/niubash/releases) [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-blue)](https://github.com/unixwin/niubash) [![Rust](https://img.shields.io/badge/rust-1.95%2B-orange)](https://github.com/unixwin/niubash) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Stars](https://img.shields.io/github/stars/unixwin/niubash)](https://github.com/unixwin/niubash/stargazers)
**niubash** is a Bash-compatible shell implemented natively in Rust. On Windows, the flagship platform, one `niu.exe` bundles everything: the [rubash](https://github.com/unixwin/rubash) language engine, real Unix commands from [winuxcmd](https://github.com/unixwin/winuxcmd), a git-aware prompt, and a permission-modeled plugin system. Git comes from [niu-git](https://github.com/unixwin/niu-git): the real git-for-windows C source built with MSVC, so the `git` on PATH *is* the git binary — no MSYS runtime, no launcher hop, no bundled perl. `git --version` starts in **~14 ms** (13.7 ms avg / 11.5 ms min measured; `git status` 22.6 ms) where Git Bash's `git` takes 45-103 ms ([niu-git#12](https://github.com/unixwin/niu-git/pull/12), [niubash#374](https://github.com/unixwin/niubash/pull/374)), and the shell-script parts of git (hooks, `git bisect`, `git mergetool`) run on niubash's own `sh`. Agents launched from a niu session inherit it as their shell through `SHELL`; see [Coding agents on Windows](docs/src/agents.md) for which shell each agent runs and how to point the rest at niu. The Linux and macOS builds are portable `niu` binaries that use your system's own tools. niu is not MSYS2, Cygwin, Git Bash, or WSL — there is no POSIX emulation layer and no path-conversion heuristics. The full per-platform contract, including the honest status of every target, lives in [platform-support.md](docs/src/platform-support.md). ## Platforms | Platform | Status | Ships as | |---|---|---| | Windows x64 / ARM64 | Released; smoke-gated every release | installer `.exe` + portable `.tar.gz`/`.7z`/`.zip`, Unix commands bundled | | Linux x86_64 / aarch64 (glibc 2.35+) | Released; smoke-gated every release | portable `.tar.gz`, uses system tools | | macOS aarch64 / x86_64 | Released; smoke-gated every release | portable `.tar.gz`, uses system tools | | Android aarch64 / armv7 | CI build only, no release | NDK-linked zip on workflow runs, not smoke-tested | | OpenHarmony (`aarch64-unknown-linux-ohos`) | CI check only, no release | kept compiling by CI, never run on a device | "Smoke-gated" means the artifact is built, then run on its own OS against four checks (`--version`, `-c` execution, a pipeline through native coreutils, the offline plugin stack) before upload — the gate lives in `release.yml` ("no smoke, no artifact": Linux legs run it natively on `ubuntu-22.04`/`ubuntu-22.04-arm`, the macOS x86_64 leg under Rosetta 2), and the release as a whole additionally blocks on the golden user journey and the per-asset timing budget gates. Android and OpenHarmony have not passed that gate: Android artifacts are build- and link-verified only (an ELF shape check, explicitly not a runtime smoke), OpenHarmony is compile-checked only, and neither claims device readiness. The per-platform contract and the full status matrix live in [platform-support.md](docs/src/platform-support.md). Quick answers: - **Does niu require WSL?** No. niu is a native build on every platform it ships for: on Windows there is no Linux VM, no emulation layer, no `/mnt/c`. - **What platforms does niu run on?** Released builds cover Windows (x64, ARM64), Linux (x86_64, aarch64; glibc 2.35+), and macOS (aarch64, x86_64). Android (aarch64, armv7) and OpenHarmony (aarch64) build in CI and have no release yet; Android additionally carries a measured performance baseline (see [Performance](#performance)). - **Does niu run real Bash scripts?** Yes. The rubash engine is gated on GNU Bash's own upstream test suites; the record lives in the [compatibility matrix](docs/src/rubash-bash-compat-matrix.md). - **Can I install niu on Android or HarmonyOS today?** Not yet. Both targets compile in CI, neither has passed a runtime smoke test, so there is nothing to install. ## Receipts Each claim below links to the artifact that produced it: a committed log, a baseline file, a CI gate. **6,336 real-world shell assets, harvested and replayed one by one.** The pipeline pulls shell scripts, frameworks, themes, and dotfiles from GitHub and sources each one under niu, recording a per-asset verdict: 4,891 OK, 350 slow, 224 that GNU Bash also fails, 101 hangs, 698 that never fetched. The full log is committed ([eco-harvest.py](scripts/harvest/eco-harvest.py), [eco-test.py](scripts/harvest/eco-test.py), snapshot [wt92-local-20261005](scripts/harvest/snapshots/wt92-local-20261005/)). **Framework assets are sourced and timed, not just "supported."** The timing baseline loads 437 real oh-my-bash and bash-it assets (166 themes plus plugins, completions, aliases) and measures three phases per asset (source, first prompt, re-render) as a median of three runs. That includes the nvm assets of both frameworks, and real users' dotfiles that load nvm.sh go through the same harness with per-phase timings on record ([baseline](scripts/perf/baselines/asset-timing-baseline.json), [snapshot](scripts/harvest/snapshots/wt92-local-20261005/)). **A release cannot ship slow.** Every asset in [budgets.toml](scripts/perf/budgets.toml) carries a measured budget (healthy themes re-render in 11-35 ms; the budget line is 120 ms; 5x over budget is a hard fail). The [release pipeline](.github/workflows/release.yml) runs the `perfbudget` gate and fails the release on a breach; a nightly run watches the trend. The GNU Bash upstream golden-suite record lives with the engine: the [rubash README](https://github.com/unixwin/rubash#readme) carries the ledger (83/83 upstream suites on the 2026-10-12 full re-run), and rubash CI replays the upstream corpus on Linux on every push (the "Bash upstream test progress" job, `scripts/run-bash-upstream-tests.sh`). ## Performance Every number below is pinned to the issue or PR that measured it, and the tests or gates that keep it honest are named. **Windows spawn cost — one hidden console per session, not per child.** A console-less session (direct `niu -c`, detached, CI) used to pay a hidden console allocation on every external spawn, ~22 ms per child (design and shape in [niubash#462](https://github.com/unixwin/niubash/issues/462)). The fix landed engine-side ([rubash#913](https://github.com/unixwin/rubash/pull/913)): a windowless console is pre-allocated once on Windows 11 24H2+/Server 2025 (`AllocConsoleWithOptions`), or adopted from the first `CREATE_NO_WINDOW` child (`AttachConsole`) on older builds, so an entire `niu -c 'a; b; c'` tree pays at most one allocation and later spawns inherit it. 14 regression tests pin zero visible windows and the scaling behavior (rubash `tests/console_window_gate.rs`). **`$(tput …)` terminal queries answered in-process.** The inline tput whitelist arm ([rubash#884](https://github.com/unixwin/rubash/pull/884)) answers admitted TERM×capability shapes in-process, byte-equal to GNU ncurses (269-row differential matrix, diff = 0; 8 regression tests). On the ticket probe — 64 tput calls through command substitution — wall time fell 1165 ms → 47 ms (~25x, zero spawns). The winuxcmd-side twin removed the ~17 ms per-call i18n overhead in the real binary (~0.4 ms in-process after the fix; 3208-row replay byte-identical: [WinuxCmd#1269](https://github.com/unixwin/WinuxCmd/pull/1269)). The other harvest SLOW face — `read` on EOF, ~4.8 s/call — is still open on [rubash#800](https://github.com/unixwin/rubash/issues/800). **Engine hot paths** (the embedded [rubash](https://github.com/unixwin/rubash) engine; each fix carries its measured delta and GNU differential battery): - Multi-word literal command fast path: `[ 1 -eq 2 ]` ×20k ≈177→155 ms ([rubash#967](https://github.com/unixwin/rubash/pull/967)). - `[[ ]]` direct numeric leaf + decimal fast path: 50k `[[ 1 -eq 2 ]]` 1.41x→1.10x vs GNU ([rubash#966](https://github.com/unixwin/rubash/pull/966)). - Whitelist-skip of the procsub metadata scan: 1.56x→1.39x (~11%) ([rubash#974](https://github.com/unixwin/rubash/pull/974)). - Decimal-subscript array write lane: interleaved 8k 3.65x→3.16x; also fixes a real double side-effect in `a[$((i++))]=v` ([rubash#959](https://github.com/unixwin/rubash/pull/959)). - Case: head-only `$BASH_COMMAND` render: 20-arm ×10k −10%, plus the divergence fix ([rubash#958](https://github.com/unixwin/rubash/pull/958)). The interpreter triage behind that wave is closed with numbers: scalar assignment ~1.06x GNU (rubash#609 → #672/#678), arithmetic loops and parameter expansion via rubash#607/#608 (#665/#671/#679, #666), and the O(n²) array element write became O(1) amortized (rubash#618/#616: associative 5000-key writes 445x→9.9x vs GNU, indexed 736x→3.8x; the ledger lives in rubash's `docs/performance.md`). The export/unset fast-lane family has landed (#917/#918/#920, reworked for correctness in #943); [rubash#916](https://github.com/unixwin/rubash/issues/916) stays open on the residual. **Android baseline — measured, honest, not yet re-measured.** On a Termux aarch64 tablet, niubash 1.4.0 vs GNU bash 5.3.20 ([niubash#352](https://github.com/unixwin/niubash/issues/352), full method and matrix in the issue): interpreter-bound workloads 2.3-3.7x slower (up to 7.3x on `${x^^}` itself), `niu -c true` 21.1 ms vs bash's 8.3 ms (median of 30), peak RSS 2.2x — while fork-bound workloads run up to 5.2x faster and a real mkdir/write/read-back script 2.1x faster. The engine-side root causes were fixed and closed (rubash#607-609) and the wrapper's one-shot startup gap closed too ([niubash#351](https://github.com/unixwin/niubash/issues/351): `niu -c true` 15 ms vs bash 13 ms after the fix, zero tput spawns). [niubash#349](https://github.com/unixwin/niubash/issues/349) is the original ~2.1x arithmetic/function datapoint. No post-fix re-measure on Android hardware exists yet — #352 stays open for that re-run, and the Android leg still ships build-verified only. ## Quick start All downloads start at [unixwin.dev](https://unixwin.dev). Windows: grab `niubash-v*-win-*-setup.exe` from [Releases](https://github.com/unixwin/niubash/releases) and run it — no admin rights; PATH and a Windows Terminal profile are set up for you. Prefer portable? Take the `.tar.gz` — it ships the bundled git/awk payload as real hardlinks, so it downloads and unpacks much smaller than the `.zip` (`tar -xf niubash-v*-win-x64.tar.gz`, built into Windows 10+). The `.zip` stays for tooling that only speaks zip. Linux (x86_64, aarch64; glibc 2.35+) and macOS (aarch64, x86_64): take the portable tarball, untar, run: ```sh tar -xzf niubash-v*-linux-x86_64.tar.gz && niubash-v*-linux-x86_64/niu ``` From source (Rust 1.95+): `git clone https://github.com/unixwin/niubash.git && cd niubash && cargo build --release` Configuration is one file, `~/.niubashrc`, in plain Bash syntax — start with [Getting started](docs/src/getting-started.md). ## Documentation [Docs site](https://unixwin.github.io/niubash/) · [Why niubash](docs/src/why-niubash.md) (the long version, with the agent casualties) · [Platform support](docs/src/platform-support.md) · [Bash compatibility matrix](docs/src/rubash-bash-compat-matrix.md) · [Roadmap](docs/src/niubash-roadmap.md) --- If niu saved you a Linux VM, a mangled quote, or an argument PowerShell ate, [star the repo](https://github.com/unixwin/niubash) and tell a developer. ★ ## License MIT. See [LICENSE](LICENSE).