phoenix

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 3, 2025 License: MIT Imports: 5 Imported by: 0

README

Phoenix TUI Framework

Phoenix TUI Framework

Go Version Release CI Go Report Card Coverage License GoDoc

Multi-module monorepo - 10 independent libraries. Full metrics in CI.

Next-generation Terminal User Interface framework for Go

Status: ✅ v0.2.0 RELEASED 🚀 Organization: github.com/phoenix-tui Go Version: 1.25+ Test Coverage: 91.8% (Excellent across all modules) Performance: 29,000 FPS (489x faster than 60 FPS target) API Quality: 9/10 (Validated against Go 2025 best practices) Latest: Theme System, Form Components, TTY Control for external processes

Why Phoenix?

Phoenix rises from the ashes of legacy TUI frameworks, solving critical problems:

  • Perfect Unicode/Emoji support - No more layout bugs
  • 10x Performance - Differential rendering, caching, zero allocations
  • DDD Architecture - Clean, testable, extendable
  • Rich Component Library - Everything you need out of the box
  • Public Cursor API - Full control for shell applications
  • Easy Migration from Charm - Comprehensive migration guide included

Libraries

Phoenix is a modular framework with 8 independent libraries:

  • phoenix/core ✅ - Terminal primitives, Unicode/Emoji support (CORRECT width calculation!)
  • phoenix/style ✅ - CSS-like styling + Theme System (4 presets, runtime switching)
  • phoenix/layout ✅ - Flexbox & grid layout (Box model, responsive sizing)
  • phoenix/tea ✅ - Elm Architecture + TTY Control (run vim, shells, job control)
  • phoenix/render ✅ - High-performance differential renderer (29,000 FPS!)
  • phoenix/components ✅ - 10 UI components:
    • TextArea | TextInput | List | Viewport | Table | Modal | Progress
    • NEW in v0.2.0: Select, MultiSelect, Confirm, Form (with validation)
  • phoenix/mouse ✅ - Mouse events (click, scroll, drag-drop, right-click support)
  • phoenix/clipboard ✅ - Cross-platform clipboard (OSC 52 for SSH)

Installation

go get github.com/phoenix-tui/phoenix@latest

This installs the umbrella module with convenient access to all Phoenix libraries through a single import:

import "github.com/phoenix-tui/phoenix"

// Use convenience API
term := phoenix.AutoDetectTerminal()
style := phoenix.NewStyle().Foreground("#00FF00").Bold()
p := phoenix.NewProgram(myModel, phoenix.WithAltScreen[MyModel]())
Install Individual Libraries (For existing projects or selective use)
go get github.com/phoenix-tui/phoenix/tea@latest        # Elm Architecture
go get github.com/phoenix-tui/phoenix/components@latest # UI Components
go get github.com/phoenix-tui/phoenix/style@latest      # Styling
go get github.com/phoenix-tui/phoenix/core@latest       # Terminal primitives

Individual imports give you more control and smaller dependencies:

import (
    tea "github.com/phoenix-tui/phoenix/tea/api"
    "github.com/phoenix-tui/phoenix/components/input/api"
)

Quick Start

Using the Umbrella Module
go get github.com/phoenix-tui/phoenix@latest
package main

import (
    "fmt"
    "os"
    "github.com/phoenix-tui/phoenix"
    tea "github.com/phoenix-tui/phoenix/tea/api"
)

type Model struct {
    count int
}

func (m Model) Init() tea.Cmd { return nil }

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.KeyMsg:
        if msg.String() == "q" {
            return m, phoenix.Quit()
        }
        m.count++
    }
    return m, nil
}

func (m Model) View() string {
    // Use Phoenix convenience API for styling
    style := phoenix.NewStyle().Foreground("#00FF00").Bold()
    return style.Render(fmt.Sprintf("Count: %d\n", m.count))
}

func main() {
    p := phoenix.NewProgram(Model{}, phoenix.WithAltScreen[Model]())
    if err := p.Run(); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
}
Using Individual Libraries
go get github.com/phoenix-tui/phoenix/tea@latest
package main

import (
    "fmt"
    "os"
    "github.com/phoenix-tui/phoenix/tea/api"
)

type Model struct {
    count int
}

func (m Model) Init() api.Cmd { return nil }

