DEV Community

Cover image for Introduction to Textual: Building Modern Text User Interfaces in Python
Developer Service
Developer Service

Posted on • Originally published at developer-service.blog

Introduction to Textual: Building Modern Text User Interfaces in Python

In the world of user interfaces, graphical user interfaces (GUIs) often steal the spotlight.

However, text-based user interfaces (TUIs) are making a comeback, offering powerful, lightweight, and cross-platform solutions for command-line applications.

If you’re a Python developer, the Textual library from Textualize.io provides a modern, feature-rich way to build stunning TUIs with ease.

This article introduces Textual, explains its core features, and walks you through how to create your first TUI application.


What is a TUI?

A Text User Interface (TUI) is a type of user interface that allows users to interact with a program through text-based commands and visual elements displayed in a terminal or command-line interface.

Unlike a Graphical User Interface (GUI), which relies on windows, icons, and buttons, a TUI uses characters, symbols, and text-based components to present information and receive input.

TUIs provide several advantages, including:

  • Lightweight: They require minimal system resources compared to GUIs.
  • Cross-Platform: TUIs work on any system with a terminal, including Linux, macOS, and Windows.
  • Fast and Efficient: Navigating with keyboard shortcuts is often faster than using a mouse in GUIs.
  • Accessible: TUIs can be used on remote servers via SSH, making them ideal for server administration and headless environments.

Classic examples of TUIs include text editors like vim and nano, command-line tools like htop (for system monitoring), and ranger (a file manager).

Modern TUIs, like those built with Textual, incorporate features like animations, custom styles, and interactive elements that go beyond traditional command-line interfaces.


What is Textual?

Textual is a Python framework for building interactive, modern TUIs using concepts that are familiar to web developers.

Instead of dealing with low-level console control sequences, Textual allows you to design responsive and interactive layouts using simple Python code.

Textual borrows concepts from web development, such as:

  • CSS-like Stylesheets: Customize the appearance of your TUI components.
  • Responsive Design: Applications that adapt to terminal size changes.
  • Widgets and Layouts: Reusable components like buttons, text areas, and panels.

Built on top of Rich (another library from the same developers), Textual inherits Rich’s capabilities for beautiful text formatting, syntax highlighting, and rendering.


Why Use Textual?

Here’s why Textual stands out for building TUIs:

  • Cross-Platform: Works on Linux, macOS, and Windows.
  • Interactive: Supports buttons, dialogs, and forms.
  • Asynchronous: Built with asyncio, enabling non-blocking operations.
  • Customizable: Customize widgets, animations, and styles.

If you've ever built a web app using frameworks like React or Vue, you’ll find Textual’s approach to components and layouts intuitive.


Installing Textual

To get started with Textual, you’ll need Python 3.7 or higher. Install it using pip:

pip install textual
Enter fullscreen mode Exit fullscreen mode

Once installed, you’re ready to build your first TUI application.


Creating Your First TUI Application

Here’s a simple example to create a "Hello, World!" TUI using Textual.

from textual.app import App
from textual.widgets import Header, Footer, Static

class HelloWorldApp(App):
    def compose(self):
        yield Header()
        yield Static("Hello, World!", id="hello-text")
        yield Footer()

if __name__ == "__main__":
    HelloWorldApp().run()
Enter fullscreen mode Exit fullscreen mode

Explanation:

  1. Header and Footer: Pre-built widgets for a consistent app layout.
  2. Static: A simple widget to display text.
  3. compose(): This method defines the layout and widgets to display.

Run the script and you’ll see a clean, interactive "Hello, World!" TUI app, like this:

Hello World TUI app


Key Components and Widgets

Textual comes with several pre-built widgets, and you can also create your own.

Here are some key widgets:

  • Header & Footer: Provide a consistent structure for your app.
  • Button: Interactive buttons for user input.
  • Input: Text input for user data.
  • TreeView: A collapsible tree structure, useful for file browsers.
  • Table: Display tabular data in a clean, readable format.

With these components, you can build dashboards, text editors, task managers, and more.


Styling Your TUI with CSS

One of Textual’s most appealing features is its CSS-like styling.

Each widget can be styled using a stylesheet that follows a syntax similar to CSS.

Here’s an example of a stylesheet:

#hello-text {
    color: green;
    background: black;
    border: round yellow;
}
Enter fullscreen mode Exit fullscreen mode

This stylesheet sets the text color, background color, and border style for the "hello-text" widget.

To apply the stylesheet, create a hello.tcss file and load it into the app:

class HelloWorldApp(App):
    CSS_PATH = "hello.tcss"
    def compose(self):
        yield Header()
        yield Static("Hello, World!", id="hello-text")
        yield Footer()
Enter fullscreen mode Exit fullscreen mode

Which styles the app like this:

Hello Word TUI app with CSS


Real-World Use Cases

Textual can be used in various projects, such as:

  • Dashboards: Display system metrics, logs, or real-time data.
  • Productivity Tools: To-do lists, notes, or time trackers.
  • Custom CLIs: Add interactivity and polish to command-line tools.
  • File Managers: Create file browsers like ranger but more interactive.

Here's an example of how a file manager could be built with Textual:

import os
from textual.app import App
from textual.widgets import Tree

class FileManagerApp(App):
    def compose(self):
        tree = Tree("Root Directory")
        self.populate_tree(tree.root, os.getcwd())
        yield tree

    def populate_tree(self, node, path):
        try:
            for entry in os.listdir(path):
                full_path = os.path.join(path, entry)
                if os.path.isdir(full_path):
                    sub_node = node.add(entry)
                    self.populate_tree(sub_node, full_path)
                else:
                    node.add(entry)
        except PermissionError:
            pass

if __name__ == "__main__":
    FileManagerApp().run()
Enter fullscreen mode Exit fullscreen mode

Which produces an app like this:

File Manager TUI app


Final Thoughts

The Textual library opens up new possibilities for Python developers to build beautiful, cross-platform TUIs with minimal effort.

Its modern approach, inspired by web development, makes it accessible to developers who are used to building web apps.

From simple utilities to full-fledged applications, Textual makes it possible to create polished command-line apps that users will love.

If you’re ready to elevate your CLI tools with TUIs, Textual is the library to explore.

Check out the official documentation at textual.textualize.io to dive deeper into its capabilities.


Follow me on Twitter: x.com

Follow me on Instagram at: Instagram

Follow me on TikTok at: TikTok - Make Your Day

Follow me on YouTube at: Developer Service - YouTube

Top comments (0)