---
name: "gum"
subtitle: "Polished shell-script UI components — choose, input, spinner, confirm"
date: 2026-05-06
category: terminal
tags: [shell, terminal, scripting, open-source, charm, cli]
link: "https://github.com/charmbracelet/gum"
description: "A Charm toolkit that gives bash and zsh scripts proper TUI components — fuzzy menus, password inputs, spinners — composable with pipes."
source: "One Thing Well"
fromFind: "gum-shell"
---

![Gum's choose component running in the terminal — a fuzzy menu with arrow-key navigation](./hero.png)

*Gum's `choose` component as a drop-in replacement for `read` and `select` — arrow-key fuzzy menu, no Go required.*

> A toolkit from Charm that turns bash and zsh scripts into things you'd actually want to share — fuzzy choosers, password prompts, spinners, multi-line confirmations — composable with pipes.

The shell's built-in interaction primitives stop at `read` and `select`. They've been there since the 1970s and they look it. Anything fancier traditionally meant rewriting your fifty-line script in Go, Python, or Node — and watching it grow into a thousand-line project nobody else on the team can reach into. Gum is the alternative: a small statically-linked binary, called like any other shell command, that gives you a Charm-quality TUI inside whatever script you've already written.

The components are the whole product: `gum choose` for menus, `gum input` for text fields (with a `--password` flag), `gum spin` for progress, `gum confirm` for yes/no, `gum filter` for fuzzy pickers, `gum write` for multi-line text, `gum format` for styled output. Each writes its result to stdout, so they pipe naturally — `gum choose option1 option2 | xargs -I {} gum confirm "Do {}?"` reads like a sentence rather than a Bash maze. The styling matches Glow, Lazygit, and the rest of the Charm catalog — rounded borders, subtle colors, restrained motion — with config cascading from CLI flags to environment variables to a `.gum.toml`.

Install via `brew install gum`, `apt-get install gum`, `go install`, or grab the static binary; no runtime dependency. Open source, MIT-licensed.

Honest limitation: it's a hard dependency in your script. Anyone running your function or installer needs `gum` on `$PATH`, which means either a bootstrap step at the top of the script or a Homebrew/apt declaration. For internal tools that's fine; for a "curl | bash" public installer it's friction worth weighing against the readability win.