func (m Model) Update(msg api.Msg) (Model, api.Cmd) {
    switch msg := msg.(type) {
    case api.KeyMsg:
        if msg.String() == "q" {
            return m, api.Quit()
        }
        m.count++
    }
    return m, nil
}

func (m Model) View() string {
    return fmt.Sprintf("Count: %d\nPress any key to increment, 'q' to quit\n", m.count)
}

func main() {
    p := api.New(Model{}, api.WithAltScreen[Model]())
    if err := p.Run(); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
}

Documentation

Development Status

Library Status Coverage Week Notes
core ✅ v0.1.0 98.4% 3-4 Unicode/Emoji CORRECT!
style ✅ v0.1.0 90%+ 5-6 CSS-like styling
tea ✅ v0.1.0 95.7% 7-8 Elm Architecture
layout ✅ v0.1.0 97.9% 9-10 Flexbox + Box model
components ✅ v0.1.0 94.5% 11-12 6 universal components
render ✅ v0.1.0 91.7% 13-14 29,000 FPS (489x faster!)
mouse ✅ v0.1.0 99.7% 16 3 critical bugs fixed!
clipboard ✅ v0.1.0 82.0% 16 Cross-platform + SSH
Overall Progress
Phase 1: Foundation     ████████████████████  (10%)  ✅ Weeks 1-2
Phase 2: Core Libs      ████████████████████  (30%)  ✅ Weeks 3-8
Phase 3: Components     ████████████████████  (20%)  ✅ Weeks 9-12
Phase 4: Advanced       ████████████████████  (15%)  ✅ Weeks 13-16
Phase 5: Launch         ████████████████████  (25%)  ✅ Week 20 - API Polish
                        ══════════════════════
                        Progress: 100% (v0.1.0 STABLE!)

v0.1.0 STABLE RELEASED: API Quality 9/10, 91.8% coverage, 29,000 FPS, zero value docs complete

Completed Features

Week 3-4: phoenix/core

  • Terminal primitives (ANSI, raw mode, capabilities)
  • Unicode/Emoji width calculation (CORRECT - fixes Charm bug!)
  • Grapheme cluster support (👋🏽 = 1 cluster, 2 cells)
  • 98.4% test coverage

Week 5-6: phoenix/style

  • CSS-like styling (bold, italic, colors)
  • Border/padding/margin support
  • 8-stage rendering pipeline
  • Fluent builder API
  • 90%+ test coverage

Week 7-8: phoenix/tea

  • Elm Architecture (Model-Update-View)
  • Type-safe event loop
  • Command system (Quit, Batch, Sequence, Tick)
  • Generic constraints (no interface{} casts!)
  • 95.7% test coverage

Week 9-10: phoenix/layout

  • Box model (padding, margin, border, sizing)
  • Flexbox layout (row/column, gap, flex grow/shrink)
  • Responsive sizing
  • 97.9% test coverage (highest!)

Week 11-12: phoenix/components

  • TextInput (90.0%) - Public cursor API, grapheme-aware, selection, validation
  • List (94.7%) - Single/multi selection, filtering, custom rendering
  • Viewport (94.5%) - Scrolling, follow mode, large content (10K+ lines)
  • Table (92.0%) - Sortable columns, custom cell renderers, navigation
  • Modal (96.5%) - Focus trap, buttons, dimming, keyboard shortcuts
  • Progress (98.5%) - Bar + 15 spinner styles
  • Average coverage: 94.5% (exceeds 90% target!)

Week 13-14: phoenix/render

  • Differential rendering (virtual buffer)
  • 29,000 FPS achieved (489x faster than 60 FPS target!)
  • Zero allocations in hot paths
  • 91.7% test coverage (improved from 87.1%)

Week 16: phoenix/mouse 🔥

  • All buttons (Left, Right, Middle, WheelUp, WheelDown)
  • Click detection (single/double/triple - automatic!)
  • Drag & drop state tracking
  • Multi-protocol (SGR, X10, URxvt)
  • Comprehensive README (588 lines)
  • 99.7% test coverage - 6,000+ lines test code
  • 3 critical bugs found and fixed during coverage sprint!

