
Tui Design
- 978 installs
- 25 repo stars
- Updated July 31, 2026
- hyperb1iss/hyperskills
Tui-design is a Claude Code skill that catalogs proven real-world terminal UI layouts, interaction patterns, and spatial organization from production TUI apps for developers building their own CLI interfaces.
About
Tui-design is a Claude Code skill from hyperb1iss/hyperskills that functions as a design-pattern gallery for terminal user interfaces. It analyzes production TUIs such as lazygit—a Go gocui fork with five left panels plus a right detail column—and extracts layout, focus, and keybinding innovations like contextual footer actions that change per focused panel. Patterns cover persistent multi-panel layouts, popup layering, and zero-memorization interaction goals. Reach for tui-design when planning a new CLI dashboard, refactoring panel navigation, or benchmarking spatial organization against established tools before writing gocui, bubbletea, or similar terminal UI code.
- In-depth analysis of lazygit as the gold-standard 5-panel persistent layout with contextual keybinding footers
- Real-time dashboard patterns from lazydocker including live ASCII graphs and master-detail tabs
- Focus on spatial memory, popup layering, command transparency and progressive disclosure workflows
- Framework-specific implementation notes (Go/gocui) paired with UX rationale for every pattern
- Gallery format for rapid inspiration when designing new TUIs
Tui Design by the numbers
- 978 all-time installs (skills.sh)
- +19 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #428 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hyperb1iss/hyperskills --skill tui-designAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 978 |
|---|---|
| repo stars | ★ 25 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 31, 2026 |
| Repository | hyperb1iss/hyperskills ↗ |
What layout patterns work best for multi-panel TUIs?
Study proven real-world TUI layouts, interaction patterns, and spatial organization before building their own terminal interfaces.
Who is it for?
Developers building CLI dashboards or developer tools who want proven TUI layout and keybinding patterns before coding terminal UI frameworks.
Skip if: Web or mobile UI work, or teams shipping headless CLIs with no interactive terminal interface requirements.
When should I use this skill?
User designs a terminal UI, asks about panel layouts, contextual keybindings, or TUI interaction patterns for CLI tools.
What you get
TUI pattern references, panel layout diagrams, and interaction precedents from production terminal apps
- TUI layout pattern references
- interaction design precedents
Files
TUI Design System
Universal design patterns for building exceptional terminal user interfaces. Framework-agnostic, works with Ratatui, Ink, Textual, Bubbletea, or any TUI toolkit.
Core philosophy: TUIs earn their power through spatial consistency, keyboard fluency, and information density that respects human attention. Design for the expert's speed without abandoning the beginner's discoverability.
TUI Design Process
digraph tui_design {
rankdir=TB;
"What are you building?" [shape=diamond];
"Select layout paradigm" [shape=box];
"Design interaction model" [shape=box];
"Define visual system" [shape=box];
"Validate against anti-patterns" [shape=box];
"Ship it" [shape=doublecircle];
"What are you building?" -> "Select layout paradigm";
"Select layout paradigm" -> "Design interaction model";
"Design interaction model" -> "Define visual system";
"Define visual system" -> "Validate against anti-patterns";
"Validate against anti-patterns" -> "Ship it";
}---
1. Layout Paradigm Selector
Choose your primary layout based on what you're building:
| App Type | Paradigm | Examples |
|---|---|---|
| File manager | Miller Columns | yazi, ranger |
| Git / DevOps tool | Persistent Multi-Panel | lazygit, lazydocker |
| System monitor | Widget Dashboard | btop, bottom, oxker |
| Data browser / K8s | Drill-Down Stack | k9s, diskonaut |
| SQL / HTTP client | IDE Three-Panel | harlequin, posting |
| Shell augmentation | Overlay / Popup | atuin, fzf |
| Log / event viewer | Header + Scrollable List | htop, tig |
Persistent Multi-Panel
All panels visible simultaneously. Focus shifts between them. Users build spatial memory, "branches are always top-left."
┌─ Status ──┬─────────── Detail ──────────┐
├─ Files ───┤ │
│ > file.rs │ diff content here... │
│ main.rs │ │
├─ Branches ┤ │
│ * main │ │
│ feat/x │ │
├─ Commits ─┤ │
│ abc1234 │ │
└───────────┴──────────────────────────────┘
[q]uit [c]ommit [p]ush [?]helpWhen to use: Multi-faceted tools where users need simultaneous context (git clients, container managers, monitoring). Key rule: Panels maintain fixed positions across sessions. Never rearrange without user action.
Miller Columns
Three-pane past/present/future navigation. Parent directory (left), current (center), preview (right).
┌── Parent ──┬── Current ──┬── Preview ────────┐
│ .. │ > config/ │ port: 8080 │
│ src/ │ lib/ │ host: localhost │
│ > config/ │ main.rs │ log_level: debug │
│ tests/ │ mod.rs │ db_url: postgres://│
└────────────┴─────────────┴───────────────────┘When to use: Hierarchical data navigation (file systems, tree structures, nested configs). Key rule: Preview pane content adapts to selection type, code gets highlighting, images render, directories show contents.
Drill-Down Stack
Enter descends, Esc ascends. Browser-like navigation through hierarchical data.
When to use: Deep hierarchies where showing all levels simultaneously is impractical (Kubernetes resources, database schemas). Key rule: Always show the current navigation path as a breadcrumb. Provide :resource command-mode for direct jumps.
Widget Dashboard
Self-contained widget panels with independent data. All information visible at once, no navigation required.
┌─── CPU ──────────────┬─── Memory ──────────┐
│ ▁▂▃▅▇█▇▅▃▂▁▂▃▅▇ │ ████████░░ 78% │
│ core0: 45% core1: 67%│ 12.4G / 16.0G │
├─── Network ──────────┼─── Disk ────────────┤
│ ▲ 1.2 MB/s ▼ 340KB/s│ /: 67% /home: 45% │
├─── Processes ────────┴─────────────────────┤
│ PID USER CPU% MEM% CMD │
│ 1234 root 23.4 4.5 postgres │
└─────────────────────────────────────────────┘When to use: Monitoring, real-time status, system dashboards. Key rule: Each widget is self-contained with its own title. Use braille/block characters for high-density data.
IDE Three-Panel
Sidebar (left), editor/main (center), detail/output (bottom). Tab bar along top.
When to use: Editing-focused tools (SQL clients, HTTP tools, config editors). Key rule: Sidebar toggles with a single key. Center panel supports tabs. Bottom panel can expand to full height.
Overlay / Popup
TUI appears on demand over the shell, disappears after use.
When to use: Shell augmentations (history search, file picker, command palette). Key rule: Configurable height. Return selection to the caller. Never disrupt scrollback.
Header + Scrollable List
Fixed header with meters/stats, scrollable data below, function bar at bottom.
When to use: Single-list tools with metadata (process viewers, log viewers, sorted listings). Key rule: The header creates a natural "overview then detail" reading flow. Sort by the most actionable dimension by default.
---
2. Responsive Terminal Design
Terminals resize. Your TUI must handle it gracefully.
| Strategy | When |
|---|---|
| Proportional split | Panels maintain percentage ratios on resize |
| Priority collapse | Less important panels hide first below minimum width |
| Stacking | Panels collapse to title-only bars, active one expands (zellij pattern) |
| Breakpoint modes | Switch layout entirely below a threshold (e.g., multi-panel → single panel) |
| Minimum size gate | Display "terminal too small" if below usable minimum |
Rules:
- Define a minimum terminal size (typically 80x24). Below that, show a resize message.
- Never crash on resize. Handle
SIGWINCHgracefully. - Use constraint-based layouts (percentages, min/max, ratios), not absolute positions.
- Test at 80x24, 120x40, and 200x60 to verify scaling.
---
3. Interaction Model
Navigation Style Selector
| App Complexity | Recommended Model |
|---|---|
| Single-purpose, <20 actions | Direct keybinding (every key = action) |
| Multi-view, complex | Vim-style modes + contextual footer |
| IDE-like, many features | Command palette + tabs + vim motions |
| Data browser | Drill-down + fuzzy search + : command mode |
Keyboard Design Layers
Design keybindings in four progressive layers:
| Layer | Keys | Audience | Always show? |
|---|---|---|---|
| L0: Universal | Arrow keys, Enter, Esc, q | Everyone | Yes (footer) |
| L1: Vim motions | hjkl, /, ?, :, gg, G | Intermediate | Yes (footer) |
| L2: Actions | Single mnemonics: d(elete), c(ommit), p(ush) | Regular users | On ? help |
| L3: Power | Composed commands, macros, custom bindings | Power users | Docs only |
Keybinding conventions (lingua franca):
j/k, move down/uph/l, move left/right (or collapse/expand)/, search?, help overlay:, command modeq, quit (orEscto go back one level)Enter, select / confirm / drill inTab, switch focus between panelsSpace, toggle selectiong/G, jump to top/bottom
Never bind: Ctrl+C (interrupt), Ctrl+Z (suspend), Ctrl+\ (quit signal). These belong to the terminal.
Focus Management
- Only one widget receives keyboard input at a time
- Tab cycles focus forward, Shift+Tab backward
- Focus indicator: highlighted border, color change, or cursor presence
- Unfocused panels: dimmed or thinner borders
- Modal dialogs create focus traps, background receives no events
- Nested focus: outer container routes events to focused child
Search & Filtering
The universal pattern: press /, type query, results filter live.
n/N, next/previous matchEsc, dismiss search- Fuzzy matching by default,
'prefix for exact match - Highlight matched characters in results
- Preview pane updates for highlighted result
Help System: Three Tiers
| Tier | Trigger | Content | Audience |
|---|---|---|---|
| Always visible | Footer bar | 3-5 essential shortcuts | Everyone |
| On demand | ? key | Full keybinding overlay for current context | Regular users |
| Documentation | --help, man page | Complete reference | Power users |
Footer format: [q]uit [/]search [?]help [Tab]focus [Enter]select
Context-sensitive footers update based on the active panel or mode. Show only what's actionable _right now_.
Dialogs & Confirmation
| Action Severity | Pattern |
|---|---|
| Reversible | Just do it, show brief confirmation in status bar |
| Moderate (delete file) | Inline "Press y to confirm" |
| Severe (drop database) | Modal dialog requiring resource name input |
| Irreversible batch | --dry-run flag + explicit confirmation |
- Modal overlays: render popup on top of dimmed/blurred background
- Toast notifications: auto-dismiss after 3-5 seconds, no interaction required
- Status bar messages: vim-style one-liner feedback, auto-fade
---
4. Color Design System
Terminal Color Tiers
Design for graceful degradation across all three tiers:
| Tier | Escape Sequence | Colors | Strategy |
|---|---|---|---|
| 16 ANSI | \033[31m | 16 (relative) | Foundation. Terminal theme controls appearance. |
| 256 Color | \033[38;5;{n}m | 256 (16 relative + 240 fixed) | Extended palette. Fixed colors may clash with themes. |
| True Color | \033[38;2;{r};{g};{b}m | 16.7M (absolute) | Full control. Requires COLORTERM=truecolor. |
Detection hierarchy:
1. $COLORTERM = truecolor or 24bit → true color 2. $TERM contains 256color → 256 colors 3. $NO_COLOR is set → disable all color 4. Default → 16 ANSI colors
Golden rule: Your TUI must be _usable_ in 16-color mode. True color _enhances_, it never _creates_ the hierarchy.
Semantic Color Slots
Define colors by function, not appearance. Map semantics to actual colors through your theme:
| Slot | Purpose | Typical Dark Theme |
|---|---|---|
fg.default | Body text | Off-white (#c0caf5) |
fg.muted | Secondary text, metadata | Gray (#565f89) |
fg.emphasis | Headers, focused items | Bright white (#e0e0e0) |
bg.base | Primary background | Near-black (#1a1b26) |
bg.surface | Panel/widget backgrounds | Slightly lighter (#24283b) |
bg.overlay | Popup/dialog backgrounds | Lighter still (#414868) |
bg.selection | Selected item highlight | Distinct (#364a82) |
accent.primary | Interactive elements, focus | Brand color (#7aa2f7) |
accent.secondary | Supporting interactions | Complementary (#bb9af7) |
status.error | Errors, deletions | Red (#f7768e) |
status.warning | Warnings, caution | Yellow (#e0af68) |
status.success | Success, additions | Green (#9ece6a) |
status.info | Informational | Cyan (#7dcfff) |
Never hardcode hex values in widget code. Always reference semantic slots.
Visual Hierarchy Techniques
Color is one tool among several. Use them in combination:
| Technique | Effect | Use For |
|---|---|---|
| Bold (SGR 1) | Increases visual weight | Headers, labels, active items |
| Dim (SGR 2) | Decreases visual weight | Metadata, timestamps, secondary info |
| Italic (SGR 3) | Semantic distinction | Comments, types, annotations |
| Underline (SGR 4) | Links, actionable items | Clickable elements, URLs |
| Reverse (SGR 7) | Swaps fg/bg | Selection highlight (always works!) |
| Strikethrough (SGR 9) | Negation | Deleted items, deprecated features |
Hierarchy recipe: 80% of content in fg.default. Headers in bold + fg.emphasis. Metadata in dim + fg.muted. Status in their semantic colors. Accents for interactive elements only.
Background Layering
Create depth without borders by layering background lightness:
bg.base (darkest) → bg.surface → bg.overlay (lightest)Each step ~5-8% lighter in dark themes. The eye perceives depth from the contrast gradient. This reduces the need for box-drawing borders while maintaining clear visual zones.
Theme Architecture
Follow the Base16 pattern: define 16 named color slots, map them semantically:
- 8 monotones (base00-base07): background/foreground gradient
- 8 accents (base08-base0F): syntax/semantic colors
Ship a dark theme by default. Detect light/dark terminal via OSC escape query or terminal-light crate. Provide at least one light variant. Respect NO_COLOR.
Accessibility Requirements
- WCAG AA contrast: 4.5:1 ratio for body text, 3:1 for large text/UI elements
- Never use color alone: Pair with symbols (checkmark, X, triangle), text labels, position, or typography
- Color blindness safe pairs: blue+orange, blue+yellow, black+white. Avoid relying on red vs green.
- Test: monochrome mode, color blindness simulator, 3+ terminal emulators, light and dark themes
---
5. Data Visualization
Character-Resolution Building Blocks
| Element | Characters | Resolution | Use For |
|---|---|---|---|
| Full blocks | █▉▊▋▌▍▎▏ | 8 steps/cell | Progress bars, bar charts |
| Shade blocks | ░▒▓█ | 4 densities | Heatmaps, density plots |
| Braille | ⠁⠂⠃...⣿ (U+2800-U+28FF) | 2x4 dots/cell | High-res line graphs, scatter plots |
| Sparkline | ▁▂▃▄▅▆▇█ | 8 heights | Inline mini-charts |
Common Widgets
| Widget | Pattern | Tips |
|---|---|---|
| Progress bar | [████████░░░░] 67% | Show percentage + ETA. Color gradient green→yellow→red by urgency. |
| Sparkline | ▁▂▃▅▇█▇▅▃▂ | Perfect for inline time-series in headers/status bars. |
| Gauge | CPU [██████████░░] 83% | Label + bar + value. Color by threshold. |
| Table | Sortable columns, zebra stripes | Align numbers right, text left. Truncate with …. |
| Tree | ├── , └── , │ guides | Indent 2-4 chars per level. Expand/collapse with Enter. |
| Diff | Green + lines, red - lines | Word-level highlighting within changed lines elevates quality. |
| Log | Colored level, timestamp, message | TRACE=dim, DEBUG=cyan, INFO=default, WARN=yellow, ERROR=red, FATAL=red+bold. |
Spinner Selection
| Context | Spinner | Interval |
|---|---|---|
| Default / modern | Braille dots ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ | 80ms |
| Minimal | Line `-\ | /` |
| Heavy processing | Blocks ▖▘▝▗ | 100ms |
| Fun / branded | Custom frames | 70-100ms |
Use spinners for indeterminate operations. Progress bars for determinate. Show spinners only after 200ms delay to avoid flash on fast operations.
---
6. Animation & Motion
Flicker-Free Rendering Stack
Three layers, all required for smooth TUI rendering:
1. Double buffering: Render to off-screen buffer, diff against previous frame, emit only changed cells 2. Synchronized output: Wrap frame in CSI ? 2026 h ... CSI ? 2026 l for atomic terminal render 3. Batched writes: Combine all escape sequences into a single write() syscall
When to Animate
| Situation | Animation | Duration |
|---|---|---|
| View transition | Fade or slide | 100-200ms |
| Selection change | Instant highlight | 0ms (never animate) |
| Data loading | Spinner or skeleton | Until complete |
| Success feedback | Brief flash/checkmark | 1-2 seconds |
| Panel resize | Immediate reflow | 0ms |
| Chart data update | Smooth value transition | 200-500ms |
Rule: Animations must never delay user input. If the user presses a key during a transition, cancel it and respond immediately.
Real-Time Updates
- Cap refresh to 15-30 FPS for dashboards (saves CPU, prevents flicker)
- Use differential updates, only redraw changed cells
- Stream text (AI responses, logs) at a readable pace, not network burst speed
- Background operations: show status in a status bar widget, never block the main loop
---
7. The Seven Design Principles
1. Keyboard-first, mouse-optional: Every feature accessible via keyboard. Mouse enhances but never replaces. Shift+click must bypass mouse capture for text selection.
2. Spatial consistency: Panels stay in fixed positions. Users build mental maps. Never rearrange without explicit user action. Tabs provide stable landmarks.
3. Progressive disclosure: Show 5 essential shortcuts in the footer. Full help behind ?. Complete reference in docs. The floor is accessible, the ceiling is unlimited.
4. Async everything: Never freeze the UI. File operations, network requests, scans all run in the background with progress indication. Cancel with Esc.
5. Semantic color: Color encodes meaning, not decoration. If you removed all color, the interface should still be _usable_ through layout, typography, and symbols.
6. Contextual intelligence: Keybindings update per panel. Status bars reflect current state. Help shows what's actionable right now, not everything ever.
7. Design in layers: Start monochrome (usable?). Add 16 ANSI colors (readable?). Layer true color (beautiful?). Each tier must stand independently.
---
Anti-Patterns
Validate your design against these ranked pitfalls (ordered by real-world complaint frequency):
| # | Anti-Pattern | Fix |
|---|---|---|
| 1 | Colors break on different terminals | Use 16 ANSI colors as foundation. Test 3+ emulators + light/dark themes. |
| 2 | Flickering / full redraws | Double buffer + synchronized output + batched writes. Overwrite, never clear. |
| 3 | Undiscoverable keybindings | Context-sensitive footer + ? help overlay + Which-Key-style hints. |
| 4 | Broken on Windows / WSL | Test on Windows Terminal. Avoid advanced Unicode beyond box-drawing. |
| 5 | Unicode rendering inconsistency | Stick to box-drawing + block elements. Restrict emoji to Unicode 9.0. |
| 6 | Terminal multiplexer incompatibility | Test inside tmux and zellij. Mouse capture must not break selection. |
| 7 | No accessibility support | Respect NO_COLOR, provide monochrome mode, never color-only meaning. |
| 8 | Blocking UI during operations | Show feedback within 100ms. Use async + spinners + progress bars. |
| 9 | Modal confusion | Always show current mode in status bar. Cursor shape changes per mode. |
| 10 | Over-decorated chrome | Borders and colors serve content, not ego. The content IS the interface. |
9. Compatibility Checklist
Before shipping, verify:
- [ ] Works at 80x24 minimum terminal size
- [ ] Handles terminal resize without crash
- [ ] Looks correct on dark AND light terminal themes
- [ ] Respects
NO_COLORenvironment variable - [ ] Works inside tmux / zellij / screen
- [ ] Functions over SSH (no features require local-only protocols)
- [ ] Mouse capture doesn't break text selection (
Shift+click) - [ ] All features accessible via keyboard alone
- [ ] No ANSI escape sequence leaks to piped/redirected output
- [ ] Exits cleanly on
Ctrl+C/SIGINT(restores terminal state)
---
For Unicode character reference tables and border style gallery, see visual-catalog.md. For real-world TUI app design analysis and inspiration, see app-patterns.md.
What This Skill is NOT
- Not a framework-specific API reference.
- Not an excuse to over-decorate terminal tools.
- Not a replacement for testing in real terminal emulators.
- Not only for Rust; the patterns apply across TUI frameworks.
TUI App Design Patterns Gallery
Real-world design analysis of exceptional TUI applications, organized by the pattern they exemplify. Use for inspiration and precedent when designing your own TUI.
---
Persistent Multi-Panel Pattern
lazygit — The Gold Standard
Framework: Go (gocui fork) | Layout: 5 left panels + right detail
The defining multi-panel TUI. All views (status, files, branches, commits, stash) remain visible simultaneously. The left column acts as a selector; the right column shows context for the selected item.
Key innovations:
- Contextual keybinding footer — available actions update as focus changes. Goal: zero memorization.
- Popup layering — confirmation dialogs and commit editors appear as overlays without losing spatial context.
- Command transparency — shows the actual git commands being executed under the hood.
- Guided multi-step workflows — interactive rebase, conflict resolution use progressive disclosure through confirmations.
Why it works: Users build spatial memory. Branches are _always_ top-left, commits are _always_ middle-left. No navigation required to see the full picture.
lazydocker — Real-Time Dashboard Variant
Framework: Go (gocui) | Layout: Master list (left) + detail tabs (right)
Two-pane horizontal split. Left switches between Docker objects; right shows live detail with tabs for logs, stats, config. Live ASCII resource graphs render directly in the detail pane.
Key innovation: Docker Compose awareness — auto-groups containers into "Services" and "Standalone." The layout adapts to project structure.
oxker — Single-Screen Everything
Framework: Rust (Ratatui) | Layout: All panels always visible
Containers list, logs, CPU charts, memory charts, and port mappings visible simultaneously. No tabs, no drill-down. Click-sortable column headers bring spreadsheet interaction to the terminal.
Key innovation: Mixed input — full keyboard AND mouse support. Neither forced; both first-class.
---
Drill-Down Stack Pattern
k9s — Command-Mode Navigation
Framework: Go (tcell/tview) | Navigation: Enter descends, Esc ascends, :resource jumps
The Kubernetes TUI. An infinite drill-down through resources: cluster → namespace → deployment → pod → container → logs.
Key innovations:
- `:resource` command mode — type
:pods,:deploymentsto jump directly. The TUI equivalent of a URL bar. - XRay mode — unique tree visualization showing a resource and all its related resources across types.
- Pulse view — heads-up display of cluster health metrics.
- Context-aware skins — different color schemes per Kubernetes cluster. Production is visually distinct from staging. Safety through color.
Why it works: The command-mode (:) plus drill-down (Enter/Esc) creates two navigation dimensions — direct jumps for known targets, exploration for discovery.
diskonaut — Spatial Treemap
Framework: Rust (tui-rs) | Navigation: Arrow keys select blocks, Enter drills in
The entire terminal fills with rectangles proportional to file/directory size. A genuine treemap visualization in text mode.
Key innovations:
- Progressive scanning — treemap builds in real-time as filesystem scan progresses. Explore already-scanned regions while scanning continues.
- Zoom levels —
+/-reveal smaller files that appear asxat default zoom. - Deletion tracking — inline delete with cumulative freed-space counter.
Why it works: Spatial reasoning. You literally _see_ which files are largest by their visual area. No need to compare numbers.
---
Miller Columns Pattern
yazi — Async-First File Management
Framework: Rust (Ratatui + Tokio) | Layout: 3 columns: parent / current / preview
The modern file manager. Miller columns with async I/O for never-blocking navigation.
Key innovations:
- Inline image previews — renders images directly in terminal via auto-detected protocols (Kitty, iTerm2, Sixel).
- Async architecture — dual-priority task queue (micro: metadata reads, macro: file transfers). UI never freezes.
- Smart preview preloading — predictive loading based on cursor position. Code gets syntax highlighting, images get decoded, archives get listed.
- Concurrent Lua plugins —
ya.sync()andya.async()modes for parallel plugin execution.
Why it works: The "never freeze" principle. Large directories, slow network mounts, big file previews — the interface stays responsive. The three-column layout provides past/present/future spatial context at every level.
ranger — Vim-Native Miller Columns
Framework: Python (curses) | Navigation: hjkl maps to column movement
The original vim-keybinding file manager. h goes up a directory (left column), l enters (right column).
Key innovation: Bookmarks (m<key> to set, '<key> to jump) provide teleportation — bypass hierarchical navigation entirely.
---
Tab-Based Workspace Pattern
gitui — Performance as UX
Framework: Rust (Ratatui) | Layout: 5 top tabs, split panes within each
Five tabs (Status, Log, Files, Stashing, Stashes) provide persistent navigation landmarks. Each tab is a focused workspace.
Key innovations:
- Line-level staging — stage individual hunks or lines in the diff view.
- Single-key mnemonics — interface shows
[c]ommit [a]mend [p]ushdirectly inline. - Performance — 2× faster than lazygit with 1/15th memory on the Linux kernel repo (900k+ commits). Speed changes interaction patterns — users browse and explore rather than search-and-jump.
Why it works: When navigating 900k commits feels instant, speed becomes a design feature.
harlequin — Terminal IDE
Framework: Python (Textual) | Layout: 3 panels: catalog / editor / results
Full SQL IDE in the terminal. Data catalog tree (left), tabbed query editor (center), virtualized results table (bottom).
Key innovations:
- 1M+ row virtual tables — scrollable results that don't load everything into memory.
- Full-screen toggle —
F10expands any panel to fill the terminal (IDE "zen mode"). - 12+ community themes — Catppuccin, Dracula, Nord, Monokai out of the box.
- Adapter plugins — database backends installed as pip packages.
Why it works: Proves that "terminal = limited" is a myth. DBeaver-level functionality with htop-level responsiveness.
---
Overlay / Popup Pattern
atuin — Augmented Shell Primitive
Framework: Rust (Ratatui) | Trigger: Replaces Ctrl+R
Replaces the 40-year-old Ctrl+R shell history with a full TUI overlay that appears on demand and disappears after selection.
Key innovations:
- Multi-dimensional filtering — toggle filters for host, session, directory, and global scope.
- Rich metadata — each entry shows command, duration, exit code, host, timestamp.
- Configurable density — from single-line fzf-style to full-screen explorer.
- Cross-device sync — encrypted history sync across machines.
Why it works: The "popup TUI" pattern — summoned, used, dismissed. Invisible when not needed. Transforms a basic shell feature with structure and intelligence.
posting — IDE Patterns in Terminal
Framework: Python (Textual) | Layout: IDE three-panel with innovations
HTTP client for terminals. The Postman-for-terminal that introduced several novel TUI interaction patterns.
Key innovations:
- Jump mode — Vimium-style: press a key, letter overlays appear on every interactive element, press the letter to jump directly. Eliminates Tab cycling entirely.
- Command palette —
Ctrl+Popens VS Code-style fuzzy command search. - YAML-based request storage — git-friendly, version-controllable, team-shareable.
- Environment-aware styling — production URLs get blinking red backgrounds as visual safety rails.
Why it works: Jump mode is genuinely novel for TUIs. Instead of navigating _through_ the interface to reach a target, users navigate _to_ the target directly.
---
Widget Dashboard Pattern
btop — Polished System Monitor
Framework: C++ (custom) | Layout: T-shaped grid of bordered widget boxes
Per-core CPU graphs, memory breakdown, network I/O, disk activity, and process table in a T-shaped dashboard.
Key innovations:
- Bordered box zones — each widget is a self-contained panel with title, creating a dashboard-of-dashboards.
- Braille sparklines — high-resolution graphs using Unicode braille characters.
- Theme ecosystem — rich theming with 24-bit truecolor and 256-color fallback.
bottom (btm) — Configurable Widget Composition
Framework: Rust (Ratatui) | Layout: Configurable widget grid
Similar to btop but the dashboard layout is configurable via TOML. Users define their own widget arrangement.
Key innovations:
- Braille + dot sparklines — Unicode braille default with dot marker fallback.
- Basic mode —
--basicflag strips graphs, shows htop-style tables only. Progressive complexity. - Battery and temperature — first-class hardware widgets beyond CPU/memory.
---
Terminal Multiplexer Pattern
zellij — Reimagined Workspace
Framework: Rust (custom) | Layout: Tiled + floating panes
Modern terminal multiplexer that treats the terminal as a workspace, not just a multiplexer.
Key innovations:
- Floating panes — first-class floating windows that overlay tiled panes. Toggle with
Alt+f. - Stacked panes — when resize shrinks a pane too small, it stacks with neighbors showing only title bars. The active one expands. Novel responsive behavior.
- Session resurrection — closed sessions preserve full state. Resurrect any previous session exactly.
- Modal keybinding — enter Pane mode, then use simple keys. Status bar shows current mode and available keys. Solves tmux's discoverability problem.
- KDL layout files — declarative, version-controllable workspace definitions.
- WASM plugins — sandboxed, crash-proof, language-agnostic extensions.
---
Classic Patterns Still Relevant
vim/neovim — Composable Grammar
The interaction model where keystrokes compose as a language: d2w = "delete 2 words." Grammar: {operator}{count}{motion}. The key insight: composable grammar over memorized shortcuts.
Modern extensions: Telescope (fuzzy finder popup), Which-Key (shows continuations after prefix), floating windows for previews.
tmux — Prefix Key Namespace
All commands sit behind a prefix key (Ctrl+b), preventing collisions with inner programs. The status bar as wayfinding strip pattern — a single persistent line showing session/window/pane context.
htop — Semantic Color Encoding
CPU meter colors encode meaning: green = user processes, red = kernel, blue = low-priority, cyan = virtualization overhead. Expert users diagnose system state at a glance from color ratios alone. Color as data channel, not decoration.
Midnight Commander — Orthodox File Manager
The dual-pane paradigm: source and destination simultaneously visible. Tab switches active panel. File operations default to using the opposite panel as destination. 40 years old and still unbeaten for power-user file manipulation.
tig — View Stack Navigation
Views push onto a navigation stack. Close a view → return to previous. Browser-like back-navigation through git data. Master-detail split: list view above, detail below. The view stack pattern makes complex data navigable.
---
Cross-Cutting Insights
1. The best TUIs feel alive — real-time updates, responsive to every keypress, async operations never freeze. 2. Spatial consistency builds mastery — users remember _where_ things are, not _how_ to find them. 3. The modern TUI trinity — command palette + vim motions + contextual footer covers every skill level. 4. Speed is a feature — sub-millisecond response to keypresses creates a fundamentally different interaction quality. 5. Configuration as code — YAML/TOML/KDL config files enable version control, sharing, and reproducibility. 6. Every great TUI has an escape hatch — q to quit, Esc to go back, ? for help. Always.
TUI Visual Catalog
Pure reference material for terminal visual elements. Scan, don't read.
Box-Drawing Characters
Light (standard TUI borders)
┌───┬───┐ Corners: ┌ ┐ └ ┘
│ │ │ T-pieces: ├ ┤ ┬ ┴
├───┼───┤ Cross: ┼
│ │ │ Lines: ─ │
└───┴───┘Heavy (emphasis borders)
┏━━━┳━━━┓ Corners: ┏ ┓ ┗ ┛
┃ ┃ ┃ T-pieces: ┣ ┫ ┳ ┻
┣━━━╋━━━┫ Cross: ╋
┃ ┃ ┃ Lines: ━ ┃
┗━━━┻━━━┛Double (classic DOS/Norton style)
╔═══╦═══╗ Corners: ╔ ╗ ╚ ╝
║ ║ ║ T-pieces: ╠ ╣ ╦ ╩
╠═══╬═══╣ Cross: ╬
║ ║ ║ Lines: ═ ║
╚═══╩═══╝Rounded (modern, friendly)
╭───┬───╮ Corners: ╭ ╮ ╰ ╯
│ │ │ (T-pieces, cross, lines
├───┼───┤ same as light set)
│ │ │
╰───┴───╯Mixed: Heavy Header + Light Body
┏━━━━━━━━━━━━━━━━━━━━┓
┃ Panel Title ┃
┡━━━━━━━━━━━━━━━━━━━━┩
│ Content here │
│ using light lines │
└─────────────────────┘When to Use Which
| Style | Use Case |
|---|---|
Light ─│ | Default panel borders, dividers, tables |
Heavy ━┃ | Active/focused panel, headers, emphasis |
Double ═║ | Legacy/retro aesthetic, prominent sections |
Rounded ╭╯ | Modern/friendly feel, cards, tooltips |
| Mixed heavy+light | Focus indicator (heavy = active, light = inactive) |
| No border | Background layering sufficient, minimal aesthetic |
---
Block Elements
Fractional Blocks (horizontal, left-to-right fill)
▏ ▎ ▍ ▌ ▋ ▊ ▉ █1/8 through 8/8 width. Use for sub-character precision in horizontal bar charts.
Fractional Blocks (vertical, bottom-to-top fill)
▁ ▂ ▃ ▄ ▅ ▆ ▇ █1/8 through 8/8 height. Use for sparklines and vertical bar charts.
Shade Blocks
░ Light shade (25%)
▒ Medium shade (50%)
▓ Dark shade (75%)
█ Full block (100%)Use for density visualization, heatmaps, and background patterns.
Progress Bar Recipes
Simple: [████████░░░░░░] 57%
Gradient: [█████▓▒░░░░░░░] 57%
Thin: ━━━━━━━━╸━━━━━━ 57%
Braille: ⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀ 57%
Minimal: ■■■■■■□□□□□□ 57%---
Braille Patterns (U+2800–U+28FF)
Each braille character is a 2-column × 4-row dot grid, encoding 8 bits:
Dot positions: ⠁(1) ⠂(2) ⠄(3) ⡀(7)
⠈(4) ⠐(5) ⠠(6) ⢀(8)
Combined: ⣿ = all dots ⠀ = empty (blank braille)Use for high-resolution terminal graphics. Each character cell provides 2×4 = 8 sub-pixels, enabling line charts, scatter plots, and pixel art at 2× horizontal and 4× vertical resolution.
Sparkline with Braille
Network: ⣀⣤⣶⣿⣶⣤⣀⣀⣤⣶⣿⣿⣶⣤ Peak: 1.2 MB/s---
Status Indicators
Dots and Bullets
● Filled circle (active, online, enabled)
○ Empty circle (inactive, offline, disabled)
◉ Bullseye (selected, current)
◆ Filled diamond (important, pinned)
◇ Empty diamond (available, optional)Check and Cross
✓ Check mark (success, done, yes) ✔ Heavy check
✗ Ballot X (failure, error, no) ✘ Heavy X
☐ Unchecked checkbox ☑ Checked checkboxSeverity/Priority
▲ Up triangle (increase, higher, expand)
▼ Down triangle (decrease, lower, collapse)
⚠ Warning sign
ℹ Information
⬤ Large circle (status dot)Arrows
Navigation: ← → ↑ ↓ ⇐ ⇒ ⇑ ⇓
Triangles: ◀ ▶ ▲ ▼ ◁ ▷ △ ▽
Pointers: ► ◄ ‣
Powerline: ▏ (thin separator)---
Tree Drawing
Standard Tree
├── src/
│ ├── main.rs
│ ├── lib.rs
│ └── utils/
│ ├── config.rs
│ └── helpers.rs
├── tests/
│ └── integration.rs
└── Cargo.tomlCharacters: ├── (branch), └── (last branch), │ (continuation), (spacing)
Compact Tree (for narrow panels)
├ src/
│ ├ main.rs
│ └ utils/
│ └ config.rs
└ Cargo.toml---
Table Formatting
Standard Table
┌──────┬────────┬───────┐
│ Name │ Status │ CPU % │
├──────┼────────┼───────┤
│ web │ ● Run │ 23.4 │
│ db │ ● Run │ 8.1 │
│ cache│ ○ Stop │ 0.0 │
└──────┴────────┴───────┘Minimal Table (no outer border)
Name Status CPU %
───── ────── ─────
web ● Run 23.4
db ● Run 8.1
cache ○ Stop 0.0Zebra Stripe (alternating background)
Use bg.surface on even rows, bg.base on odd rows for scanability.
---
Separator Styles
Light: ────────────────────────
Heavy: ━━━━━━━━━━━━━━━━━━━━━━━━
Double: ════════════════════════
Dashed: ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Dotted: ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
Mixed: ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
Labeled: ──── Section Title ──────---
Diff Presentation
Inline (unified)
fn process(data: &str) { (context - default color)
- let result = parse(data); (removed - red + dim)
+ let result = parse_v2(data); (added - green)
result.validate() (context - default color)
}Side-by-Side
│ fn process(data: &str) { │ fn process(data: &str) { │
│- let result = parse(data); │+ let result = parse_v2(data);│
│ result.validate() │ result.validate() │Word-level diff highlighting within changed lines dramatically improves readability. Highlight the changed words/tokens, not just the whole line.
---
Gauge Patterns
CPU: [████████████████████░░░░░░░░░░] 67%
Mem: [███████████████░░░░░░░░░░░░░░░] 50% 8.0G/16.0G
Disk: [██████████████████████████████] 99% ← red when >90%
Bat: [████████░░░░░░░░░░░░░░░░░░░░░] 27% ⚡ chargingColor thresholds: green (0-60%), yellow (60-80%), red (80-100%).
---
Common Nerd Font Icons
Only use when Nerd Font detection is available. Always provide a Unicode/ASCII fallback.
Nerd Font → Fallback
→ > (directory/folder)
→ * (file)
→ ⚙ (settings/config)
→ ● (git branch)
→ ✓ (success)
→ ✗ (error)
→ ⚠ (warning)
→ ℹ (info)Rule: Never assume Nerd Fonts are installed. Always define a fallback using standard Unicode or ASCII.
Related skills
How it compares
Use tui-design for terminal interface precedent; use web frontend design skills when the deliverable is a browser UI instead of a TUI.
FAQ
What TUI apps does tui-design analyze?
Tui-design profiles production terminal apps such as lazygit, a Go gocui fork using five left selector panels plus a right detail column, and extracts reusable layout and interaction innovations.
When should developers use tui-design?
Tui-design fits pre-implementation planning for CLI dashboards—choosing panel layout, focus behavior, and contextual keybindings—before writing gocui, bubbletea, or similar terminal UI code.
Is Tui Design safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.