A cross-platform desktop terminal with workspaces and tabs
Project description
terminux
A fast, reliable, cross-platform terminal — organized the way you actually work.
Workspaces on the left. Tabbed terminals in the middle. Everything where you left it.
Why terminux?
You don't have one project. You have six. Each one is a different directory, a different mental context, a different set of running shells. terminux gives each of them a home — a workspace — and keeps them alive and arranged exactly how you left them, even across restarts.
It's the workspace UX of cmux on a clean, auditable two-process architecture inspired by terax — rebuilt in Python for reliability over features. No accounts. No telemetry. No AI. Just a terminal that respects your flow.
uv sync && make frontend
uv run terminux
That's it. You're in.
✨ What you get
- Workspaces sidebar — a persistent list of named workspaces. Names track the active shell's working directory automatically (until you pin one).
- Tabbed terminals — every workspace has its own tabs, each a real PTY shell. Switch freely; background tabs keep streaming, no jank.
- Survives restarts — workspaces, tabs, window geometry, font size, and each shell's working directory all come back. Fresh shells, same layout.
- Keyboard-first — jump to a workspace with
Cmd/Ctrl+1..9, fuzzy quick-switcher onCmd/Ctrl+P, find-in-terminal, font zoom, and more. - Attention that finds you — background activity indicators; BEL or
OSC 9on an off-screen tab raises a badge that bubbles up to its workspace. - Drag & drop — reorder workspaces and tabs with live drop feedback (works even in WKWebView, where HTML5 DnD doesn't). Drop a file to paste its shell-quoted path.
- Local-first & hardened — loopback-only by default, per-session auth token, CSP and security headers, atomic versioned persistence.
The fuzzy quick switcher (Cmd/Ctrl+P) — jump to any workspace or tab.
Run
uv sync
make frontend # build the web UI (needs Node; first run only)
uv run terminux # desktop window (pywebview)
uv run terminux --no-window # server only — open the printed URL in a browser
--no-window is the dev/test path and a preview of the future web mode.
Install / package
terminux ships as a self-contained desktop app — no Python or Node required to run the bundle.
make app # macOS .app → dist/terminux.app
make linux # Linux bundle (built in Docker) → dist/linux/terminux/terminux
make docker-run # run headless web mode on :8000
Full platform notes (signing, Gatekeeper, X11, architectures) live in the documentation.
Documentation
Docs are built with Zensical and live in docs/.
uv run zensical serve # live preview at http://127.0.0.1:8000
uv run zensical build # static site → site/
Start with docs/index.md. The original vision, functional
spec, and technical spec are in notes/.
Develop
make frontend # build TS/Vite UI → src/terminux/web/static
make frontend-test # vitest unit tests (pure TS logic)
make test # pytest: unit, integration, e2e (Playwright)
make lint # ruff + ty + pyrefly + mypy
make format
The e2e tier drives the served UI with a real browser (no pywebview); install
it once with uv run playwright install chromium.
Status — 0.5 preview
Works today: workspaces sidebar (create / rename / reorder / close, auto status dot), tabs with multiple live terminals, real PTY shells over a per-terminal WebSocket, background streaming, structure persisted to disk (fresh shells on restart), per-session loopback token, macOS & Linux bundles.
Not yet: split panes, client/server detach, Windows PTY, scrollback persistence.
Architecture in one breath
A Vite/TypeScript xterm.js web UI runs in a sandboxed pywebview window and talks
to a loopback Starlette/uvicorn backend that owns the PTYs and streams raw bytes
over per-terminal WebSockets. The frontend build output is committed to
src/terminux/web/static/, so the Python package runs with no Node toolchain.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file terminux-0.5.0.tar.gz.
File metadata
- Download URL: terminux-0.5.0.tar.gz
- Upload date:
- Size: 101.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b36805776db87881ad2210fef074e8115b8fc326c4401d17eaed309aa7856fc5
|
|
| MD5 |
cb901f4f686a141deb9a249864930b32
|
|
| BLAKE2b-256 |
e5680cbb3896cb003ccc3cfa7461cde7a1bb6718a354edca024677dc4ddc1c1f
|
File details
Details for the file terminux-0.5.0-py3-none-any.whl.
File metadata
- Download URL: terminux-0.5.0-py3-none-any.whl
- Upload date:
- Size: 106.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ac96cd903cdee00f222fe4d05cfdca528bfa8db0c28f9f9dfa3dd3f40450f66
|
|
| MD5 |
6b9a930679ff454f5536cf239c1b7877
|
|
| BLAKE2b-256 |
52e0477f796b132eaa7cb53ca91db14e2ded09ee8b946a6610d26c27f38d0b44
|