Week 16: phoenix/clipboard

  • Cross-platform (Windows/macOS/Linux)
  • OSC 52 for SSH sessions (auto-detect)
  • Native APIs (user32.dll, pbcopy/pbpaste, xclip/xsel)
  • DDD architecture
  • 82% average test coverage (domain 100%)

Key Features

1. Perfect Unicode/Emoji Support ✅

Problem: Charm's Lipgloss has broken emoji width calculation (issue #562) Solution: Phoenix uses grapheme cluster detection with correct East Asian Width (UAX #11)

// Phoenix: CORRECT
text := "Hello 👋 World 🌍"
width := style.Width(text)  // Returns 17 (correct!)

// Charm Lipgloss: BROKEN
width := lipgloss.Width(text)  // Returns 19 (wrong!)
2. 10x Performance ✅

Benchmark: 29,000 FPS (489x faster than 60 FPS target) Techniques: Differential rendering, caching, zero allocations

3. DDD Architecture ✅
library/
├── domain/        # Business logic (95%+ coverage)
├── application/   # Use cases
├── infrastructure/ # Technical details
└── api/           # Public interface
4. Public Cursor API ✅

Problem: Bubbles TextArea has private cursor - syntax highlighting impossible Solution: Phoenix TextInput exposes CursorPosition() and ContentParts()

// Phoenix: PUBLIC API (syntax highlighting works!)
before, at, after := input.ContentParts()
highlighted := syntax.Highlight(before) +
               cursor.Render(at) +
               syntax.Highlight(after)

// Bubbles: PRIVATE (syntax highlighting impossible!)
// cursor is internal field - no access
5. Mouse & Clipboard Support ✅

Mouse: All buttons (Left, Right, Middle, Wheel), drag-drop, click detection Clipboard: Cross-platform (Windows/macOS/Linux), SSH support (OSC 52)

6. Progress Component ✅

Available: Progress Bar + 15 Spinner Styles (Week 11-12, 98.5% coverage) Location: github.com/phoenix-tui/phoenix/components/progress/api

Phoenix includes a comprehensive Progress component with both bars and animated spinners:

import progress "github.com/phoenix-tui/phoenix/components/progress/api"

// Progress Bar
bar := progress.NewBar(100).  // Max value 100
    SetWidth(40).
    SetLabel("Downloading").
    SetValue(65)  // Current progress 65%

// Animated Spinner (15 styles available!)
spinner := progress.NewSpinner(progress.SpinnerDots).
    SetLabel("Loading").
    SetFPS(10)

// Example styles: SpinnerDots, SpinnerLine, SpinnerArrow, SpinnerCircle,
// SpinnerBounce, SpinnerPulse, SpinnerGrowHorizontal, SpinnerGrowVertical, etc.

Features:

  • Progress bars with customizable width and characters
  • 15 pre-built spinner styles (dots, lines, arrows, circles, bouncing, etc.)
  • Label support for both bars and spinners
  • Configurable FPS for smooth animations
  • 98.5% test coverage

Examples: See examples/progress/ for working demonstrations:

  • bar_simple.go - Basic progress bar
  • bar_styled.go - Styled progress bar with colors
  • spinner_simple.go - Animated spinner
  • multi_progress.go - Multiple progress indicators

Documentation: See components/progress/README.md for full API reference

What's New in v0.2.0

Released Features

TTY Control System (Level 1, 1+, 2):

  • Run external processes like vim, nano, shells with full terminal control
  • Suspend/Resume Phoenix TUI while external process runs
  • Job control support (foreground/background process groups)
  • Platform support: Linux, macOS, Windows

Form Components:

  • Select - Single-choice dropdown with keyboard navigation
  • MultiSelect - Multiple-choice selection with checkboxes
  • Confirm - Yes/No prompts with customizable buttons
  • Form - Complete form system with validation

Theme System:

  • 4 built-in presets: Default, Dark, Light, HighContrast
  • Runtime theme switching
  • All 10 components support Theme API
  • Custom theme creation

See CHANGELOG.md for full v0.2.0 details

What's Next?

v0.3.0 (Future):

  • Signals integration (reactive views - optional, hybrid approach)
  • Animation framework
  • Grid layout enhancements

Contributing

Phoenix is part of an active development effort. See CONTRIBUTING.md for contribution guidelines and GoDoc for API documentation.

License

MIT License - see LICENSE file for details

