Lip Gloss
GitHub Overview
charmbracelet/lipgloss
Style definitions for nice terminal layouts 👄
Repository:https://github.com/charmbracelet/lipgloss
Stars9,305
Watchers35
Forks259
Created:March 1, 2021
Language:Go
License:MIT License
Topics
cligogolanghacktoberfestlayoutstyletui
Star History
Data as of: 7/25/2025, 11:09 AM
Lip Gloss
Lip Gloss is a styling library for terminal applications developed by Charmbracelet. With an intuitive CSS-like API, it allows you to apply beautiful layouts and styles to terminals. As part of the Bubble Tea and Charm ecosystem, it's used in many projects.
Features
CSS-like Styling
- Properties: Colors, padding, margins, borders
- Layout: Flexbox-like alignment, positioning
- Text Decoration: Bold, italic, underline, strikethrough
- Animation: Blinking, fading
Advanced Features
- Adaptive Colors: Color adjustment based on terminal capabilities
- Gradients: Gradient backgrounds
- Responsive: Adjustments based on terminal size
- Style Inheritance: CSS-like style inheritance
Utilities
- Table Rendering: Beautiful table creation
- Join Functions: Element combination
- Wrapping and Truncation: Text processing
- Custom Renderers: Extensible rendering system
Performance
- Zero Allocation: Style reuse
- Efficient Rendering: Minimal ANSI codes
- Caching: Style calculation caching
- Lightweight: Minimal dependencies
Basic Usage
Installation
go get github.com/charmbracelet/lipgloss
Hello World
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// Basic style
style := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FAFAFA")).
Background(lipgloss.Color("#7D56F4")).
PaddingTop(2).
PaddingLeft(4).
Width(22)
fmt.Println(style.Render("Hello, Lip Gloss!"))
}
Combining Styles
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// Base style
var baseStyle = lipgloss.NewStyle().
PaddingLeft(1).
PaddingRight(1)
// Title style
titleStyle := baseStyle.Copy().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
MarginTop(1).
MarginBottom(1)
// Content style
contentStyle := baseStyle.Copy().
Foreground(lipgloss.Color("#CCCCCC")).
Padding(1, 2)
// Border style
borderStyle := lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("62")).
Padding(1, 2)
// Rendering
title := titleStyle.Render("Welcome")
content := contentStyle.Render("This is content styled\nwith Lip Gloss.")
// Combining
output := lipgloss.JoinVertical(lipgloss.Left, title, content)
fmt.Println(borderStyle.Render(output))
}
Layout and Positioning
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// Get terminal size
width := 80
height := 24
// Header
headerStyle := lipgloss.NewStyle().
Background(lipgloss.Color("62")).
Foreground(lipgloss.Color("230")).
Bold(true).
Align(lipgloss.Center).
Width(width).
Padding(0, 1)
header := headerStyle.Render("🌈 My Application")
// Sidebar
sidebarStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder(), false, true, false, false).
BorderForeground(lipgloss.Color("240")).
Width(20).
Height(height - 4).
Padding(1)
sidebar := sidebarStyle.Render("Menu\n\n• Home\n• About\n• Contact")
// Main content
mainStyle := lipgloss.NewStyle().
Width(width - 22).
Height(height - 4).
Padding(2).
Align(lipgloss.Center, lipgloss.Center)
main := mainStyle.Render("Main Content Area")
// Footer
footerStyle := lipgloss.NewStyle().
Background(lipgloss.Color("235")).
Foreground(lipgloss.Color("241")).
Align(lipgloss.Center).
Width(width)
footer := footerStyle.Render("Press q to quit")
// Assemble layout
body := lipgloss.JoinHorizontal(lipgloss.Top, sidebar, main)
doc := lipgloss.JoinVertical(lipgloss.Left, header, body, footer)
fmt.Println(doc)
}
Creating Tables
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
)
func main() {
// Table data
rows := [][]string{
{"ID", "Name", "Age", "City"},
{"1", "Alice", "30", "New York"},
{"2", "Bob", "25", "Los Angeles"},
{"3", "Charlie", "35", "Chicago"},
}
// Create table
t := table.New().
Border(lipgloss.NormalBorder()).
BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99")))
// Header style
headerStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("230")).
Background(lipgloss.Color("63")).
Align(lipgloss.Center)
// Even row style
evenRowStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("245"))
// Odd row style
oddRowStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("250"))
// Apply styles to table
t.Headers(rows[0]...).
StyleFunc(func(row, col int) lipgloss.Style {
if row == 0 {
return headerStyle
}
if row%2 == 0 {
return evenRowStyle
}
return oddRowStyle
})
// Add data
for _, row := range rows[1:] {
t.Row(row...)
}
fmt.Println(t)
}
Gradients and Animation
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// Gradient style
gradientStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
Background(lipgloss.Color("#FFD700")).
Width(40).
Align(lipgloss.Center).
Margin(1)
// Blinking style
blinkStyle := lipgloss.NewStyle().
Blink(true).
Foreground(lipgloss.Color("#FF0000")).
Bold(true)
// Underline style
underlineStyle := lipgloss.NewStyle().
Underline(true).
UnderlineSpaces(true).
Foreground(lipgloss.Color("#00FF00"))
// Reverse style
reverseStyle := lipgloss.NewStyle().
Reverse(true).
Padding(0, 2)
fmt.Println(gradientStyle.Render("Gradient Background"))
fmt.Println(blinkStyle.Render("Blinking Text"))
fmt.Println(underlineStyle.Render("Underlined Text"))
fmt.Println(reverseStyle.Render("Reversed Text"))
}
Advanced Features
Adaptive Colors
// Color selection based on terminal capabilities
adaptiveColor := lipgloss.AdaptiveColor{
Light: "#000000",
Dark: "#FFFFFF",
}
style := lipgloss.NewStyle().
Foreground(adaptiveColor)
Custom Borders
// Define custom border
customBorder := lipgloss.Border{
Top: "━",
Bottom: "━",
Left: "┃",
Right: "┃",
TopLeft: "┏",
TopRight: "┓",
BottomLeft: "┗",
BottomRight: "┛",
}
style := lipgloss.NewStyle().
Border(customBorder).
BorderForeground(lipgloss.Color("63"))
Responsive Design
func responsiveLayout(width int) string {
var style lipgloss.Style
if width < 40 {
// Mobile layout
style = lipgloss.NewStyle().
Width(width).
Padding(1)
} else if width < 80 {
// Tablet layout
style = lipgloss.NewStyle().
Width(width).
Padding(2).
Margin(1)
} else {
// Desktop layout
style = lipgloss.NewStyle().
Width(width / 2).
Padding(3).
Margin(2).
Border(lipgloss.NormalBorder())
}
return style.Render("Content")
}
Componentization
// Button component
func Button(label string, primary bool) string {
style := lipgloss.NewStyle().
Padding(0, 3).
Bold(true).
Border(lipgloss.RoundedBorder())
if primary {
style = style.
Foreground(lipgloss.Color("#FFFFFF")).
Background(lipgloss.Color("#7D56F4")).
BorderForeground(lipgloss.Color("#7D56F4"))
} else {
style = style.
Foreground(lipgloss.Color("#7D56F4")).
BorderForeground(lipgloss.Color("#7D56F4"))
}
return style.Render(label)
}
// Card component
func Card(title, content string) string {
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
MarginBottom(1)
contentStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#CCCCCC"))
cardStyle := lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#666666")).
Padding(1, 2).
Width(40)
card := lipgloss.JoinVertical(
lipgloss.Left,
titleStyle.Render(title),
contentStyle.Render(content),
)
return cardStyle.Render(card)
}
Ecosystem
Charmbracelet Tools
- Bubble Tea: TUI framework
- Bubbles: TUI component collection
- Glamour: Markdown renderer
- Glow: Markdown viewer
Adoption Examples
- gh: GitHub CLI
- lazygit: Git TUI
- soft-serve: Git server
- mods: AI chat CLI
Advantages
- Intuitive: CSS-like API
- Beautiful: Professional appearance
- Flexible: Easy componentization
- Efficient: Performance focused
- Active: Continuous development by Charmbracelet
Limitations
- Styling Only: No interactive features
- Framework Dependent: Cannot create TUI apps alone
- Layout Limitations: Complex layouts require manual calculation
Comparison with Other Libraries
Feature | Lip Gloss | tview | termui |
---|---|---|---|
Purpose | Styling | Full TUI | Dashboard |
API | CSS-like | Widget | Widget |
Learning Cost | Low | Low | Medium |
Flexibility | Very High | Medium | Low |
Ecosystem | Charmbracelet | Independent | Independent |
Summary
Lip Gloss is an excellent library for applying beautiful styles to terminal applications. With its intuitive CSS-like API, developers can easily create professional-looking terminal UIs. While it cannot build complete TUI applications alone, when combined with Bubble Tea, it enables the creation of the most modern and beautiful TUI applications.