The C shell, native to Windows. Familiar csh ergonomics, a self-contained installer, and direct access to Win32 — with no WSL, no Cygwin, and no compatibility layer.
Windows developers have lived for decades with two unsatisfying options for shell work: cmd.exe, frozen in time, and WSL, which is really a separate operating system bolted on. PowerShell occupies its own niche but does not match the ergonomics of a Unix shell.
C Shell for Windows is a native Win32 implementation of csh designed for engineers who want the familiarity and discipline of a Unix shell without leaving Windows behind. It runs natively, integrates with the Windows process model, and ships with 188 bundled man pages.
No GUI launcher, no telemetry, no surprises. Just a fast, scriptable shell that does what you tell it to.
Ships as a self-contained bundle — nothing to install separately. No WSL, no Cygwin, no Windows runtime prerequisites to chase.
Variables, aliases, history substitution, and control flow behave the way csh users expect.
Registers itself as a Windows Terminal profile on install — one click to a new csh tab. ANSI escape sequences and 24-bit color throughout.
Completion for files, paths, and command history.
Scriptable startup file. Write scripts that integrate with the rest of your Windows tooling — with an optional VS Code extension for syntax highlighting.
Approximately twelve megabytes on disk, including bundled regex and compression. Fast startup. No background services.
CShW is in active alpha. Feedback from real users shapes what ships next — we’d like yours.
Installer with a desktop shortcut, Start menu integration, and Windows Terminal profile. Uninstalls cleanly. New in 1.0.7.0: concurrent pipelines — a | b | c stages run on parallel threads with bounded Win32 pipes between them. seq 1 10000000 | head -1 now terminates the producer near-instantly instead of running ten million iterations. External commands stream too via per-stage STARTF_USESTDHANDLES; pipelines inside procs see $1/$argv correctly via per-thread scope snapshot; backtick capture of pipelines works under load. set pipemode = sequential remains as the user-selectable opt-out preserving 1.0.6.x semantics exactly. Still in: bc -x exact rationals + matrices + complex, POSIX dc, the cascading settings layer, and 79/79 in both modes.
The first cshw release where a | b | c runs on parallel threads. This is the headline infrastructure milestone of the 1.0.x line — the load-bearing change that the 1.0.6.x bc/dc cycle laid groundwork for, and the last piece on the path toward a beta-readiness call.
Pipeline stages run concurrently. Each segment of a pipeline runs on its own thread with bounded Win32 anonymous pipes between adjacent stages. Backpressure flows naturally — the consumer reads as the producer writes, instead of the producer running to completion and the consumer slurping the result. Stages 0..N-2 run on std::thread workers; stage N-1 runs on the caller's thread so $status / $result naturally land in the caller's thread-local dispatcher state (POSIX last-stage-status semantics).
Streaming early-termination. When a downstream stage exits, the upstream producer notices and stops within milliseconds. seq 1 10000000 | head -1 now returns in about as much time as cshw takes to start up — head reads its first line, closes its pipe, seq sees ERROR_BROKEN_PIPE on its next write, and stops. The old sequential behavior would have run all ten million iterations. head itself was rewritten to read line-by-line via a new bounded reader instead of the slurp-then-trim pattern that was defeating the entire mechanism.
External commands stream too. cat huge.log | grep foo | head -10 works the same whether segments are cshw builtins or Win32 externals. External-command launches inherit per-stage pipe handles via STARTF_USESTDHANDLES + restricted PROC_THREAD_ATTRIBUTE_HANDLE_LIST, without touching the process-global SetStdHandle state — that turned out to be a load-sensitive race in earlier development and is now closed in both the preferred and legacy fallback launch paths.
Backtick capture works inside pipelines. set out = `cmd | grep pattern | wc -l` captures correctly even when the pipeline runs across multiple worker threads. The interaction between the outer capture's stdout redirection and per-stage pipe handles was the last race we chased before flipping the default.
Procs work in pipeline stages. A pipeline running inside a proc body sees the caller's $1 / $argv correctly — workers snapshot the caller's local-scope stack on spawn so proc-arg references resolve. Without this, the universal assert_contains idiom (echo "$1" | grep "$2") silently returned wrong data on every call.
Opt-out preserved. set pipemode = sequential restores 1.0.6.x semantics byte-for-byte, including the 64 MiB per-stage pipe buffer that covers large command output (netstat, tasklist, log dumps). pipemode lives in the cascaded settings layer (settings.csh > HKCU > HKLM > built-in default), so the change can be machine-wide, per-user, or per-invocation. The mode is snapshotted once per pipeline invocation; a stage that runs set pipemode = sequential mid-pipeline doesn't retroactively change the running pipeline.
Concurrent-mode internals. 64 KiB anonymous pipes between stages (the Win32 default; matches the streaming-backpressure model). New per-thread I/O override on CShellCommands repoints scpi.fOutput / scpi.fInput at per-stage pipe FILE∗s without touching process-global fd 0 / fd 1. Builtins that already used the scpi.fOutput abstraction (1,800+ references) needed no changes; the few stragglers (cat, awk, sed, plugin output API, bc/dc one-shot stdin) were migrated through the same accessor.
1.0.6.x carries over unchanged. bc -x exact rationals + matrices + complex from 1.0.6.4 are still there. POSIX dc with conditional macros and register arrays. The cascading settings layer. The 21-chapter book bundled with the install. Test suite: 79 suites, all green, in both modes.
Doesn't change at all. Coroutines (corun / wait / cowait / cocancel) remain a distinct subsystem from pipeline workers — you can run pipelines inside coroutines and vice versa. Mutex / event / semaphore / barrier / channel primitives unchanged. Plugin DLLs in C/C++, built-in AI (OpenAI / Anthropic / Azure / Ollama / LM Studio), persistent history, bang-recall, Ctrl-R reverse search — same.
Shell fundamentals. csh/tcsh-flavored control flow (if/while/foreach/loop/for/switch) with optional then on every header. Procedures with locals and $result. Real arrays and hashes. Chainers (;, &&, ||, and, or, xor, nor, nand). Stderr redirection (2>, 2>>, 2>&1). Regex match (=~ / !~). Persistent history with bang-recall and Ctrl-R reverse search.
Daily-driver commands. Full text-tool suite (grep with PCRE2, sed, awk, sort -t/-k, uniq, cut, tr, wc, head, tail -f). File operations including find with size/mtime/type filters. Job control. genai (OpenAI, Anthropic, Azure, Ollama, LM Studio). Networking primitives. Browse all 187 in the full command reference →
Windows-native. Real concurrency (coroutines plus mutex, event, semaphore, barrier, channel). Plugin DLLs in C/C++. Direct Win32 from the shell (rundllproc, winapi, dllimport). Runs your existing .bat/.cmd scripts through cmd.exe and .ps1 scripts through PowerShell — cshw dispatches them to the right interpreter, it doesn’t reinterpret them.
It’s alpha. Expect rough edges. Some commands have feature gaps relative to GNU equivalents (e.g., awk is a subset of full POSIX awk; sort -k accepts a single field rather than ranges). The Win32 calling-convention surface of rundllproc is generally x64 fastcall; mismatched signatures are still UB. Found something broken? Email bugs@tropibyte.com.
cshw is a developer/admin shell. Plugins are native code; rundllproc calls real Win32; scripts aren’t sandboxed. The trust model is identical to running any .exe: you load it, you ran it, you trust it. No auto-discovery of plugins from the internet, no driver-level code, no hidden privilege escalation.
The SHA-256 of the installer is shown above. Verify in PowerShell with
Get-FileHash cshw-setup-1.0.7.1.exe -Algorithm SHA256.
If the hash doesn’t match, don’t run the installer.
CShW ships incrementally. Here’s the work currently on the path to beta.
Hardening the core interpreter, expanding the test suite, and addressing alpha feedback.
Native binaries for Windows on ARM, alongside the existing x64 release.
Per-project shell configuration with explicit precedence and reload semantics.
Wider release with installer signing chain, automatic updates, and a published EULA.
CShW is being shaped by its early users. Bug reports go to a dedicated address with a fill-in-the-blanks template; general notes go to hello@tropibyte.com. We read everything.