[go-fan] Go Module Review: charmbracelet/huh #23073
Closed
Replies: 1 comment
-
|
This discussion has been marked as outdated by Go Fan. A newer discussion is available at Discussion #23213. |
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.
-
🐹 Go Fan Report: charmbracelet/huh — Terminal Forms & Prompts
Module Overview
github.com/charmbracelet/huhis Charmbracelet's terminal forms library built on Bubble Tea. It provides composable form fields —Input,Select,MultiSelect,Confirm,Text(textarea),Note, andFilePicker— grouped into multi-page forms with validation, theming, and accessible fallback modes.Current version:
v0.8.0(v1 API)Latest available:
v2.0.3oncharm.land/huh/v2(released 2026-03-10)Current Usage in gh-aw
12 files import
huhacross thepkg/directory:pkg/styles/huh_theme.gohuh.ThemeBase()pkg/console/confirm.goNewConfirm()for yes/no dialogspkg/console/input.goNewInput()withEchoModePasswordfor secret entrypkg/cli/interactive.goSelect,MultiSelect,Textpkg/cli/engine_secrets.goNewInput()forms for API key/token collectionpkg/cli/add_interactive_engine.goNewSelect[string]()for AI engine selectionpkg/cli/add_interactive_auth.goNewInput()withowner/repoformat validationpkg/cli/add_interactive_*.go(×5)pkg/cli/run_interactive.goKey APIs used:
NewForm,NewGroup,NewInput,NewSelect[T],NewMultiSelect[T],NewConfirm,NewText,NewOption,EchoModePassword,WithTheme,WithAccessible(form-level only),RunWithContext,Option[T]All forms follow a consistent pattern:
Research Findings
The Dual-Lipgloss Situation
The most notable finding is this comment in
pkg/styles/huh_theme.go:The project needs
github.com/charmbracelet/lipgloss(v1) as an indirect dep solely becausehuh v0.8.0depends on it — even though the rest of the codebase usescharm.land/lipgloss/v2. Upgrading huh to v2 would clean this up.v1 → v2 Breaking Changes (relevant to gh-aw)
github.com/charmbracelet/huhcharm.land/huh/v2*huh.Themehuh.ThemeFunc(func(isDark bool) *Styles)ThemeBasesignatureThemeBase()ThemeBase(isDark bool)WithThemeargument*huh.Themehuh.Themeinterfacegithub.com/charmbracelet/lipglosscharm.land/lipgloss/v2WithAccessible()The project already uses form-level
WithAccessible()only — no field-level calls — so that breaking change has zero impact.Recent Updates (v2.x line)
WithWidthThemeDracula,ThemeCatppuccin, built-in themes now takeisDark bool;ThemeFuncreplaces theThemestruct;Modeltype exported;WithViewHookaddedImprovement Opportunities
🏃 Quick Wins
Extract validation helpers: The project has inline validators scattered across forms (
len(s) == 0,len(s) < 10,owner/repoformat check). These could live in a sharedpkg/console/validate.go, reducing repetition across the 12 files.Form builder helper: Every form call duplicates
.WithTheme(styles.HuhTheme()).WithAccessible(console.IsAccessibleMode()). A thin helper that applies these defaults would reduce boilerplate:✨ Feature Opportunities
Upgrade to
charm.land/huh/v2: This is the primary recommendation. The migration path is:github.com/charmbracelet/huh→charm.land/huh/v2HuhTheme()return type:*huh.Theme→huh.ThemeFunchuh.ThemeBase()→huh.ThemeBase(isDark), usecharm.land/lipgloss/v2instead of v1lipgloss.HasDarkBackground()forisDarkdetectiongithub.com/charmbracelet/lipglossfromgo.mod(no longer needed)Consider
huh.ThemeDracula(isDark): huh v2 now ships a built-in Dracula theme. The project's custom theme inpkg/styles/huh_theme.gois a Dracula-inspired palette — after upgrading, it might be worth checking ifhuh.ThemeDracula(isDark)matches closely enough to replace the custom theme entirely (or use it as the base with minimal overrides).View Hooks (new in v2):
form.WithViewHook(func(v tea.View) tea.View)enables pre-render customization. Could be useful for any full-screen interactive prompts that need alt-screen mode.📐 Best Practice Alignment
Theme function signature: After v2 migration,
HuhTheme()should become ahuh.ThemeFunc:This gives the theme proper light/dark adaptability instead of only responding to
lipgloss.AdaptiveColor.isDark detection: Currently the custom theme relies on
lipgloss.AdaptiveColorfor light/dark switching. With v2, theisDark boolparameter passed toThemeFuncenables explicit conditional styling, which is cleaner and more testable.Recommendations (Prioritized)
[High] Upgrade
huhtocharm.land/huh/v2— Unifies all Charm dependencies undercharm.land/*, eliminates the dual lipgloss dependency, and aligns with the already-upgraded bubbletea/bubbles/lipgloss v2 stack. The migration checklist is short and all breaking changes have minimal impact on the current codebase.[Medium] Refactor
HuhTheme()toThemeFunc— Part of the v2 upgrade; enables proper isDark-aware adaptive theming.[Low] Evaluate
huh.ThemeDracula(isDark)as base — After v2 upgrade, compare the built-in Dracula theme against the custom one; may eliminatepkg/styles/huh_theme.goor greatly simplify it.[Low] Extract form validation helpers — Move inline validators to shared utilities to reduce duplication across 12 call sites.
Next Steps
huhfromv0.8.0tocharm.land/huh/v2— the upgrade guide covers all required changesgithub.com/charmbracelet/lipglossfromgo.mod(it will no longer be needed as a direct dep)go mod tidyto clean upModule summary saved to:
scratchpad/mods/huh.mdSorted by
pushed_at— huh was most recently updated (2026-03-18) among unreviewed direct dependenciesReferences:
Beta Was this translation helpful? Give feedback.
All reactions