textual
The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.
Write a Python UI once, run it in the terminal and the browser
Textual builds sophisticated interfaces from a simple Python API and runs the same app in a terminal or a web browser, with async available underneath but never forced on you.
One codebase, two runtimes
The lean application framework for Python, as the project styles itself, builds sophisticated user interfaces with a simple API and runs the resulting apps in the terminal and in a web browser. The API mixes modern Python with ideas borrowed from web development. Python under MIT, homepage at textual.textualize.io, around 37,000 stars.
Async when you want it
Under the hood Textual is an asynchronous framework, so apps can integrate with async libraries wherever that earns its keep. The design stance, though, is that users who do not want async should never be forced to touch it. That flexibility is called out as a stated goal rather than left as an accident of implementation.
The widget shelf
Buttons, tree controls, data tables, inputs, text areas, and more. Combined with a flexible layout system, the README claims these parts can realize any user interface needed, the kind of sentence that usually deserves skepticism, except the widget list here is genuinely broad for terminal work.
The dev console in another terminal
A companion package, textual-dev, supplies a dev console that connects to your running application from a second terminal and shows system messages, events, logged messages, and print statements. Debugging a full screen terminal app is normally an exercise in blindness, so a side channel like this is a practical mercy.
Built to stay maintainable
Components are decoupled, and the framework ships what it calls an advanced testing framework, both in service of long term maintenance. For teams considering a terminal UI that will outlive its original author, that part of the README deserves as much weight as the widget list does.
Community notes