Why Winuxsh

The long version of the pitch. The README sells it in five seconds; this page shows the receipts.

The Windows shell civil war

Every Windows developer knows the tabs open on their machine:

OptionThe fine print
CMDFrozen in 1987. Your company's docs still paste it.
PowerShellA genuinely powerful automation language. It is not Bash — your for loops, grep, and quoting instincts die on arrival.
WSLA whole Linux distribution as a hobby you didn't sign up for. Boot a VM to print a directory. Dock your Docker Desktop's memory. Greet /mnt/c/Users/you/....
Git Bash / MSYS2Brilliant emulation with a cost: it translates, mangles, and converts your paths at the worst possible moments, and every git pays an emulation tax.

The treaty

Winuxsh is one native Windows binary that runs Bash syntax on Windows paths with real Windows programs — and brings the Unix commands Windows never had (ls, cat, grep, find, test, printf, ...).

WinuxshWSLGit BashPowerShell
Bash syntax
Native Windows paths (C:\..., no /mnt/c)⚠️ conversion quirks
Calls git.exe / node.exe directly⚠️ via /mnt/c⚠️ path translation
Unix commands (ls, grep, find)
Cold start to prompt~170 msseconds~1 s~280 ms
No extra OS, no VM
Themes, git prompt, plugins⚠️

One binary. One process. No distro to patch, no emulation layer to appease.

PowerShell eats arguments

Windows itself is the root cause: the platform has no argv array. Every executable receives a single command-line string and parses it with its own rules — and PowerShell adds a second parser on top. That's how PowerShell/PowerShell#1995 ("Arguments for external executables aren't correctly escaped") became a household name, and how dotnet/runtime#23347 opens by citing "the ongoing quoting woes PowerShell experiences."

Same command line, two shells. Watch what actually reaches the process:

# PowerShell 5.1                                # Winuxsh
> node -e "console.log(JSON.stringify(          ❯ node -e "console.log(JSON.stringify(
    process.argv.slice(1)))" "a b" "" "c\"d"      process.argv.slice(1)))" "a b" "" "c\"d"
    "e\f" "---"                                   "e\f" "---"

ParserError: TerminatorExpectedAtEndOfString   ["a b","","c\"d","e\\f","---"]

That command is written the way any model trained on Bash would write it. PowerShell throws a parse error before the process even starts. And when you quote it PowerShell's own way, the damage is quieter but still real: five arguments in, two mangled ones out — the empty string vanishes, the embedded quote is flattened, the last two arguments fuse into one:

> node -e "console.log(JSON.stringify(process.argv.slice(1)))" "a b" "" 'c"d' "e\f" "---"
["a b","cd e\\f ---"]

Agent casualties, with receipts

For humans this is a nuisance. For AI agents it's a minefield: models are trained on Bash, their quoting instincts are Bash-shaped, and on a PowerShell machine every generated command is a roll of the dice.

The path philosophy: native in, native out

Windows-native binaries don't speak the MSYS dialect. Here is Git Bash, in the wild, failing at exactly the things Winuxsh does without thinking:

Git Bash failing: backslash paths eaten, /c/ paths rejected by cmd, MSYS path conversion breaking git grep

What just happened, command by command:

CommandIn Git Bash (MSYS)In Winuxsh
node -e "..." "C:\Users\you\repo"the backslashes are eaten — the argument vanishesargument arrives byte-for-byte
cmd /c dir /c/Windows/...cmd.exe rejects the MSYS path (exit 1)native path, native tools, no guessing
git grep "/fn main"MSYS rewrites /fn into a Windows path — the pattern silently dies/ is just a character, not a path to convert

MSYS "solves" paths by guessing: it heuristically rewrites /c/foo into C:\foo, and famously mangles innocent arguments along the way — the notorious case of git grep "/pattern" silently becoming git grep "C:\...\pattern" is why MSYS2 still ships MSYS2_ARG_CONV_EXCL as an escape hatch. Every native tool call is a game of path roulette.

Winuxsh is the only Windows shell that doesn't translate anything — because it speaks both dialects itself and hands every process its own native language:

❯ cd /c/Users/you/repo     # MSYS-style input: understood
C:/Users/you/repo            # output: always Windows-native
❯ node -e "console.log(process.cwd())"
C:\Users\you\repo            # native binaries get native cwd
❯ cd "C:\Program Files"     # Windows-style input: understood
❯ pwd
C:/Program Files

Input in any dialect. Output always native. Zero guessing, zero conversion roulette — for your fingers, and for your agent.