Screenshots now properly preserve terminal colors: 1. Replay buffer provides raw ANSI data with color codes 2. pyte interprets escape sequences for accurate screen state 3. Rich renders the pyte buffer with colors to SVG This gives us both accurate terminal state (no creeping/wrapping) and proper color preservation in screenshots. Bumps version to 0.1.12.
textual-webterm
Serve terminal sessions and Textual apps over the web with a simple CLI command.
This is heavily based on textual-web, but specifically focused on serving a persistent terminal session in a way that you can host behind a reverse proxy (and some form of authentication).
Built on top of textual-serve, this package provides an easy way to expose terminal sessions and Textual applications via HTTP/WebSocket with automatic reconnection support.
Features
- 🖥️ Web-based terminal - Access your terminal from any browser
- 🐍 Textual app support - Serve Textual apps directly from Python modules
- 🔄 Session reconnection - Refresh the page and reconnect to the same session
- 🎨 Full terminal emulation - Colors, cursor, and ANSI codes work correctly
- 📐 Auto-sizing - Terminal automatically resizes to fit the browser window
- 🚀 Simple CLI - One command to start serving
Non-Features
- No Authentication - this is meant to be used inside a dedicated container, and you should set up an authenticating reverse proxy like
authelia - No Encryption (TLS/HTTPS) - again, this is meant to be fronted by something like
traefikorcaddy
Quick Start
Serve a Terminal
Serve your default shell:
textual-webterm
Serve a specific command:
textual-webterm htop
Serve a Textual App
Serve a Textual app from an installed module:
textual-webterm --app mypackage.mymodule:MyApp
Serve a Textual app from a Python file:
textual-webterm --app ./calculator.py:CalculatorApp
Options
Specify host and port:
textual-webterm --host 0.0.0.0 --port 8080 bash
Then open http://localhost:8080 in your browser.
Landing pages
You can serve a landing page with multiple terminal tiles driven by a YAML manifest:
- name: My Service
slug: my-service
command: docker logs -f my-service
Run with:
textual-webterm --landing-manifest landing.yaml
You can also point to a docker-compose file; services with the label webterm-command
become tiles. For example:
services:
db:
image: postgres
labels:
webterm-command: docker exec -it db psql
Start with:
textual-webterm --compose-manifest compose.yaml
When a landing manifest is provided, the root (/) shows the grid; clicking a tile
opens a dedicated terminal session in a new tab. Without a manifest, the server
operates in single-terminal mode.
CLI Reference
Usage: textual-webterm [OPTIONS] [COMMAND]
Serve a terminal or Textual app over HTTP/WebSocket.
COMMAND: Shell command to run in terminal (default: $SHELL)
Options:
-H, --host TEXT Host to bind to [default: 0.0.0.0]
-p, --port INTEGER Port to bind to [default: 8080]
-a, --app TEXT Load a Textual app from module:ClassName
Examples: 'mymodule:MyApp' or './app.py:MyApp'
-L, --landing-manifest PATH YAML manifest describing landing page tiles
(slug/name/command).
-C, --compose-manifest PATH Docker compose YAML; services with label
"webterm-command" become landing tiles.
--version Show the version and exit.
--help Show this message and exit.
Development
Setup (Makefile-first)
git clone https://github.com/rcarmo/textual-webterm.git
cd textual-webterm
# Install with dev dependencies via Makefile
make install-dev
Common tasks (use Makefile)
- Lint:
make lint - Format:
make format - Tests:
make test - Coverage (fail_under=80):
make coverage - Full check (lint + coverage):
make check
Notes
- WebSocket protocol (browser <-> server) is JSON:
["stdin", data],["resize", {"width": w, "height": h}],["ping", data]. - Static assets are provided by
textual-serve; this project does not add custom static files. /screenshot.svgreplays the terminal buffer to SVG via Rich; width can be set with?width=120and is clamped for safety.
Requirements
- Python 3.9+
- Linux or macOS
License
MIT License - see LICENSE for details.
Related Projects
- Textual - TUI framework for Python
- textual-serve - Serve Textual apps on the web
- Rich - Rich text formatting for terminals