Special Thanks

Professor Ancha Baranova - This project would not have been possible without her invaluable help and support. Her assistance was crucial in bringing Phoenix to life.


Rising from the ashes of legacy TUI frameworks 🔥 v0.2.0 STABLEAPI Quality: 9/10 | 91.8% coverage | 29,000 FPS | Theme System + Form Components + TTY Control!

Documentation

Overview

Package phoenix is the root umbrella module for Phoenix TUI Framework.

Phoenix is a modern, high-performance Terminal User Interface framework for Go, built with Domain-Driven Design principles and modern Go 1.25+ patterns.

Architecture

Phoenix consists of 10 independent libraries that can be used together or separately:

  • github.com/phoenix-tui/phoenix/core - Terminal primitives & Unicode support
  • github.com/phoenix-tui/phoenix/style - CSS-like styling system
  • github.com/phoenix-tui/phoenix/tea - Elm Architecture (Model-Update-View)
  • github.com/phoenix-tui/phoenix/layout - Flexbox & Box Model layouts
  • github.com/phoenix-tui/phoenix/render - High-performance differential renderer
  • github.com/phoenix-tui/phoenix/components - Rich UI component library
  • github.com/phoenix-tui/phoenix/mouse - Mouse input handling
  • github.com/phoenix-tui/phoenix/clipboard - Cross-platform clipboard operations
  • github.com/phoenix-tui/phoenix/terminal - Terminal detection & capabilities
  • github.com/phoenix-tui/phoenix/testing - Testing utilities (Mock/Null terminals)

Quick Start

Install individual libraries:

go get github.com/phoenix-tui/phoenix/tea@latest
go get github.com/phoenix-tui/phoenix/components@latest

Or install all libraries via the root module:

go get github.com/phoenix-tui/phoenix@latest

Example: Hello World

package main

import (
    "fmt"
    "os"
    tea "github.com/phoenix-tui/phoenix/tea/api"
)

type model struct{ message string }

func (m model) Init() tea.Cmd { return nil }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    if _, ok := msg.(tea.KeyMsg); ok {
        return m, tea.Quit
    }
    return m, nil
}

func (m model) View() string {
    return fmt.Sprintf("Hello, %s!\n\nPress any key to quit.", m.message)
}

func main() {
    p := tea.NewProgram(model{message: "World"})
    if _, err := p.Run(); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
}

Why Phoenix?

Phoenix was created to address critical issues in the Charm ecosystem:

  • Perfect Unicode/Emoji support (no width calculation bugs)
  • 10x better performance (29,000 FPS renderer vs ~450 FPS)
  • Type-safe API with Go 1.25+ generics
  • DDD architecture (testable, maintainable)
  • 94.5% average test coverage
  • Zero external TUI dependencies

Multi-Module Monorepo

This repository uses a multi-module structure where each library is independently versioned. The root module serves as an umbrella module for convenient installation and documentation.

For more information, see:

Version

Phoenix version is managed through git tags and Go modules. To check your installed version:

go list -m github.com/phoenix-tui/phoenix

This will show the exact version you're using, including any pre-release tags.

Index

Constants

View Source
const (
	ColorDepthNone      = coreapi.ColorDepthNone
	ColorDepth8         = coreapi.ColorDepth8
	ColorDepth256       = coreapi.ColorDepth256
	ColorDepthTrueColor = coreapi.ColorDepthTrueColor
)

ColorDepth constants (re-exported from core).

Variables

This section is empty.

Functions

func AutoDetectTerminal

func AutoDetectTerminal() *coreapi.Terminal

AutoDetectTerminal creates a Terminal by auto-detecting the current environment. This is the recommended way to create a Terminal for most applications.

Example:

term := phoenix.AutoDetectTerminal()
fmt.Printf("Terminal size: %dx%d\n", term.Size().Width, term.Size().Height)

func NewANSITerminal

func NewANSITerminal() terminalapi.Terminal

NewANSITerminal creates a new ANSI-based Terminal. Use this when you want to force ANSI escape codes (e.g., for SSH, tmux).

Example:

term := phoenix.NewANSITerminal()
term.Clear()

func NewCapabilities

func NewCapabilities(ansi bool, colorDepth coreapi.ColorDepth, mouse, altScreen, cursor bool) *coreapi.Capabilities

