ULTRAVIOLET(1)

NAME

ultraviolet β€” Mystical terminal user interface primitives 🌈

SYNOPSIS

INFO

340 stars
33 forks
0 views

DESCRIPTION

Mystical terminal user interface primitives 🌈

README

Ultraviolet

Charm Ultraviolet

GoDoc Build Status

Ultraviolet is a set of primitives for building terminal user interfaces in Go. It provides cell-based rendering, cross-platform input handling, and a diffing renderer inspired by ncursesβ€”without the need for terminfo or termcap databases.

Ultraviolet powers Bubble Tea v2 and Lip Gloss v2. It replaces the ad-hoc terminal primitives from earlier versions with a cohesive, imperative API that can also be used standalone.

Install

go get github.com/charmbracelet/ultraviolet@latest

Quick Start

package main

import ( "log"

uv "github.com/charmbracelet/ultraviolet"
"github.com/charmbracelet/ultraviolet/screen"

)

func main() { t := uv.DefaultTerminal() scr := t.Screen()

scr.EnterAltScreen()

if err := t.Start(); err != nil {
	log.Fatalf("failed to start terminal: %v", err)
}
defer t.Stop()

ctx := screen.NewContext(scr)
text := "Hello, World!"
textWidth := scr.StringWidth(text)

display := func() {
	screen.Clear(scr)
	bounds := scr.Bounds()
	x := (bounds.Dx() - textWidth) / 2
	y := bounds.Dy() / 2
	ctx.DrawString(text, x, y)
	scr.Render()
	scr.Flush()
}

for ev := range t.Events() {
	switch ev := ev.(type) {
	case uv.WindowSizeEvent:
		scr.Resize(ev.Width, ev.Height)
		display()
	case uv.KeyPressEvent:
		if ev.MatchString("q", "ctrl+c") {
			return
		}
	}
}

}

Architecture

Ultraviolet is organized as a set of layered primitives:

  • Terminal β€” manages the application lifecycle: raw mode, input event loop, start/stop. Create one with DefaultTerminal() or NewTerminal(console, opts).

  • TerminalScreen β€” the screen state manager. Handles rendering, alternate screen buffer, cursor, mouse modes, keyboard enhancements, bracketed paste, window title, and more. Access it via terminal.Screen().

  • Screen β€” a minimal interface (Bounds, CellAt, SetCell, WidthMethod) implemented by TerminalScreen, Buffer, Window, and ScreenBuffer. Write code against Screen to stay decoupled from the terminal.

  • Buffer / Window β€” off-screen cell buffers. Buffer is a flat grid of cells. Window adds parent/child relationships and shared-buffer views. Both implement Screen and Drawable.

  • screen package β€” drawing helpers that operate on any Screen: a Context for styled text rendering (Print, DrawString, etc.) and utility functions like Clear, Fill, Clone.

  • layout package β€” a constraint-based layout solver built on the Cassowary algorithm. Partition screen space with Len, Min, Max, Percent, Ratio, and Fill constraints.

Features

  • Cell-based diffing renderer β€” only redraws what changed. Optimizes cursor movement, uses ECH/REP/ICH/DCH when available, and supports scroll optimizations. Minimal bandwidth, critical for SSH.

  • Universal input β€” unified keyboard and mouse event handling across platforms. Supports legacy encodings, Kitty keyboard protocol, SGR mouse, and Windows Console input.

  • Inline and fullscreen β€” works in both alternate screen (fullscreen) and inline mode. Inline TUIs preserve terminal context and scrollback.

  • Cross-platform β€” first-class support for Unix (termios + ANSI) and Windows (Console API). Consistent behavior across terminal emulators.

  • Suspend/resume β€” Stop() and Start() can be called repeatedly for suspend/resume cycles, shelling out to editors, or process suspension via uv.Suspend().

Examples

See the examples/ directory for core examples and examples/advanced/ for more complex demos.

Tutorial

See TUTORIAL.md for a step-by-step guide to building your first Ultraviolet application.

[!NOTE] Ultraviolet is in active development. The API may change.

Feedback

We'd love to hear your thoughts on this project. Feel free to drop us a note!

License

MIT


Part of Charm.

The Charm logo

Charmηƒ­ηˆ±εΌ€ζΊ β€’ Charm loves open source β€’ نحنُ Ω†Ψ­Ψ¨ Ψ§Ω„Ω…Ψ΅Ψ§Ψ―Ψ± المفΨͺوحة

SEE ALSO

clihub5/8/2026ULTRAVIOLET(1)