Windows support
FrankenTUI treats Windows as a first-class CI target but not yet as a
first-class native runtime target. Today that means every test in the
workspace is expected to pass on windows-latest, color and input work on
Windows Terminal, and a dedicated native backend is on the roadmap behind
the Unix v1 milestone. The canonical status document is
docs/WINDOWS.md; this page summarizes it and points to the governing ADRs.
The short version: it runs, it tests green in CI, and the native
backend crate (ftui-win32, tentative) is deliberately deferred until
the Unix backend API is frozen. See ADR-008
for why.
CI validation status
Last validated: 2026-02-03 (bead bd-31go).
| Platform | Runner | Toolchain | Status |
|---|---|---|---|
| Linux | ubuntu-latest | stable, nightly | Validated |
| macOS | macos-latest | stable, nightly | Validated |
| Windows | windows-latest | stable | Validated |
The matrix lives in .github/workflows/ci.yml. Every PR runs:
cargo fmt --check,cargo clippy -- -D warnings,cargo buildon all three.- Full unit-test sweep on all three.
#[cfg(target_os = "windows")]capability-detection tests (notably Windows-Terminal detection viaWT_SESSION).- Platform-independent golden snapshot tests.
- PTY-based E2E tests on Linux/macOS only (see
scripts/cross_platform_e2e.sh). A Windows-native PTY path is part of the deferred work below.
What works on Windows today (v1 target)
- Raw-mode enter/exit with best-effort cleanup on panic.
- Basic key input (letters, arrows, modifiers).
- Resize events where the backend surfaces them.
- Mouse input via SGR encoding where the terminal supports it.
- Color:
- 16-color baseline everywhere.
- 256-color on Windows Terminal and modern ConHost.
- TrueColor on Windows Terminal.
Known limitations on Windows (v1)
- DEC synchronized output (mode 2026): not widely supported. Flicker-free mode falls back to scroll-region batching.
- OSC 8 hyperlinks: Windows Terminal only;
cmd.exeand legacy ConHost skip them silently. - Bracketed paste: varies by emulator.
- Focus events: unreliable in some terminals; treat them as advisory.
- Kitty keyboard protocol: limited/absent.
DECSTBMscroll region: behavior varies by emulator; the renderer sniffs and downgrades.- Mouse SGR: may fall back to legacy encoding on older paths.
Terminal compatibility matrix
| Feature | Windows Terminal | cmd.exe | ConHost | PowerShell |
|---|---|---|---|---|
| TrueColor | Yes | No | Partial | Depends |
| OSC 8 Links | Yes | No | No | Partial |
| Mouse (SGR) | Yes | No | Partial | Partial |
| Sync Output (DEC 2026) | No | No | No | No |
The recommendation is simple: prefer Windows Terminal, use a Unicode-capable font (Cascadia Mono, JetBrains Mono, Fira Code), and let the capability detector do the downgrades.
The v1 scope decision — ADR-004
ADR-004 fixes two things:
- Windows stays in CI. No feature lands that cannot compile and test
green on
windows-latest. - No Windows-specific runtime code ships in v1. That means no
ftui-win32crate yet, no Windows-only dependencies in core, and no feature flags gated on#[cfg(windows)]in widget or runtime code.
This is deliberately conservative. The alternative — sprinkling
crossterm and Win32 API calls throughout core — made the TTY backend seam
much harder to reason about and meant every Unix-side refactor had to
dual-verify on Windows. Keeping a hard line at “everything in core is
portable” has kept the codebase honest.
The terminal backend strategy — ADR-008
ADR-008 generalizes the lesson:
platform specifics go behind ftui-backend, not inside the crates that
consume it. That is already how ftui-tty and ftui-web coexist; a future
Windows-native crate slots into the same seam.
Deferred: the native backend plan
docs/WINDOWS.md Section “Deferred Native Backend Strategy” (bead
bd-lff4p.4.9) lays out the staged plan for a native Windows backend. It
starts after the Unix backend API is frozen.
| Phase | Goal | Primary dependencies | Notes |
|---|---|---|---|
| 0 (current) | Keep Windows CI green while Unix evolves | Existing workspace deps | No new Windows-only runtime dep |
| 1 | Backend crate skeleton + RAII lifecycle | windows-sys / windows for console mode + handles | Mirrors TerminalSession cleanup |
| 2 | Input parity (key/mouse/resize/focus) | Win32 console input records + ConPTY probes | Normalize into ftui_core::event::Event |
| 3 | Output + capability parity | VT-enablement APIs, mode toggles, synchronized flushing | Preserves the one-writer rule |
| 4 | Validation + hardening | Windows CI + deterministic E2E fixtures | Terminal-specific paths (WT + ConHost) |
Scope boundaries, restated from the doc:
- Windows work must not block the web renderer/input path, the WASM showcase, or the remote PTY bridge.
- Unix-first milestones stay priority. The Windows crate work starts only
when:
- Unix backend API stabilizes,
- parity tests for core lifecycle pass consistently,
- existing CI is green.
The practical implication: if you are reading this and wondering why
there is no ftui-win32 source yet, that is the reason. The seam is
ready; the crate waits its turn.
Risk register (Windows-specific)
- Capability fragmentation — Windows Terminal vs ConHost vs
cmd.exe. Mitigation: capability-driven branches, strict downgrade paths, no assuming Windows means any one of the three. - Input encoding — modifiers, IME, surrogate pairs all behave differently across console APIs. Mitigation: explicit normalization tests on each.
- Cleanup on abrupt exit — RAII is load-bearing. Mitigation: Windows cleanup tests that mirror the Unix panic-path tests.
Related: frankenterm-architecture.md §13.5
The broader FrankenTerm architecture document (docs/spec/frankenterm-architecture.md)
has a Windows section that outlines how a future browser-backed terminal
experience also satisfies the “Windows works” promise without needing a
native backend at all. Users on Windows today who run the WASM showcase are
effectively using that path already.
Pitfalls
- Do not import
windows-sysfrom core. Every such import is a reviewer “no.” Platform deps live in the backend crate, full stop. - Do not assume
cmd.exebehavior represents “Windows”. Windows Terminal is the target emulator for v1. - Do not disable tests on Windows “because they flake.” File the issue,
tag it
windows, and keep the test green. Silent disabling has bitten us before. - Do not gate features on
#[cfg(windows)]in portable crates. Gate them on aBackendFeaturesbit instead and let the backend answer.
See also
- Platforms overview — the backend seam this depends on
- TTY backend — the Unix-native implementation being stabilized first
- ADR-004 — Windows v1 scope · ADR-008 — terminal backend strategy
- Runtime overview · Contributing — dev loop · Demo showcase — screen catalog