Genro Textual
A declarative TUI framework that builds terminal interfaces from Bag structures using Textual as the rendering engine.
The Idea
Instead of writing imperative widget code, you describe your UI in a main method — a series of builder calls that create a Bag structure. The framework builds this structure and renders it as a Textual application.
from genro_textual import TextualApp
class MyApp(TextualApp):
def main(self, source):
source.binding(key="q", action="quit", description="Quit")
source.static("^greeting")
source.input(value="^form.name", placeholder="Your name")
def store(self, data):
data["greeting"] = "Hello, World!"
data["form.name"] = ""
if __name__ == "__main__":
MyApp().run()
Key Concepts
main() — Declare your UI structure with builder calls
Bag-driven — All state lives in Bag structures (data, source, built)
Reactive binding —
^pointersyntax binds widgets to data pathsBidirectional — Input widgets write back to data on blur
CSS in main — Inline stylesheets via
source.css()Puppeteer/Puppet — TextualApp (logic) drives LiveApp (rendering)
Architecture
graph LR
R[main] --> S[Source Bag]
S --> B[Build]
B --> BB[Built Bag]
BB --> RE[Renderer]
RE --> W[Widget Tree]
D[Data Bag] -.->|binding| BB
W -.->|blur/change| D
Next: Getting Started — Build your first app in 5 minutes