{"id":376,"library":"textual","title":"Textual: Modern Text User Interface Framework","description":"Textual is a Python framework for building sophisticated user interfaces with a simple API. The current version is 8.2.0, released on March 27, 2026. It follows a regular release cadence, with updates approximately every few weeks.","status":"active","version":"8.2.0","language":"python","source_language":"en","source_url":"https://github.com/Textualize/textual","tags":["UI","Framework","Python","Terminal","Web"],"install":[{"cmd":"pip install textual","lang":"bash","label":"Install Textual"}],"dependencies":[{"reason":"Provides rich text and formatting capabilities for Textual","package":"rich","optional":false}],"imports":[{"note":"Ensure correct import path to avoid ImportError","symbol":"App","correct":"from textual.app import App"}],"quickstart":{"code":"import os\nfrom textual.app import App\nfrom textual.widgets import Header, Footer, Placeholder\n\nclass MyApp(App):\n    async def on_mount(self) -> None:\n        self.set_interval(1, self.update)\n\n    async def update(self) -> None:\n        pass\n\n    async def on_resize(self, width: int, height: int) -> None:\n        pass\n\nif __name__ == '__main__':\n    app = MyApp()\n    app.run()","lang":"python","description":"A minimal Textual application with a header, footer, and placeholder."},"warnings":[{"fix":"Update code to use 'Select.NULL' instead of 'Select.BLANK'.","message":"In version 8.0.0, 'Select.BLANK' was renamed to 'Select.NULL' to avoid a name clash.","severity":"breaking","affected_versions":"8.0.0"},{"fix":"Avoid using 'App.PAUSE_GC_ON_SCROLL_' in production code.","message":"The 'App.PAUSE_GC_ON_SCROLL_' attribute is experimental and may be removed in future versions.","severity":"deprecated","affected_versions":"8.1.0"},{"fix":"Update calls to `on_resize()` to include the `height` argument, or modify its definition to match the new signature if you are implementing it.","message":"The `on_resize()` function or method signature has changed and now requires a 'height' argument.","severity":"breaking","affected_versions":"unknown"},{"fix":"Update the signature of `MyApp.on_resize()` to accept a 'height' argument, or ensure it is called with the 'height' argument if the signature is already correct according to the expected API.","message":"The `MyApp.on_resize()` method is being called without a required 'height' argument.","severity":"breaking","affected_versions":"3.13.0"}],"env_vars":null,"last_verified":"2026-05-12T13:24:30.842Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"pip install textual","cause":"The 'textual' library is not installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'textual'"},{"fix":"from textual.widgets import Button","cause":"Widgets like Button are located within the 'textual.widgets' submodule, not directly in the top-level 'textual' package.","error":"ImportError: cannot import name 'Button' from 'textual'"},{"fix":"Button('Click Me')","cause":"The Button widget requires a string 'label' argument to be provided during its instantiation.","error":"TypeError: Button.__init__() missing 1 required positional argument: 'label'"},{"fix":"Define a method in your App or Screen class: `def on_button_pressed(self, event: Button.Pressed): ...`","cause":"Textual uses a reactive event system where event handlers are defined as methods (e.g., 'on_button_pressed') in the App or Screen class, rather than being directly assigned to a widget attribute.","error":"AttributeError: 'Button' object has no attribute 'on_click'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.79,"mem_mb":13.5,"disk_size":"37.6M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":13.5,"disk_size":"38M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.86,"mem_mb":15.3,"disk_size":"41.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.7,"mem_mb":15.3,"disk_size":"42M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.95,"mem_mb":15.1,"disk_size":"33.2M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.94,"mem_mb":15.1,"disk_size":"34M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.92,"mem_mb":16,"disk_size":"32.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.91,"mem_mb":16,"disk_size":"33M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":13.5,"disk_size":"36.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.44,"mem_mb":13.5,"disk_size":"37M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}