NewCapabilities creates a new terminal capabilities configuration.

Example:

caps := phoenix.NewCapabilities(
	true,                      // ANSI support
	phoenix.ColorDepth256,     // 256-color support
	true,                      // Mouse support
	true,                      // Alt screen support
	true,                      // Cursor support
)

func NewPlatformTerminal

func NewPlatformTerminal() terminalapi.Terminal

NewPlatformTerminal creates a new platform-optimized Terminal. Automatically selects the best implementation for the current platform:

  • Windows Console API (fastest on Windows cmd.exe/PowerShell)
  • ANSI fallback (for Git Bash, MinTTY, Unix)

Note: This is from the terminal package, providing platform-optimized terminal operations. Different from core package which focuses on capabilities detection.

Example:

term := phoenix.NewPlatformTerminal()
term.HideCursor()
defer term.ShowCursor()

func NewProgram

func NewProgram[T modelConstraint[T]](model T, opts ...teaapi.Option[T]) *teaapi.Program[T]

NewProgram creates a new Tea Program with the given model. This is the main entry point for building Phoenix TUI applications.

Example:

type MyModel struct { count int }
// ... implement tea.Model interface ...

p := phoenix.NewProgram(MyModel{}, phoenix.WithAltScreen[MyModel]())
if err := p.Run(); err != nil {
	log.Fatal(err)
}

func NewSize

func NewSize(width, height int) coreapi.Size

NewSize creates a new terminal size (width x height in cells).

Example:

size := phoenix.NewSize(80, 24)  // 80 columns, 24 rows

func NewStyle

func NewStyle() styleapi.Style

NewStyle creates a new Style builder for applying colors, borders, padding, etc.

Example:

s := phoenix.NewStyle().
	Foreground("#00FF00").
	Background("#000000").
	Bold().
	Padding(1)
fmt.Println(s.Render("Styled text"))

func NewTerminal

func NewTerminal() *coreapi.Terminal

NewTerminal creates a new Terminal with default auto-detected capabilities. Equivalent to AutoDetectTerminal() - provided for API completeness.

Example:

term := phoenix.NewTerminal()
fmt.Printf("Terminal size: %dx%d\n", term.Size().Width, term.Size().Height)

func NewTerminalWithCapabilities

func NewTerminalWithCapabilities(caps *coreapi.Capabilities) *coreapi.Terminal

NewTerminalWithCapabilities creates a new Terminal with the specified capabilities. Use this when you need full control over terminal configuration.

Example:

caps := phoenix.NewCapabilities(true, phoenix.ColorDepth256, true, true, true)
term := phoenix.NewTerminalWithCapabilities(caps)

func Quit

func Quit() teaapi.Cmd

Quit returns a command that quits the program.

Example:

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
	if msg.(tea.KeyMsg).String() == "q" {
		return m, phoenix.Quit()
	}
	return m, nil
}

func ReadClipboard

func ReadClipboard() (string, error)

ReadClipboard reads text from the system clipboard.

Example:

text, err := phoenix.ReadClipboard()
if err != nil {
	log.Fatal(err)
}
fmt.Println("Clipboard:", text)

func WithAltScreen

func WithAltScreen[T any]() teaapi.Option[T]

WithAltScreen enables the alternate screen buffer. This allows your TUI to take over the full terminal without affecting the scrollback.

Example:

p := phoenix.NewProgram(model, phoenix.WithAltScreen[MyModel]())

func WithMouseAllMotion

func WithMouseAllMotion[T any]() teaapi.Option[T]

WithMouseAllMotion enables mouse support with all motion events.

Example:

p := phoenix.NewProgram(model, phoenix.WithMouseAllMotion[MyModel]())

func WriteClipboard

func WriteClipboard(text string) error

WriteClipboard writes text to the system clipboard.

Example:

err := phoenix.WriteClipboard("Hello, clipboard!")
if err != nil {
	log.Fatal(err)
}

Types

This section is empty.

Directories

Path Synopsis
clipboard module
components module
list module
core module
examples
umbrella command
Package main demonstrates using Phoenix via the umbrella module.
Package main demonstrates using Phoenix via the umbrella module.
layout module
mouse module
render module
style module
tea module
terminal module
testing module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL