This gives Claude the context to help you build terminal UIs with Textual's Python framework. It covers the full architecture from reactive state management and event handling to screens, custom widgets, and TCSS styling. The reference sheets for built-in widgets and CSS properties are especially handy when you're mid-build and can't remember if a DataTable emits RowSelected or CellSelected. Use this when you're scaffolding a new TUI app, debugging layout issues, or trying to figure out why your reactive variable isn't triggering a watch method. It's dense but organized well enough that Claude can pull what's relevant without drowning in the full Textual docs.
- skills.sh installs
- 258
- GitHub stars
- 21
- last updated
- Aug 21, 2026
Install
$ npx -y skills add johnlarkin1/claude-code-extensions --skill textual --agent claude-codeInstalls into .claude/skills of the current project.
Files
Textual TUI Framework
Build terminal applications with Textual's web-inspired architecture: App → Screen → Widget.
Quick Start
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static
class MyApp(App):
CSS_PATH = "styles.tcss"
BINDINGS = [("q", "quit", "Quit"), ("d", "toggle_dark", "Dark Mode")]
def compose(self) -> ComposeResult:
yield Header()
yield Static("Hello, World!")
yield Footer()
def action_toggle_dark(self) -> None:
self.theme = "textual-dark" if self.theme == "textual-light" else "textual-light"
if __name__ == "__main__":
MyApp().run()
Core Concepts
Widget Lifecycle
__init__()→compose()→on_mount()→on_show()/on_hide()→on_unmount()
Reactivity
from textual.reactive import reactive, var
class MyWidget(Widget):
count = reactive(0) # Triggers refresh on change
internal = var("") # No automatic refresh
def watch_count(self, new_value: int) -> None:
"""Called when count changes."""
self.styles.background = "green" if new_value > 0 else "red"
Sponsors
Details
- Repository
- github.com/johnlarkin1/claude-code-extensions
- Categories
- Testing & QA, DevOps & CI/CD, Python, CLI & Terminal
- First seen
- Jun 3, 2026
