An app started inside an SSH or mosh login runs in auto-detected remote mode. In that mode, native detection returned before it read `TERM` and `COLORTERM`, so neither `ansi256` nor `rgb` was ever set, and the renderer sent truecolor SGR to every remote terminal. A 256-color endpoint such as GNU screen 4.x then showed the UI without color, while the same `TERM` worked locally. This supersedes #1492 by @yurial and keeps its commit as authored. The fix is that commit's design: read the color depth keys (a `TERM` that contains `256color`, a `COLORTERM` of `truecolor` or `24bit`) before the auto remote return, and keep the return for the identity keys such as `TERM_PROGRAM`, the multiplexer variables, and the `OPENTUI_*` overrides, which can describe the wrong endpoint on the process host. The later commits port its renderer test to the current test fixtures (it used the pool API that #1479 removed, so `test:native` did not compile), read the two keys in one place instead of through a helper called on both sides of the return, and fold the tests into one table. Local and explicit remote mode, which `@opentui/ssh` uses, give the same result as before. Color depth values in `environment` now take effect in auto remote mode too; the other values still need `remote: true`, and the terminal capabilities docs now say so. There is a trade-off. A truecolor terminal that reaches the server with `TERM=xterm-256color` and no `COLORTERM`, for example iTerm2, WezTerm, or Ghostty over a stock macOS ssh client, used to get exact colors by accident and now gets 256-color approximations, which is what it gets locally. A Kitty XTVERSION reply still turns on `rgb`. The docs explain how to keep truecolor: export `COLORTERM=truecolor` on the server, forward it with `SendEnv`/`AcceptEnv`, or pass it in `environment`. A table in `terminal_test.zig` runs the same `SSH_CONNECTION`, `TERM`, and `COLORTERM` rows through local, auto, and explicit remote mode, with both an `env_map` passed at init and forwarded `setHostEnvVar` values. The renderer fallback test now gets `ansi256` from an auto remote forwarded `TERM` and checks for `38;5` output, and the remote TypeScript tests check `ansi256` and `rgb` from forwarded and explicit values. On main the forwarded auto remote rows and these tests fail. Moving the checks back after the return, dropping the `TERM` check or `24bit`, accepting any `COLORTERM`, reading only forwarded maps, matching `256color` only as a suffix, or deleting the return each makes at least one test fail. Fixes #1491 --------- Co-authored-by: Yuri Dyachenko <pub.yurial@gmail.com>
OpenTUI is a library to build terminal user interfaces.
- It is written in Zig.
- You write TypeScript directly or through React and Solid.
- You arrange boxes and text with flexbox.
- You add selects, inputs, and scroll boxes with keyboard and mouse controls.
- You can play sounds, show images, and render 3D graphics.
OpenCode uses OpenTUI in production for millions of users.
Website | Documentation | Packages
Packages
@opentui/core- Native terminal UI library with TypeScript bindings.@opentui/react- React renderer for building terminal user interfaces with OpenTUI Core.@opentui/solid- Solid renderer for building terminal user interfaces with OpenTUI Core.@opentui/keymap- Key binding and command routing library for terminal and browser applications.@opentui/qrcode- QR code encoder and renderable with React and Solid surfaces.@opentui/three- Three.js WebGPU renderer for OpenTUI.@opentui/ssh- SSH server integration for OpenTUI applications.
Private packages
@opentui/native- Private workspace with the Zig implementation, native tests, and benchmarks.@opentui/examples- Private workspace with example applications and a standalone examples executable.@opentui/web- Private workspace with the documentation website and the AI agent skill.
AI agent skill
Install the OpenTUI documentation as a skill for your AI coding assistant with npx skills:
npx skills add https://opentui.com --skill opentui
Add -g to install the skill globally. The skill matches the latest release, and npx skills update moves it to each
new release. Install from https://opentui.com/docs/next to follow the main branch. A skill installed with
npx skills add anomalyco/opentui follows the main branch; run the command above to switch it to releases.
Development
Development requires Bun 1.4.1 or later and Zig 0.16.0.
See AGENTS.md for engineering, tooling, and verification conventions.
bun install
Run package scripts from their package directory. Run bun run build from the repository root after you change
native code or cross-package build outputs. Ordinary TypeScript changes do not require a root build.
Run repository tests and static checks from the repository root:
bun run test
bun run fmt:check
bun run lint
To link the source packages into a Bun-managed project, install that project's dependencies, then run
./scripts/link-opentui-dev.sh /path/to/project from the repository root. Add --react or --solid when needed.
Contributing
OpenTUI is open for contributions.
License
OpenTUI is licensed under the MIT License.