termenv lets you safely use advanced styling options on the terminal. It
gathers information about the terminal environment in terms of its ANSI & color
support and offers you convenient methods to colorize and style your output,
without you having to deal with all kinds of weird ANSI escape sequences and
color conversions.
- RGB/TrueColor support
 - Detects the supported color range of your terminal
 - Automatically converts colors to the best matching, available colors
 - Terminal theme (light/dark) detection
 - Chainable syntax
 - Nested styles
 
go get github.com/muesli/termenvoutput := termenv.NewOutput(os.Stdout)termenv queries the terminal's capabilities it is running in, so you can
safely use advanced features, like RGB colors or ANSI styles. output.Profile
returns the supported profile:
termenv.Ascii- no ANSI support detected, ASCII onlytermenv.ANSI- 16 color ANSI supporttermenv.ANSI256- Extended 256 color ANSI supporttermenv.TrueColor- RGB/TrueColor support
Alternatively, you can use termenv.EnvColorProfile which evaluates the
terminal like ColorProfile, but also respects the NO_COLOR and
CLICOLOR_FORCE environment variables.
You can also query the terminal for its color scheme, so you know whether your app is running in a light- or dark-themed environment:
// Returns terminal's foreground color
color := output.ForegroundColor()
// Returns terminal's background color
color := output.BackgroundColor()
// Returns whether terminal uses a dark-ish background
darkTheme := output.HasDarkBackground()If you don't want to rely on the automatic detection, you can manually select the profile you want to use:
output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor))termenv supports multiple color profiles: Ascii (black & white only),
ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors
will automatically be degraded to the best matching available color in the
desired profile:
TrueColor => ANSI 256 Colors => ANSI 16 Colors => Ascii
s := output.String("Hello World")
// Supports hex values
// Will automatically degrade colors on terminals not supporting RGB
s.Foreground(output.Color("#abcdef"))
// but also supports ANSI colors (0-255)
s.Background(output.Color("69"))
// ...or the color.Color interface
s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255}))
// Combine fore- & background colors
s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff"))
// Supports the fmt.Stringer interface
fmt.Println(s)You can use a chainable syntax to compose your own styles:
s := output.String("foobar")
// Text styles
s.Bold()
s.Faint()
s.Italic()
s.CrossOut()
s.Underline()
s.Overline()
// Reverse swaps current fore- & background colors
s.Reverse()
// Blinking text
s.Blink()
// Combine multiple options
s.Bold().Underline()termenv provides a set of helper functions to style your Go templates:
// load template helpers
f := output.TemplateFuncs()
tpl := template.New("tpl").Funcs(f)
// apply bold style in a template
bold := `{{ Bold "Hello World" }}`
// examples for colorized templates
col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}`
fg := `{{ Foreground "#ff0000" "Red Foreground" }}`
bg := `{{ Background "#0000ff" "Blue Background" }}`
// wrap styles
wrap := `{{ Bold (Underline "Hello World") }}`
// parse and render
tpl, err = tpl.Parse(bold)
var buf bytes.Buffer
tpl.Execute(&buf, nil)
fmt.Println(&buf)Other available helper functions are: Faint, Italic, CrossOut,
Underline, Overline, Reverse, and Blink.
// Move the cursor to a given position
output.MoveCursor(row, column)
// Save the cursor position
output.SaveCursorPosition()
// Restore a saved cursor position
output.RestoreCursorPosition()
// Move the cursor up a given number of lines
output.CursorUp(n)
// Move the cursor down a given number of lines
output.CursorDown(n)
// Move the cursor up a given number of lines
output.CursorForward(n)
// Move the cursor backwards a given number of cells
output.CursorBack(n)
// Move the cursor down a given number of lines and place it at the beginning
// of the line
output.CursorNextLine(n)
// Move the cursor up a given number of lines and place it at the beginning of
// the line
output.CursorPrevLine(n)// Reset the terminal to its default style, removing any active styles
output.Reset()
// RestoreScreen restores a previously saved screen state
output.RestoreScreen()
// SaveScreen saves the screen state
output.SaveScreen()
// Switch to the altscreen. The former view can be restored with ExitAltScreen()
output.AltScreen()
// Exit the altscreen and return to the former terminal view
output.ExitAltScreen()
// Clear the visible portion of the terminal
output.ClearScreen()
// Clear the current line
output.ClearLine()
// Clear a given number of lines
output.ClearLines(n)
// Set the scrolling region of the terminal
output.ChangeScrollingRegion(top, bottom)
// Insert the given number of lines at the top of the scrollable region, pushing
// lines below down
output.InsertLines(n)
// Delete the given number of lines, pulling any lines in the scrollable region
// below up
output.DeleteLines(n)// SetWindowTitle sets the terminal window title
output.SetWindowTitle(title)
// SetForegroundColor sets the default foreground color
output.SetForegroundColor(color)
// SetBackgroundColor sets the default background color
output.SetBackgroundColor(color)
// SetCursorColor sets the cursor color
output.SetCursorColor(color)
// Hide the cursor
output.HideCursor()
// Show the cursor
output.ShowCursor()
// Copy to clipboard
output.Copy(message)
// Copy to primary clipboard (X11)
output.CopyPrimary(message)
// Trigger notification
output.Notify(title, body)// Enable X10 mouse mode, only button press events are sent
output.EnableMousePress()
// Disable X10 mouse mode
output.DisableMousePress()
// Enable Mouse Tracking mode
output.EnableMouse()
// Disable Mouse Tracking mode
output.DisableMouse()
// Enable Hilite Mouse Tracking mode
output.EnableMouseHilite()
// Disable Hilite Mouse Tracking mode
output.DisableMouseHilite()
// Enable Cell Motion Mouse Tracking mode
output.EnableMouseCellMotion()
// Disable Cell Motion Mouse Tracking mode
output.DisableMouseCellMotion()
// Enable All Motion Mouse mode
output.EnableMouseAllMotion()
// Disable All Motion Mouse mode
output.DisableMouseAllMotion()// Enables bracketed paste mode
termenv.EnableBracketedPaste()
// Disables bracketed paste mode
termenv.DisableBracketedPaste()- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Ghostty, Windows Terminal
 - 8-bit (256): rxvt, screen, xterm, Apple Terminal
 - 4-bit (16): Linux Console
 
Click to show feature matrix
| Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) | 
|---|---|---|---|---|---|---|---|---|---|
| alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 
| kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 
| Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | 
| urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| screen | ⛔1 | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | 
| st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| tmux | ⛔1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| vte-based2 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | 
| wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 
| xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | 
| Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 
| Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | 
| iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | 
| Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | 
| Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | 
You can help improve this list! Check out how to and open an issue or pull request.
Click to show feature matrix
| Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) | 
|---|---|---|---|
| alacritty | ✅ | ✅3 | ❌ | 
| foot | ✅ | ✅ | ✅ | 
| kitty | ✅ | ✅ | ✅ | 
| Konsole | ❌4 | ✅ | ❌ | 
| rxvt | ❌ | ❌ | ❌ | 
| urxvt | ✅5 | ❌ | ✅ | 
| screen | ✅ | ❌6 | ❌ | 
| st | ✅ | ❌ | ❌ | 
| tmux | ✅ | ❌7 | ❌ | 
| vte-based2 | ❌2 | ✅ | ❌ | 
| wezterm | ✅ | ✅ | ❌ | 
| xterm | ✅ | ❌ | ❌ | 
| Linux Console | ⛔ | ⛔ | ❌ | 
| Apple Terminal | ✅8 | ❌ | ❌ | 
| iTerm | ✅ | ✅ | ❌ | 
| Windows cmd | ❌ | ❌ | ❌ | 
| Windows Terminal | ✅ | ✅ | ❌ | 
termenv works on Unix systems (like Linux, macOS, or BSD) and Windows. While
terminal applications on Unix support ANSI styling out-of-the-box, on Windows
you need to enable ANSI processing in your application first:
    restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput())
    if err != nil {
        panic(err)
    }
    defer restoreConsole()The above code is safe to include on non-Windows systems or when os.Stdout does not refer to a terminal (e.g. in tests).
You can find the source code used to create this chart in termenv's examples.
- reflow - ANSI-aware text operations
 - Lip Gloss - style definitions for nice terminal layouts 👄
 - ansi - ANSI sequence helpers
 
Need some inspiration or just want to see how others are using termenv? Check
out these projects:
- Bubble Tea - a powerful little TUI framework 🏗
 - Glamour - stylesheet-based markdown rendering for your CLI apps 💇🏻♀️
 - Glow - a markdown renderer for the command-line 💅🏻
 - duf - Disk Usage/Free Utility - a better 'df' alternative
 - gitty - contextual information about your git projects
 - slides - terminal-based presentation tool
 
Got some feedback or suggestions? Please open an issue or drop me a note!
Footnotes
- 
Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time. ↩ ↩2
 - 
This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. ↩ ↩2 ↩3
 - 
OSC52 is not supported, for more info see bug#372116. ↩
 - 
Workaround for urxvt not supporting OSC52. See this for more information. ↩
 - 
OSC52 works with a workaround. ↩
 


