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.
go get github.com/charmbracelet/ultraviolet@latestpackage 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
}
}
}
}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()orNewTerminal(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 byTerminalScreen,Buffer,Window, andScreenBuffer. Write code againstScreento stay decoupled from the terminal. -
Buffer / Window โ off-screen cell buffers.
Bufferis a flat grid of cells.Windowadds parent/child relationships and shared-buffer views. Both implementScreenandDrawable. -
screen package โ drawing helpers that operate on any
Screen: aContextfor styled text rendering (Print,DrawString, etc.) and utility functions likeClear,Fill,Clone. -
layout package โ a constraint-based layout solver built on the Cassowary algorithm. Partition screen space with
Len,Min,Max,Percent,Ratio, andFillconstraints.
-
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()andStart()can be called repeatedly for suspend/resume cycles, shelling out to editors, or process suspension viauv.Suspend().
See the examples/ directory for core examples and
examples/advanced/ for more complex demos.
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.
We'd love to hear your thoughts on this project. Feel free to drop us a note!
Part of Charm.
Charm็ญ็ฑๅผๆบ โข Charm loves open source โข ูุญูู ูุญุจ ุงูู ุตุงุฏุฑ ุงูู ูุชูุญุฉ
