halo
Beautiful terminal spinners for Python — provides elegant spinner animations for CLI applications during long-running tasks. halo features: Halo context manager, 40+ spinner styles (dots, line, pipe, bouncing ball, moon phases, etc.), color support, text alongside spinner, succeed()/fail()/warn()/info() for final state, stop_and_persist() with custom symbol, spinner chaining, manual start()/stop(), enabled parameter for non-TTY, stream parameter for stderr support, and @Halo decorator for function decoration.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Terminal spinner library with no network calls. No security concerns. Minimally maintained — dependency hygiene lower due to infrequent updates. Consider pinning version.
⚡ Reliability
Best When
Simple elegant spinner for CLI tools — halo is the most aesthetically polished spinner library for Python, ideal when visual quality matters for developer tools.
Avoid When
Multiple simultaneous spinners (use enlighten), determinate progress (use tqdm), or when yaspin's API is already familiar.
Use Cases
- • Agent CLI loading indicator — from halo import Halo; with Halo(text='Loading...', spinner='dots') as spinner: data = fetch_data(); spinner.succeed('Data loaded successfully!') — spinner with success; agent shows animated spinner during API calls; succeed() stops animation with ✓; fail() shows ✗
- • Agent decorator usage — from halo import Halo; @Halo(text='Processing', spinner='dots12'); def long_task(): return result; long_task() — function decorator; agent wraps functions with spinner; spinner starts when function called; stops when function returns or raises
- • Agent custom spinner style — spinner = Halo(text='Fetching', spinner={'interval': 100, 'frames': ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']}, color='cyan'); spinner.start(); result = compute(); spinner.succeed() — custom frames; agent defines custom animation frames and interval
- • Agent stderr spinner — from halo import Halo; spinner = Halo(text='Working', stream=sys.stderr); spinner.start(); result = produce_stdout_output(); spinner.stop() — stderr spinner; agent uses spinner on stderr while stdout produces data output; prevents mixing spinner with pipeline data
- • Agent conditional spinner — from halo import Halo; with Halo(text='Processing', enabled=sys.stdout.isatty()) as spinner: process() — conditional; agent disables spinner in non-TTY environments; output is clean in CI/pipes; spinner enabled only when interactive
Not For
- • Multiple simultaneous spinners — halo shows one spinner at a time; for multiple bars use enlighten
- • Determinate progress — halo is indeterminate spinner; for progress bars use tqdm
- • Complex TUI — halo is single-line spinner; for full TUI use urwid/textual
Interface
Authentication
No auth — terminal spinner library.
Pricing
halo is MIT licensed. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ halo is minimally maintained — halo has not had active development since ~2019; last PyPI release 0.0.31; agent code using halo may encounter Python version compatibility issues or unfixed bugs; consider yaspin as actively maintained alternative with similar API
- ⚠ print() inside context corrupts spinner — print() writes directly to stdout without coordinating with spinner thread; spinner renders use carriage return (\r) to overwrite — plain print() interleaves badly; agent code: avoid print() inside with Halo(); or stop spinner, print, restart
- ⚠ succeed()/fail() text is separate from initial text — spinner = Halo(text='Loading'); spinner.succeed('Done!') — the succeed text replaces the spinner text entirely; agent code: include context in succeed/fail text; or: spinner.text = 'Processing complete'; spinner.succeed() to use updated text
- ⚠ enabled=False suppresses all output including final state — Halo(enabled=False) makes all methods no-ops including succeed()/fail(); agent code using enabled=False for non-TTY: if agent code then uses result of succeed() for flow control, it still works; but no visible output at all
- ⚠ @Halo decorator does not forward return value — in some versions, @Halo decorated functions return None not the function's return value; agent code using @Halo decorator: test that return value is preserved; use context manager with Halo() as sp: instead if return value must be captured
- ⚠ spinner thread blocks on fast functions — Halo runs animation in background thread; for very fast functions (<80ms), spinner may never visually appear then immediately succeed; agent code: spinner is more useful for operations taking >0.5s; for fast operations, simple print statement may be more appropriate
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for halo.
Scores are editorial opinions as of 2026-03-06.