pb
A terminal progress bar library for Go with customizable templates, byte-aware formatting, and proxy readers/writers for tracking I/O.
Repository Health
Technical Analysis
pb is a lightweight Go library for rendering progress bars in terminal applications. It ships a set of ready-made presets (Default, Simple, Full) alongside a template engine that lets you compose fully custom bars from reusable elements such as percent, counters, speed, remaining/elapsed time, and the bar glyph itself, with color support via fatih/color.
Beyond simple counters, pb includes a NewProxyReader/NewProxyWriter pair that wraps any io.Reader or io.Writer so byte-oriented operations — file downloads, copies, uploads — automatically drive the bar’s progress and switch it into byte-formatted output (KiB/MiB or SI kB/MB). Terminal width detection is handled per-platform (Linux, BSD, Windows, Plan9, AIX, Solaris) through an internal termutil package, and adaptive elements resize themselves to fill whatever space the terminal provides.
The library has been stable and widely used since 2012, with the current v3 module (imported as github.com/cheggaaa/pb/v3) representing a rewrite of the original API that added the template-based element system and cleaner concurrency handling around a single mutex-guarded state.
What You Get
- Ready-to-use presets (Default, Simple, Full) for common progress-bar layouts with zero configuration
- A template engine with composable elements (bar, percent, counters, speed, rtime, etime, string, cycle) for building custom displays
- Byte-aware formatting (IEC KiB/MiB or SI kB/MB) for tracking file and network transfer progress
- NewProxyReader and NewProxyWriter wrappers that drive progress automatically from io.Reader/io.Writer operations
- Cross-platform terminal width detection (Linux, BSD, Windows, Plan9, Solaris, AIX) with graceful fallback
- Thread-safe operation via atomic counters and mutex-guarded state, safe to update from multiple goroutines
- Optional Unicode progress glyphs via the UNICODE_PROGRESS_BAR environment variable
- A RegisterElement API for adding entirely custom template elements
Common Use Cases
- Showing download/upload progress for CLI tools that fetch or transfer files
- Displaying batch job progress (e.g., processing N records) in long-running command-line scripts
- Wrapping io.Copy operations to report byte-level progress without changing the copy logic
- Building custom terminal dashboards with multiple concurrent progress bars via the pool sub-API
- Providing ETA and throughput (items/sec or bytes/sec) feedback during data migrations or imports
Under The Hood
Architecture
The library centers on a single ProgressBar struct (v3/pb.go) whose state is guarded by a sync.RWMutex for the counters/config and a separate sync.Mutex (rm) that serializes rendering, while current/total are updated with sync/atomic so Add/Increment calls from worker goroutines never block the render path. Rendering itself is delegated to text/template (getTemplate in template.go) executed against a State wrapper that exposes read-only accessors (Total, Value, Width, IsFinished) to templates and elements, keeping bar logic decoupled from presentation; a background goroutine (writer) ticks on refreshRate and pushes rendered frames to the configured io.Writer, with a finish channel used to synchronize shutdown in Finish(). Custom display logic plugs in through the Element interface and a global elements map (element.go), with an adaptiveWrap mechanism that defers width-dependent elements (like the bar glyph itself) to a second pass once static content width is known — a deliberately narrow but effective solution to the “bar must fill remaining terminal width” problem.
Tech Stack
Written in Go (module github.com/cheggaaa/pb/v3, requiring Go 1.25 in the current go.mod) with a small, focused dependency set: github.com/fatih/color for ANSI color output, github.com/mattn/go-colorable and github.com/mattn/go-isatty for cross-platform TTY/color detection, github.com/mattn/go-runewidth and github.com/clipperhouse/uax29/v2 for correct terminal cell-width calculation of Unicode strings, github.com/VividCortex/ewma for exponentially-weighted moving-average speed calculation, and golang.org/x/sys for platform syscalls. Terminal width detection is implemented per-OS in the internal termutil package (separate files per platform: Linux, BSD, Windows, Plan9, Solaris, AIX, plus a stub fallback), compiled in via Go build tags rather than runtime branching.
Code Quality
The v3 package ships table-style unit tests alongside most core files (pb_test.go, element_test.go, template_test.go, util_test.go, preset_test.go, io_test.go), and CI (.github/workflows/) runs go test -v ./... against the v3 module on every push and PR to master. Error handling is explicit and typed: ProgressBar carries an internal err field surfaced through Err()/SetErr() rather than panicking, and template execution failures are captured rather than propagated as fatal errors, though a render-time recover() is used as a defensive backstop for template panics. Naming is consistent and idiomatic Go (exported types/methods documented with standard doc comments), and there is no linter config or static-analysis step visible in CI beyond go test.
What Makes It Unique
Rather than hardcoding a fixed set of progress-bar layouts, pb exposes its rendering as a text/template-driven pipeline where every visual piece — bar glyph, percentage, counters, speed, timers — is a registered Element that any consumer can override or extend via RegisterElement, and the adaptive-width mechanism lets a single bar element auto-fill whatever terminal space remains after the rest of the template is rendered. Combined with byte-aware Proxy readers/writers that require no additional wiring to track I/O throughput, this gives pb a template-first customization model that is less common among comparable Go progress-bar libraries, most of which expose only a fixed handful of preset styles.
Used by 2 apps in this directory
Okteto
Devops · Developer Tools
Develop applications directly inside your Kubernetes cluster with real-time file sync and instant hot-reload — no more docker build/redeploy cycles.
TiDB
Databases · AI Development
AI-Native Distributed SQL Database for Agentic Workloads