7 lessons from building a modern TUI framework
Episode Deep Dive
Guest introduction and background
Will McGugan is a long-time Python developer and creator of the popular terminal formatting library Rich. He’s also the founder of Textualize.io where he and his team are building Textual, a framework for creating modern text user interfaces (TUIs). Will comes from a web-development background but has turned his focus to pushing the boundaries of what is possible in the terminal through rich formatting, advanced layout concepts, and even interactive mouse-driven interfaces.
What to Know If You're New to Python
Here are a few quick pointers from the episode to help new Python developers get the most out of this discussion:
- Learning Python’s basic data structures and control flow will help you understand how Textual and Rich handle complex rendering tasks.
- Libraries like Rich simplify terminal output, but you should still know basic I/O (e.g.,
print()
, reading files) before diving in. - Familiarize yourself with Python’s packaging and installation (e.g.,
pip install
) to easily experiment with Rich and Textual in your virtual environment.
Key points and takeaways
Modern TUIs Are Surprisingly Capable
Will and his team at Textualize.io are redefining text-based applications. Rather than simple static text, Textual can include animations, mouse interactions, and layout transitions that mirror web apps. This modern approach is built on top of Rich, giving developers higher-level abstractions to create sleek and dynamic interfaces right in the terminal.- Links and tools:
Terminals Are Faster Than You Think
Contrary to the idea that terminals are slow, modern terminals use GPU acceleration and can render at 60+ frames per second. Tools like Kitty, iTerm, and WezTerm are highly optimized for drawing text and colors quickly. This performance headroom makes high-framerate animations and smooth transitions possible.- Links and tools:
Rich CLI for Better Terminal Output
Beyond being a Python library, Rich can be installed as a command-line tool to pretty-print JSON, CSV, Markdown, and more. It can highlight syntax, add line numbers, or even give you a scrolling pager. This transforms your basiccat
ormore
commands into a polished developer experience.- Links and tools:
Leaning on Python’s Built-in
dict
Views
Will highlighted a powerful but underused Python feature:dict
views returned by.items()
,.keys()
, etc. These views behave like sets and can be intersected, unioned, or differenced to quickly detect changes in data structures. For example, Textual uses them to identify which UI elements changed and need redrawing.- Links and tools:
Caching for Performance with
functools.lru_cache
By wrapping small frequently-called functions with@lru_cache
, performance often skyrockets. Textual uses caching to speed up geometry calculations for layouts (e.g., intersecting rectangles). This approach is especially effective for “pure” functions whose return values never change for the same inputs.- Links and tools:
Why Immutability Helps
Will’s team often prefers immutable data structures (e.g., using namedtuples or “frozen” variants). Immutability removes edge cases where data changes unexpectedly, and it also works nicely with caching. This reduces bugs and confusion, leading to more maintainable code.Fractional Calculations Instead of Floats
Rounding errors from floating-point arithmetic led to glitches in positioning and layouts. By switching to Python’sFraction
, Textual can divide screen space or merge layout constraints exactly without weird off-by-one issues. Fractions eliminate those subtle decimal errors.- Links and tools:
Unicode Art and Diagrams in Code
Drawing small box diagrams in code comments or docstrings can make geometric logic much clearer. Will highlighted the Monodraw app for macOS, which lets you create ASCII/Unicode art as though it were vector graphics. This visual aid speeds up collaboration and onboarding for complex layout code.- Links and tools:
Challenges with Emojis and Wide Characters
Emojis and certain Unicode symbols can occupy one or two character cells. Different terminals and operating systems also disagree on how to render certain multi-code-point emojis. This can break table alignment and cause visual artifacts. Textual handles most common use cases but perfect cross-platform rendering remains difficult.- Links and tools:
Comparisons to “Old School” Tools Like Curses
Textual aims to replace or stand beside older TUI frameworks such as ncurses by providing higher-level building blocks. Rather than manually redrawing characters, developers can define widgets and layouts in a more web-like approach. This is closer to modern frameworks, making TUIs approachable for more Python devs.Community and Open-Core Business Model
Textual will remain open source, while Will’s company, Textualize, plans to offer a web-based hosting or “TUI as a Service” platform. Similar to how Streamlit or MongoDB monetize advanced or managed hosting, Textualize’s upcoming commercial offering aims to simplify deploying terminal apps on the web.Editor Preferences: VS Code vs. PyCharm
Will writes most of his code in VS Code but mentioned his colleague using PyCharm. Each has strengths such as integrated debugging, version control, or code intelligence. Editor choice often comes down to developer familiarity and comfort.
Interesting quotes and stories
- On Terminal Speed: “I was surprised at how smooth it was. We had 60 frames per second animation moving across the screen, and it looked silky smooth.”
- On Using Fractions: “I must have known about Python’s
Fraction
years ago, but I always thought, ‘Why would I need that?’ Turns out, it solved a ton of layout headaches.” - On Modern TUI vs. Curses: “It’s more abstract. You just place a button in this part of the screen, or a text box here, and Textual handles everything else.”
Key definitions and terms
- Textual: A modern Python TUI framework built atop Rich, offering advanced layouts, widgets, and animation in the terminal.
- Rich: A Python library for rich text, color, and formatting in the terminal (including tables, syntax highlighting, progress bars, etc.).
- Double-width characters: Unicode characters (often East Asian or emoji) that occupy two columns in a terminal rather than one.
- Fractions: Python’s standard library class for exact rational arithmetic, avoiding floating-point rounding issues.
Learning resources
If you want to deepen your Python skills, here are some courses from Talk Python Training:
- Python for Absolute Beginners: A thorough, hands-on introduction to Python.
- Getting started with pytest: Learn how to test your projects effectively, including terminal-driven tests.
- Full Web Apps with FastAPI: If you want to complement your TUI with a modern Python web framework.
Overall takeaway
Terminals might seem retro, but they’re more vibrant and capable than ever. Will McGugan’s work on Rich and Textual leverages hardware acceleration, clever Python techniques like caching and immutability, and creativity around layout and animations to deliver modern, “web-like” terminal applications. This episode highlights how far the terminal platform has come and what’s possible when you combine solid engineering with a curiosity to push boundaries. Whether you’re building a developer tool, a personal project, or a commercial application, Textual opens up an exciting new frontier for Python TUIs.
Links from the show
7 things I've learned building a modern TUI framework post: textualize.io
Prior Talk Python Episode: talkpython.fm
Textualize: textualize.io
Kitty terminal: sw.kovidgoyal.net
Pydantic Immutability: pydantic-docs.helpmanual.io
Monodraw: monodraw.helftone.com
Async's lru cache: github.com
Rich CLI: github.com
Nerd Fonts: nerdfonts.com
Oh My Posh: ohmyposh.dev
Python Object Allocator ASCII Art: github.com
Balsamiq wireframes: balsamiq.com
Watch this episode on YouTube: youtube.com
Episode transcripts: talkpython.fm
--- Stay in touch with us ---
Subscribe to Talk Python on YouTube: youtube.com
Talk Python on Bluesky: @talkpython.fm at bsky.app
Talk Python on Mastodon: talkpython
Michael on Bluesky: @mkennedy.codes at bsky.app
Michael on Mastodon: mkennedy