Modern Text User Interface framework for building cross-platform terminal and web applications with Python
npx @tessl/cli install tessl/pypi-textual@6.1.0A comprehensive Python framework for building modern Text User Interface (TUI) applications that work both in terminals and web browsers. Textual provides a complete widget ecosystem, CSS-like styling, event-driven programming, and deployment flexibility for creating professional interactive applications across platforms.
pip install textualfrom textual.app import App
from textual.widget import Widget
from textual.screen import ScreenCommon widget imports:
from textual.widgets import Button, Input, Static
from textual.containers import Container, ScrollableContainerEvent handling and utilities:
from textual import on, log
from textual.reactive import Reactivefrom textual.app import App
from textual.containers import Container
from textual.widgets import Button, Static
class BasicApp(App):
"""A basic Textual application."""
def compose(self):
"""Compose the UI."""
yield Container(
Static("Hello, Textual!"),
Button("Click me!", id="click-btn"),
Button("Exit", id="exit-btn")
)
def on_button_pressed(self, event: Button.Pressed):
"""Handle button presses."""
if event.button.id == "exit-btn":
self.exit()
elif event.button.id == "click-btn":
self.log("Button was clicked!")
if __name__ == "__main__":
app = BasicApp()
app.run()Textual uses a component-based architecture with several key concepts:
This design enables building complex applications from reusable components while maintaining familiar web-like development patterns adapted for terminal interfaces.
Essential application framework classes and decorators for building Textual applications, including the main App class, base Widget class, screen management, and event handling decorators.
__version__: str # Package version string
class App:
def run(self) -> None: ...
def push_screen(self, screen: Screen) -> None: ...
def pop_screen(self) -> Screen: ...
def exit(self, result=None) -> None: ...
class Widget:
def compose(self) -> ComposeResult: ...
def render(self) -> RenderableType: ...
def on_mount(self) -> None: ...
def on(*selectors, **kwargs): ...
def work(exclusive=False, thread=False): ...Complete collection of built-in UI components including input controls (Button, Input, TextArea), display widgets (Static, Label, DataTable), navigation components (Tabs, Tree), and utility widgets (ProgressBar, LoadingIndicator).
class Button(Widget):
def __init__(self, label, *, variant="default", disabled=False, **kwargs): ...
class Input(Widget):
def __init__(self, value="", placeholder="", **kwargs): ...
class DataTable(Widget):
def add_column(self, key, *, label=None, **kwargs): ...
def add_row(self, *cells, **kwargs): ...
class Static(Widget):
def __init__(self, renderable="", **kwargs): ...Comprehensive event handling system for user interactions, widget lifecycle, and system events, including keyboard input, mouse interactions, focus management, and custom message passing.
class Event:
def prevent_default(self) -> None: ...
def stop(self) -> None: ...
class Key(Event):
key: str
character: str | None
class Mouse(Event):
x: int
y: int
button: int
class Message:
def __init__(self) -> None: ...CSS-like styling system with layout algorithms, reactive properties for automatic UI updates, color management, and geometric utilities for precise UI positioning and sizing.
class Styles:
def __init__(self): ...
def __setattr__(self, name: str, value: Any): ...
def reactive(default=None, *, layout=False, repaint=True): ...
class Color:
def __init__(self, r: int, g: int, b: int, a: float = 1.0): ...
class Size:
def __init__(self, width: int, height: int): ...Rich content system for displaying formatted text, custom renderables for specialized visualizations, and content processing utilities for handling complex text layouts and styling.
class Content:
def __init__(self, text: str = "", spans=None): ...
class Strip:
def __init__(self): ...
def render(self, console, options): ...
def walk_children(node: DOMNode, *, reverse=False): ...
def walk_depth_first(root: DOMNode): ...Programmatic testing framework with the Pilot class for automated UI testing, command palette system for built-in development tools, and logging utilities for debugging applications.
class Pilot:
def __init__(self, app: App): ...
async def press(self, *keys: str): ...
async def click(self, selector: str = None): ...
class CommandPalette(Widget):
def __init__(self): ...
def log(*args, **kwargs): ...from typing import Union, Iterator, Any
from rich.console import RenderableType
ComposeResult = Iterator[Widget]
MessageTarget = Union[Widget, Screen, App]
CSSPathType = Union[str, list[str]]