rivo/tview
Terminal UI library with rich, interactive widgets — written in Golang
Mixed signals — read the receipts
worst of 4 axesno tests detected; no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 8w ago
- ✓23+ active contributors
- ✓MIT licensed
Show 3 more →Show less
- ⚠Concentrated ownership — top contributor handles 73% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: add a test suite
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/rivo/tview)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/rivo/tview on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: rivo/tview
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/rivo/tview shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 8w ago
- 23+ active contributors
- MIT licensed
- ⚠ Concentrated ownership — top contributor handles 73% of recent commits
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live rivo/tview
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/rivo/tview.
What it runs against: a local clone of rivo/tview — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in rivo/tview | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 84 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of rivo/tview. If you don't
# have one yet, run these first:
#
# git clone https://github.com/rivo/tview.git
# cd tview
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of rivo/tview and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "rivo/tview(\\.git)?\\b" \\
&& ok "origin remote is rivo/tview" \\
|| miss "origin remote is not rivo/tview (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "application.go" \\
&& ok "application.go" \\
|| miss "missing critical file: application.go"
test -f "box.go" \\
&& ok "box.go" \\
|| miss "missing critical file: box.go"
test -f "ansi.go" \\
&& ok "ansi.go" \\
|| miss "missing critical file: ansi.go"
test -f "button.go" \\
&& ok "button.go" \\
|| miss "missing critical file: button.go"
test -f "borders.go" \\
&& ok "borders.go" \\
|| miss "missing critical file: borders.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 84 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~54d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/rivo/tview"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
tview is a pure Go terminal UI library that renders rich, interactive widgets directly to the terminal using tcell/v2 for low-level cell-based drawing. It provides form inputs, tables, trees, lists, text areas, grids, and layout primitives—eliminating the need to write escape sequences or manage terminal state manually when building TUI applications. Monolithic single-package library: core widget implementations (box.go, button.go, checkbox.go, form.go, table.go, tree.go, etc.) live at repo root; demos/ directory contains ~15 self-contained example programs (each with main.go, README, screenshot) demonstrating individual widgets and layouts; application.go wraps the main event loop and renderer.
👥Who it's for
Go developers building command-line tools and dashboards (like K9s for Kubernetes, redis-terminal, and LDAP TUIs) who need a high-level widget toolkit instead of wrestling with ncurses bindings or raw terminal I/O.
🌱Maturity & risk
Actively maintained and production-ready. Requires Go 1.18+, depends on stable upstream tcell/v2 and go-colorful, with numerous real-world projects shipping it (K9s, IRCCloud client, Redis browsers). Evidence of active codebase (~510KB Go code) and demo coverage across ~15+ widget types suggests maturity, though commit recency and formal test suite visibility are not provided in this snapshot.
Low-risk dependencies: only 3 core imports (tcell/v2, go-colorful, uniseg) plus indirect transitive deps on encoding/term/text. Single maintainer (rivo) may pose long-term maintenance risk if unresponsive. No visibility into CI/CD setup or test coverage from file structure alone, so automated quality gates are unclear.
Active areas of work
No PR, milestone, or commit metadata visible in the provided snapshot. The file structure shows mature, complete coverage of form widgets, layouts (grid/flex), and text views—suggesting the project is in steady-state maintenance rather than active feature development. Real-world projects like K9s and redis-terminal are ongoing consumers.
🚀Get running
go get github.com/rivo/tview@master
cd $GOPATH/src/github.com/rivo/tview
go run demos/box/main.go # or any demos/{widget}/main.go
Daily commands:
No Makefile visible. Examples run via go run demos/{widget}/main.go. To integrate into your own project: go get github.com/rivo/tview@master, then import "github.com/rivo/tview" and follow the Hello World pattern in the README (create a root widget, wrap in Application, call Run()).
🗺️Map of the codebase
application.go— Core Application struct that manages the event loop, screen rendering, and widget lifecycle — essential entry point for any tview-based terminal applicationbox.go— Base Box primitive that all other widgets inherit from; defines core rendering, border, and layout logic that underpins the entire widget hierarchyansi.go— ANSI color and text attribute parsing/rendering logic; critical for proper terminal output formatting across all widgetsbutton.go— Button widget implementation; demonstrates the standard pattern for interactive widgets with callbacks and event handlingborders.go— Border drawing utilities using tcell; foundational for all boxed widget renderingcheckbox.go— Checkbox widget; exemplifies form-input patterns used throughout the framework
🧩Components & responsibilities
- application.go (Application) (tcell, Go channels/goroutines) — Owns tcell.Screen, manages event loop, orchestrates focus/blur, triggers renders, handles global key bindings
- Failure mode: Screen corruption, event loss, focus stuck on widget, application hangs on blocking operations
- box.go (Box) (tcell colors/styles, rune rasterization) — Base primitive providing borders, padding, margins, text styling, and layout alignment for all widgets
- Failure mode: Misaligned borders, text overflow, color bleed, layout corruption in containers
- ansi.go (ANSI Handler) (Regex/string parsing, tcell.Style) — Parses [color]text[/] escape codes, maps to tcell.Color, applies text attributes (bold/underline/italic)
- Failure mode: Malformed ANSI codes break layout, colors not rendered, style attributes ignored
- Interactive Widgets (button, checkbox, inputfield, etc.) (tcell events, Go callbacks) — Capture InputHandler events, update state, invoke user callbacks, render custom content
- Failure mode: Input not registered, callbacks not fired, visual state inconsistent with data state
- Container Widgets (flex, grid, pages) — Manage child widget layout, delegate input to focused child
🛠️How to make changes
Add a New Simple Interactive Widget
- Create a new file (e.g., toggle.go) that embeds *Box from box.go (
toggle.go (new)) - Implement the Primitive interface: Draw(screen tcell.Screen, x, y, width, height int, focused bool) (
toggle.go) - Implement keyboard/mouse handling via InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) (consumed bool) (
toggle.go) - Add a callback setter (e.g., SetChangedFunc) and invoke callbacks in event handlers (
toggle.go) - Create a demo in demos/toggle/main.go following the pattern from button.go or checkbox.go demos (
demos/toggle/main.go (new))
Add a New Container/Layout Widget
- Create container.go (or similar) that embeds *Box and maintains a slice of child Primitives (
container.go (new)) - Implement layout logic in Draw() to position and render children based on width/height constraints (
container.go) - Delegate keyboard/mouse events to focused child via InputHandler() by checking focus state (
container.go) - Provide AddChild(p Primitive) and SetFocus(p Primitive) methods for composition (
container.go) - Create a demo in demos/container/main.go showing child widget arrangement and focus navigation (
demos/container/main.go (new))
Integrate ANSI Colored Text in a Custom Widget
- Import ansi.go utilities and use TranslateANSI() or ParseANSI() to parse color codes from strings (
mywidget.go (new)) - In Draw(), iterate through parsed regions and render each segment with tcell.Style using extracted color/attribute data (
mywidget.go) - Use box.go's WorldToScreen() or similar coordinate helpers to position text correctly within widget bounds (
mywidget.go) - Reference demos/presentation/colors.go or demos/textview/main.go for ANSI examples (
demos/presentation/colors.go)
🔧Why these technologies
- tcell/v2 — Cross-platform terminal abstraction providing low-level screen drawing, color management, and event handling for Win/Mac/Linux
- go-colorful — Color interpolation and manipulation for converting between color spaces; used for theme color customization
- uniseg — Unicode grapheme segmentation; critical for correct character width and text layout in terminals with complex scripts
⚖️Trade-offs already made
-
*Embedded Box base class pattern vs. interface-only design
- Why: Maximizes code reuse (borders, sizing, margin/padding logic shared across 15+ widgets) and simplifies learning curve
- Consequence: All widgets inherit unused features; harder to create minimal lightweight widgets without boilerplate removal
-
Synchronous event handling and immediate Draw() calls vs. event queue + batched rendering
- Why: Simpler mental model for developers; straightforward callback chains; easier to understand execution flow
- Consequence: High-throughput input (e.g., rapid key repeats) can cause jank; no async task integration (UI freezes on blocking ops)
-
Single-goroutine event loop vs. concurrent widget rendering
- Why: Eliminates race conditions on widget state; tcell screen is not thread-safe; simpler synchronization
- Consequence: Long-running operations must be offloaded to separate goroutines with careful state synchronization via channels/callbacks
🚫Non-goals (don't propose these)
- Web-based UI rendering (terminal-only)
- Async/concurrent task integration with built-in goroutine pooling (library provides callbacks for this, app must manage)
- Accessibility features like screen readers or keyboard-only navigation beyond basic arrow keys
- GPU-accelerated rendering (text-only terminal output)
- Real-time multi-client TUI (single-terminal, single-user design)
🪤Traps & gotchas
Terminal detection: tcell/v2 auto-detects terminal capabilities; forcing a specific TERM value (e.g., xterm-256color) may be needed in non-standard shells. Unicode graphemes: uniseg is required because Go's len() counts bytes, not display widths—widgets must use uniseg.StringWidth() for text measurement. Color palette limits: 256-color or true-color support depends on terminal; go-colorful downgrades RGB to nearest ANSI 256 if needed, but is not lossless. Event blocking: SetInputCapture() returning true consumes the event; returning false propagates it—easy to accidentally swallow events. Focus navigation: Tab/Shift-Tab order follows widget registration order in container; not automatically optimal.
🏗️Architecture
💡Concepts to learn
- Cell-based rendering — tview delegates all drawing to tcell's cell abstraction (rune + color per position); you must think in discrete terminal cells, not pixels or vector graphics.
- Unicode grapheme segmentation — Go's len() counts UTF-8 bytes, not display width; tview uses uniseg to correctly measure and truncate text containing emoji, accents, and wide CJK characters.
- ANSI escape sequence stripping — Terminal emulators interpret escape codes for colors/styles, but they consume bytes; ansi.go removes them so text width calculations are accurate.
- Constraint-based layout (Grid/Flex) — Instead of absolute pixel positions, tview widgets negotiate space via row/column constraints and flex grow/shrink; required to build responsive terminal layouts that adapt to window resize.
- Event bubbling and input capture — tview follows a focus-based input model where SetInputCapture() intercepts events; true return consumes, false propagates—critical for custom key bindings without blocking child widgets.
- 256-color and true-color terminal support — Modern terminals support 256 ANSI colors or 24-bit RGB; go-colorful maps arbitrary RGB to the closest available palette to degrade gracefully on limited terminals.
- Primitive interface and composition — All tview widgets implement Primitive (GetRect, SetRect, Draw, GetFocusable, HandleEvent); this small interface allows containers like Grid to treat any widget uniformly.
🔗Related repos
gdamore/tcell— Direct dependency: low-level terminal cell drawing abstraction that tview builds on; needed to understand rune rendering, colors, and events.charmbracelet/bubbles— Alternative Go TUI widget library (part of Bubble Tea framework); overlaps on buttons, text input, lists—good comparison if tview doesn't fit your use case.charmbracelet/lipgloss— Complementary Go styling/layout library often used with Bubble Tea; tview bundles styling but lipgloss offers fine-grained control.derailed/k9s— Canonical real-world tview consumer: Kubernetes CLI using tview's table, form, and modal widgets—best reference for patterns in a large production TUI.golang/text— Go's official Unicode package (imported transitively via uniseg); understanding text/width and text/unicode helps with grapheme segmentation bugs.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for ansi.go ANSI escape sequence parsing
ansi.go handles ANSI escape sequence parsing which is critical for terminal rendering correctness. Currently there are no visible test files for this core functionality. Comprehensive tests covering edge cases (malformed sequences, color codes, cursor movements) would improve reliability and catch regressions when terminal compatibility features are added.
- [ ] Create ansi_test.go with test cases for ANSI parsing functions
- [ ] Add tests for color code extraction and validation
- [ ] Add tests for edge cases: incomplete sequences, nested codes, invalid UTF-8
- [ ] Run go test ./... and ensure >80% coverage of ansi.go
- [ ] Document test cases in comments explaining each scenario
Add GitHub Actions CI workflow for cross-platform testing
The repo has .github/FUNDING.yml but no visible CI workflows. Terminal UI libraries need testing across different OS/terminal environments. A GitHub Actions workflow would catch platform-specific bugs in box.go, borders.go, and application.go before merging, especially since tcell/v2 has OS-specific behavior.
- [ ] Create .github/workflows/test.yml with matrix testing for Linux, macOS, Windows
- [ ] Add go test, go vet, and golangci-lint steps
- [ ] Test against Go 1.18+ versions (matching go.mod minimum version)
- [ ] Add test coverage reporting (codecov integration optional)
- [ ] Ensure demos can at least compile without runtime errors
Add comprehensive documentation for widget customization patterns in demos/
While demos/ folder has individual widget examples (button, checkbox, form, etc.), there's no guide on common customization patterns across all widgets. New contributors struggle to understand how to theme, extend, or style widgets consistently. A demo/CUSTOMIZATION_GUIDE.md with before/after code examples would significantly reduce contributor friction.
- [ ] Create demos/CUSTOMIZATION_GUIDE.md with sections for each customization type
- [ ] Add examples: custom colors (using box.go/borders.go), event handling, layout patterns
- [ ] Reference actual demo code files (e.g., demos/form/main.go, demos/grid/main.go)
- [ ] Include common pitfalls and solutions for widget composition
- [ ] Add links to relevant API documentation in pkg.go.dev
🌿Good first issues
- Add a Spinner or ProgressBar widget—currently tree.go, list.go, and table.go exist, but no animated loading indicator. Create spinner.go with rotating animation frames.: Fills a gap in common TUI patterns; has clear acceptance criteria (visual demo, no API ambiguity).
- Expand ansi.go documentation with unit tests for edge cases—currently no test file exists for ANSI stripping (e.g., 24-bit color codes, malformed sequences). Add ansi_test.go.: Core text safety function lacks coverage; tests will catch regressions in color/style escape handling.
- Create demos/tabbedpages/ example—TabBar and Pages exist, but no integrated demo showing tabbed navigation. Combine them into a working example with screenshots.: Common UI pattern used in K9s and other tools; a runnable demo will help new users adopt the pattern quickly.
⭐Top contributors
Click to expand
Top contributors
- @rivo — 73 commits
- @LinPr — 3 commits
- @SamWhited — 2 commits
- @markusressel — 2 commits
- @alekseysavchuk — 2 commits
📝Recent commits
Click to expand
Recent commits
63ee97f— Avoid partial transparency inside a border. (rivo)a9e8493— Improved documentation somewhat. (rivo)c03ee26— Fixed wrong handling of transparency setting in table cells. (rivo)f39b95c— Merge pull request #1147 from laborin/master (rivo)2a2df46— handle KeyCtrlJ as newline during paste (laborin)e113793— Merge pull request #1123 from dbohdan/add-pago (rivo)a92a7f7— Merge pull request #1114 from ayn2op/pages.clear (rivo)2cde1d2— Fixed disappearing buttons in some layouts. Fixes #1119 (rivo)b39430e— docs: add pago to project list in readme (dbohdan)0b5989b— Merge pull request #1120 from declan-whiting/add-vaulty (rivo)
🔒Security observations
The tview repository demonstrates generally good security practices for a terminal UI library. No critical vulnerabilities were identified. The codebase has minimal external attack surface as it's a rendering library with no network, database, or file I/O operations evident from the file structure. Primary recommendations involve: (1) upgrading the Go version requirement to receive current security patches, (2) adding security documentation for responsible disclosure, and (3) emphasizing input validation responsibilities in the documentation for consuming applications. Dependencies on gdamore/tcell and related packages appear well-maintained. The library's security posture is primarily dependent on secure implementation by downstream users of the widgets.
- Low · Outdated Go Version Requirement —
go.mod. The project specifies go 1.18 as the minimum version, which was released in March 2022. Modern Go versions include security patches and performance improvements. Go 1.18 is significantly outdated and no longer receives security updates. Fix: Update the go.mod to require a more recent Go version (1.21 or later). Consider Go 1.23+ for latest security patches. - Low · Potential Input Validation in Terminal UI Components —
button.go, checkbox.go, inputfield.go (implied). While this is a terminal UI library, components like InputField, TextArea, and Form could be vulnerable to injection if not properly validated by consuming applications. The library provides rendering components but input sanitization responsibility falls on implementers. Fix: Ensure comprehensive documentation warning users about input validation. Consider adding built-in validation helpers for common use cases (URLs, emails, etc.). Add security guidelines to CONTRIBUTING.md. - Low · Missing Security Policy —
.github/ directory. No SECURITY.md file found for responsible vulnerability disclosure. This makes it difficult for security researchers to report issues privately. Fix: Create a SECURITY.md file in the root directory with clear instructions for reporting security vulnerabilities privately, including contact information and expected response timeframes. - Low · Dependency Pinning Best Practice —
go.mod (indirect dependencies). The go.mod uses flexible version constraints (v2.8.1, v1.2.0, v0.4.7) but indirect dependencies lack specific version pinning which could lead to unexpected updates. Fix: Run 'go mod tidy' and consider using 'go mod why' to understand indirect dependencies. Ensure go.sum is committed and reviewed to lock transitive dependency versions.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.