# Textual — Rapid Application Development Framework for the Terminal > Textual is a Python framework for building sophisticated TUI applications with CSS-based styling, async event handling, and 20+ built-in widgets. The same app can run in the terminal or in a web browser. ## Install Save as a script file and run: # Textual — Rapid Terminal Application Development ## Quick Use ```bash pip install textual textual-dev python -m textual # Open demo textual run --dev my_app.py ``` ```python # hello.py from textual.app import App, ComposeResult from textual.widgets import Header, Footer, Button class HelloApp(App): CSS = "Button { margin: 1; }" def compose(self) -> ComposeResult: yield Header() yield Button("Click me", id="hi") yield Footer() def on_button_pressed(self, event): self.notify("Hello from Textual!") HelloApp().run() ``` ## Introduction Textual is the most ambitious terminal UI framework in the Python ecosystem. Built on top of Rich, it brings web-app-style development (CSS styling, reactive state, async events) to the terminal. Applications can target both the TTY and the browser (via textual-web). With over 26,000 GitHub stars, Textual powers modern CLI tools like Harlequin (SQL IDE), Posting (HTTP client), and Memray (memory profiler UI). ## What Textual Does Textual gives you widgets (Button, Input, DataTable, Tree, etc.), CSS-based styling, an async event loop, reactive state (watch properties and rerender automatically), and a full devtools stack. You write a class, compose widgets, style with CSS, and run anywhere Python runs. ## Architecture Overview ``` [Textual App] | [Compose Tree] Widgets & containers | [CSS Stylesheet] Layout, colors, borders | [Event Loop (asyncio)] on_mount / on_key / on_click | [Message Queue] Reactive updates | [Driver] +-- Terminal (Linux/macOS/Windows) +-- Browser (textual-web) ``` ## Self-Hosting & Configuration ```python from textual.app import App, ComposeResult from textual.widgets import Input, DataTable, Header, Footer from textual.containers import Vertical class SearchApp(App): CSS_PATH = "search.tcss" BINDINGS = [("q", "quit", "Quit")] def compose(self) -> ComposeResult: yield Header() with Vertical(): yield Input(placeholder="Search...", id="q") yield DataTable(id="results") yield Footer() def on_mount(self) -> None: table = self.query_one(DataTable) table.add_columns("Name", "Stars") async def on_input_submitted(self, event: Input.Submitted) -> None: rows = await fetch_results(event.value) table = self.query_one(DataTable) table.clear() for row in rows: table.add_row(*row) SearchApp().run() ``` ## Key Features - **Widget library** — Button, Input, DataTable, Tree, Tabs, and 20+ more - **CSS styling** — real cascading stylesheets for terminals (.tcss) - **Reactive state** — properties that trigger re-renders on change - **Async event loop** — asyncio-native, play nicely with aiohttp/httpx - **DevTools** — live reload + console for debugging - **Cross-target** — run in terminal or browser via textual-web - **Theming** — built-in dark/light themes, easy custom palettes - **Testable** — Pilot object lets you script UI interactions in pytest ## Comparison with Similar Tools | Feature | Textual | Rich | urwid | Curses | Blessed | |---|---|---|---|---|---| | Widgets | 20+ | No | Many | Low-level | Low-level | | CSS Styling | Yes | BBCode markup | Manual | No | No | | Async | Yes | No | Limited | No | No | | Web Target | Yes | No | No | No | No | | Learning Curve | Moderate | Low | High | Very High | Moderate | | Best For | Full TUI apps | Pretty CLI output | Legacy TUI | Custom TUI | Shell scripts | ## FAQ **Q: Can Textual apps really run in a browser?** A: Yes. textual-web serves your app over WebSockets and renders it with an HTML canvas. Same code, zero changes. **Q: Is Textual production ready?** A: Yes (v0.x but actively used). Posting, Harlequin, and dozens of commercial tools ship Textual apps. **Q: How do I test a Textual app?** A: Use App.run_test() which returns a Pilot for scripting keystrokes and mouse clicks. Combine with pytest. **Q: Does it work on Windows?** A: Yes, including Windows Terminal and legacy cmd.exe (with reduced fidelity). ## Sources - GitHub: https://github.com/Textualize/textual - Docs: https://textual.textualize.io - Author: Will McGugan (Textualize) - License: MIT --- Source: https://tokrepo.com/en/workflows/cd808776-37b4-11f1-9bc6-00163e2b0d79 Author: Script Depot