shui · 水
A Zsh design system. Semantic components, a token-based theme engine, and one consistent API — zero runtime dependencies.
git clone https://github.com/kud/shui.git
Built for real shell scripts
Stop hard-coding ANSI escape sequences. shui gives your scripts a consistent visual language with zero overhead.
Drop source shui.zsh at the top of any script.
Everything loads in a single pass — no package manager, no
install step.
Colours live in theme files, not components. Switch between
default, minimal, and
plain with one env var — or author your own.
Ship with Nerd Font glyphs, Unicode emoji, or plain ASCII. Set
SHUI_ICONS=emoji and every component adapts
automatically.
Every component speaks intent: shui success,
shui warning, shui badge error EOL. No
magic numbers, no raw escape codes.
Respects the NO_COLOR environment variable spec out
of the box. CI pipelines and screen readers get clean plain-text
output automatically.
confirm, select, radio,
multiselect, and input give your
scripts a polished interactive layer with sensible defaults.
Quick Start
Clone the repo, source the main file, and start using components immediately.
# 1. Clone
git clone https://github.com/kud/shui.git ~/shui
# 2. Source in your script
source ~/shui/shui.zsh
# 3. Use components
shui section "Deploying to production"
shui info "Pulling latest changes..."
shui success "Build complete"
shui warning "Restart required"
# Switch theme and icon set
SHUI_THEME=minimal SHUI_ICONS=emoji source ~/shui/shui.zsh
Component Examples
Every component rendered exactly as it appears in your terminal.
shui success "Operation completed"
shui error "Something went wrong"
shui warning "This cannot be undone"
shui info "Running in dry-run mode"
shui bold "Bold text"
shui dim "Dimmed text"
shui italic "Italic text"
shui underline "Underlined text"
shui text --color=primary "Primary"
shui text --color=success "Success"
shui text --color=warning "Warning"
shui text --color=error "Error"
shui text --color=muted "Muted"
shui section "Deploy pipeline"
shui subtitle "Step 1: Build"
shui subsection "Compiling sources"
shui spacer
shui divider
shui fence "output"
echo "$(shui badge success SUCCESS) \
$(shui badge error ERROR) \
$(shui badge warning WARNING)"
echo "$(shui badge info INFO) \
$(shui badge primary PRIMARY) \
$(shui badge muted MUTED)"
echo "$(shui pill success done) \
$(shui pill error failed) \
$(shui pill warning skipped)"
echo "$(shui pill info info) \
$(shui pill primary major) \
$(shui pill muted patch)"
shui box "Simple content inside a box"
shui box --title="Deployment Summary" \
"$(shui badge success 3) installed
$(shui badge warning 1) skipped
$(shui badge muted 0) errors"
┌──────────────────────────────────────┐ │ Simple content inside a box │ └──────────────────────────────────────┘ ┌────────── Deployment Summary ──────────┐ │ 3 installed │ │ 1 skipped │ │ 0 errors │ └──────────────────────────────────────┘
shui table \
"Package|Version|Status" \
"node|20.11.0|$(shui badge success OK)" \
"bun|1.1.3|$(shui badge success OK)" \
"python|3.12.0|$(shui badge warning outdated)" \
"ruby|2.7.0|$(shui badge error EOL)"
┌──────────┬───────────┬──────────┐ │ Package │ Version │ Status │ ├──────────┼───────────┼──────────┤ │ node │ 20.11.0 │ OK │ │ bun │ 1.1.3 │ OK │ │ python │ 3.12.0 │ outdated │ │ ruby │ 2.7.0 │ EOL │ └──────────┴───────────┴──────────┘
shui progress 0 100; echo
shui progress 25 100; echo
shui progress 50 100; echo
shui progress 75 100; echo
shui progress 100 100; echo
shui progress 65 100 \
--width=20 --label="Downloading "
# Wraps a command — spinner while it runs
shui spinner npm install
# Indeterminate loader styles
shui loader --style=dots
shui loader --style=pulse
shui loader --style=spinner
# Confirm — exits 0 for yes, 1 for no
if shui confirm "Deploy to production?"; then
shui success "Confirmed!"
fi
# Select — numbered list, type to choose
theme=$(shui select "Pick a theme:" \
default minimal plain)
# Radio — ↑↓ move · enter confirm
env=$(shui radio "Environment:" \
development staging production)
# Multiselect — ↑↓ move · space toggle · enter confirm
choices=$(shui multiselect "Which packages?" \
brew npm cargo)
selected=("${(@f)choices}")
# Input — free text
name=$(shui input --default="world" \
"Enter your name:")
# Full-screen runner with elapsed time
shui screen "Running tests" npm test
# One-shot text effects
shui animation typewriter "Hello, world"
shui animation fade-in "Hello, world"
Environment Variables
Set these before sourcing shui.zsh to customise
behaviour across all components.
| Variable | Values | Default | Description |
|---|---|---|---|
SHUI_THEME |
default minimal
plain
|
default |
Active colour theme. minimal uses 16-colour
ANSI; plain strips all colour and uses ASCII
icons.
|
SHUI_ICONS |
nerd emoji none
|
nerd |
Icon set. nerd requires a Nerd Font;
emoji uses Unicode emoji; none
disables icons entirely.
|
NO_COLOR |
any non-empty value | unset |
Disables all colour output when set. Follows the no-color.org spec. |
SHUI_DIR |
directory path | auto |
Root directory of the shui installation. Detected automatically from the sourced file path; override only if symlinked. |