[go-fan] Go Module Review: charmbracelet/lipgloss #22626
Closed
Replies: 1 comment
-
|
This discussion has been marked as outdated by Go Fan. A newer discussion is available at Discussion #22839. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Module Overview
Lip Gloss is a CSS-inspired terminal styling library from the Charm team. It provides a declarative, chainable API for colors, borders, padding, margins, alignment, and layout composition — the design layer for Bubble Tea TUIs. This is one of the most actively maintained modules in gh-aw's dependency tree, with v2.0.2 released on 2026-03-11.
The module went through a major migration: v1 lived at
github.com/charmbracelet/lipgloss, while v2 moved tocharm.land/lipgloss/v2— a new import path with significant API improvements.Current Usage in gh-aw
The project uses both lipgloss versions simultaneously:
charm.land/lipgloss/v2pkg/styles/theme.go,pkg/console/console.go,pkg/console/banner.go,pkg/console/list.gogithub.com/charmbracelet/lipglosspkg/styles/huh_theme.goonlyNewStyle(),compat.AdaptiveColor,charm.land/lipgloss/v2/table,JoinVertical,RoundedBorder(),DoubleBorder(),Border(),Foreground(),Background(),Bold(),Italic()The split is intentional:
pkg/styles/huh_theme.godocuments clearly thathuh v0.8.0depends on the v1 type system (lipgloss.AdaptiveColor,lipgloss.HiddenBorder()), so it cannot yet be migrated to v2.Research Findings
Recent Updates (v2.0.2 — 2026-03-11)
pkg/console/console.gousescharm.land/lipgloss/v2/tableforRenderTable.Best Practices from Maintainers
Styleis a pure value type — no renderer pointer, no global state, safe for package-level variables and concurrent use.Style.Render()always emits full ANSI; uselipgloss.Println/lipgloss.Fprintfor automatic downsampling to terminal capability.LightDarkis the idiomatic v2 color adaptation —compat.AdaptiveColorworks but reads global I/O;LightDark(isDark)(light, dark)is more explicit.var— sinceStyleis a value type, allocation is cheap but avoids repeated construction.Improvement Opportunities
🏃 Quick Wins
1. Hoist inline styles in
pkg/console/list.goIn
itemDelegate.Render(), three styles are created fresh on every item render frame:Since
Styleis a value type in v2, these are safe to define as package-levelvar(like the pattern already used inpkg/styles/theme.go), avoiding per-frame allocation.2. Consider
lipgloss.Fprint/lipgloss.Fprintlnfor styled stderr outputpkg/console/console.gouses the manualapplyStyle(style, text)+isTTY()guard pattern. In v2, usinglipgloss.Fprint(os.Stderr, ...)would handle automatic color downsampling at the writer level, removing the need for the TTY check insideapplyStyle.View current vs. v2-idiomatic pattern
This is a nice-to-have refactor, not a bug — the current approach is correct and safe.
✨ Feature Opportunities
1. Clickable hyperlinks for file paths
v2 adds
lipgloss.NewStyle().Hyperlink(url)support. File paths inFormatErrorcould render as terminal hyperlinks in supporting terminals (VS Code, iTerm2, modern terminals):2. Richer underline styles in
ListHeaderv2 offers
UnderlineStyle(lipgloss.UnderlineCurly),UnderlineDouble,UnderlineDotted, etc. TheListHeaderstyle intheme.gouses basicUnderline(true):3. Gradient error box border
v2 adds
BorderForegroundBlend(...color.Color)for gradient border colors, which could make theErrorBoxintheme.gomore visually impactful.📐 Best Practice Alignment
1.
compat.AdaptiveColorvsLightDarkThe project uses
compat.AdaptiveColoracross all oftheme.go. While this works, the v2 upgrade guide notes thatcompat"reads stdin/stdout globally" which "removes transparency around when I/O happens." For new code,LightDark(isDark)(light, dark)is preferred. The existing usage is fine — this is a future migration consideration.2. Tracking huh v1→v2 migration
The
huh_theme.gov1 dependency will become removable oncegithub.com/charmbracelet/huhupdates tocharm.land/lipgloss/v2. This should be tracked — it will simplify the go.mod by removing thegithub.com/charmbracelet/lipglossdirect dependency.🔧 General Improvements
The project's lipgloss usage is well-structured overall:
pkg/styles/) and usage (pkg/console/)Error,Warning,Success,Info,FilePath, etc.)Recommendations
selectedStyle,titleStyle,descStyleto package-level inlist.gopkg/console/list.go:92-103pkg/styles/huh_theme.goHyperlink()for file path rendering in error outputpkg/console/console.gocompat.AdaptiveColortoLightDarkfor new stylespkg/styles/theme.goNext Steps
github.com/charmbracelet/huhreleasing a version that depends oncharm.land/lipgloss/v2— at that pointhuh_theme.gocan be migrated and the v1 dep removedcharm.land/lipgloss/v2 v2.0.2is already in go.modModule summary saved to:
scratchpad/mods/charmbracelet-lipgloss.mdWorkflow run: §23477800939
Beta Was this translation helpful? Give feedback.
All reactions