progressbar

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2025 License: Apache-2.0 Imports: 7 Imported by: 7

README

progressbar

GoDoc Go Report Card CI Checks GitHub Release

Zero dependency cross platform (just needs basic ANSI codes and Unicode font support, and ANSI codes can be disabled too if needed) golang concurrent safe progress bar for terminal/CLIs, with 8x the resolution of others (8 steps per character).

Shows a spinner and/or a progress bar with optional prefix and extra info.

Also provides reader/writer wrappers to automatically show progress of downloads/uploads or other io operations, as well as a Writer that can be used concurrently with the progress bar to show other output on screen.

Examples

See examples/

Manually updating a progress bar and additional output

Manually handling a 2-line output update (1 misc line and the 1 line for the progress bar):

	pb := progressbar.NewBar()
	fmt.Print("Progress bar example\n\n") // 1 empty line before the progress bar, for the demo
	n := 1000
	for i := 0; i <= n; i++ {
		pb.ProgressBar(100. * float64(i) / float64(n))
		if i%63 == 0 {
			progressbar.MoveCursorUp(1)
			fmt.Printf("Just an extra demo print for %d\n", i)
		}
		time.Sleep(20 * time.Millisecond)
	}

Source: examples/simple/simple.go (-moveup mode)

Concurrent safe screen writer example
	pb := progressbar.NewBar()
	w := pb.Writer()
	fmt.Fprintln(w, "Progress bar example")
	// demonstrate concurrency safety:
	go PrintStuff(w, *everyFlag)
	// exact number of 'pixels', just to demo every smooth step:
	n := pb.Width * 8
	for i := 0; i <= n; i++ {
		pb.ProgressBar(100. * float64(i) / float64(n))
		time.Sleep(*delayFlag)
	}
go run fortio.org/progressbar/examples/simple@latest -color

Produces

Example Screenshot

Or without color:

◅███████████████████████████▊            ▻ 69.4%

Source: examples/simple/example.go (default mode)

Automatic Reader or Writer progress bar
	reader := progressbar.NewAutoReader(progressbar.NewBar(), resp.Body, resp.ContentLength)
	_, err = io.Copy(os.Stdout, reader)
	reader.Close()

See it in action with a progress bar while downloading a URL:

go run fortio.org/progressbar/examples/auto@latest https://go.dev/ > go_dev.html

Will show a progress bar for instance

$  go run ./examples/auto https://go.dev/dl/go1.24.1.src.tar.gz > /dev/null
Fetching https://go.dev/dl/go1.24.1.src.tar.gz
⣾ █████████████████████▌                   53.7% 15.766 Mb out of 29.352 Mb, 293ms elapsed, 53.790 Mb/s, 253ms remaining

Source (now includes a multi bar separating R/W): auto_examples/auto/auto_example.go

Multiple Bars updating concurrently
	cfg := progressbar.DefaultConfig()
	cfg.ExtraLines = 1
	cfg.ScreenWriter = os.Stdout
	mbar := cfg.NewMultiBarPrefixes(
		"b1",
		"longest prefix",
		"short",
		"b4",
	)
	wg := sync.WaitGroup{}
	for i, bar := range mbar {
		wg.Add(1)
		// Update at random speed so bars move differently for a demo:
		delay := time.Duration(5+rand.IntN(40)) * time.Millisecond
		bar.WriteAbove(fmt.Sprintf("\t\t\tBar %d delay is %v", i+1, delay))
		go func(b *progressbar.State) {
			UpdateBar(b, delay)
			wg.Done()
		}(bar)
	}
	wg.Wait()
	progressbar.MultiBarEnd(mbar)

Multi example Screenshot

Complete source: multi_example/multi_example.go

Which includes adding extra bars dynamically.

Multicurl

You can see it in use in fortio/multicurl cli too.

See also

If you have more advanced needs for TUI including raw mode input or readline, you can also see/use/have a look at

github.com/fortio/terminal

And still use this for a progress bar part.

It is used for instance in github.com/fortio/fps's web mode progress update

And grol's multi file processing progress info (make grol-tests)

Documentation

Overview

Package progressbar is a simple zero dependency cross platform (only need ANSI(*) compatible terminal) progress bar library for your golang terminal / command line interface (CLI) applications. Shows a spinner and/or a progress bar with optional prefix and extra info. The package provides reader/writer wrappers to automatically show progress of downloads/uploads or other io operations. As well as a Writer that can be used concurrently with the progress bar to show other output on screen.

ANSI codes can be disabled completely for non terminal output or testing or as needed. Color is enabled by default but can also be disabled.

Index

Constants

View Source
const (
	DefaultWidth = 40
	Space        = " "
	Full         = "█"

	GreenBar     = "\033[32;100m"
	RedBar       = "\033[91;100m"
	YellowBar    = "\033[93;100m"
	BlueBar      = "\033[34;100m"
	WhiteBar     = "\033[97;100m"
	DefaultColor = GreenBar
	Reset        = "\033[0m"
	ClearAfter   = "\033[J"
	DoneSpinner  = "✓ "
	// DefaultMaxUpdateInterval is the default max refresh to avoid slowing down transfers because of progress bar updates.
	DefaultMaxUpdateInterval = 100 * time.Millisecond
	// ExpectedMaxLength is the expected max length of a progress bar line (prefix + spinner + bar + percentage + extra).
	// used for initial buffer size, will resize if needed but should be avoided. Note it includes
	// non printable ANSI sequences and utf8 encoded characters so it's the same as the onscreen width.
	ExpectedMaxLength = 256
)

Variables

View Source
var (
	FractionalBlocks = [...]string{"", "▏", "▎", "▍", "▌", "▋", "▊", "▉"}
	SpinnerChars     = [...]string{"⣾ ", "⣷ ", "⣯ ", "⣟ ", "⡿ ", "⢿ ", "⣻ ", "⣽ "}
)

Functions

func HumanBytes added in v0.5.0

func HumanBytes[T int64 | float64](inp T) string

HumanBytes shows bytes in `b`, `Kb`, `Mb`, `Gb` and can also be used for speed/rate (by appending "/s") in addition to raw bytes quantities.

func HumanDuration added in v0.5.0

func HumanDuration(d time.Duration) string

HumanDuration shows a duration rounded according to it's order of magnitude (minute/100ms/1ms resolution).

func Spinner added in v0.4.0

func Spinner()

Spinner is a standalone spinner when the total or progress toward 100% isn't known. (but a progressbar with -1 total or with negative % progress does that too).

Types

type AutoProgress added in v0.5.0

type AutoProgress struct {
	*Bar
	// contains filtered or unexported fields
}

AutoProgress is base progress bar for auto reader/writers.

func NewAutoProgress added in v1.2.0

func NewAutoProgress(bar *Bar, total int64) *AutoProgress

NewAutoProgress returns a new AutoProgress associated with the given bar and total size. AutoProgress.Update can be called from multiple goroutines to increment the progress by <n>.

func (*AutoProgress) Extra added in v0.5.0

func (a *AutoProgress) Extra(_ *Bar, progressPercent float64) string

Extra provides the extra information on the right of the progress bar: currrent transfer amount, speed and estimated time left.

func (*AutoProgress) Update added in v0.5.0

func (a *AutoProgress) Update(n int)

type AutoProgressReader added in v0.5.0

type AutoProgressReader struct {
	AutoProgress
	// contains filtered or unexported fields
}

AutoProgressReader is a reader proxy associated with a progress bar.

func NewAutoReader added in v0.5.0

func NewAutoReader(bar *Bar, r io.Reader, total int64) *AutoProgressReader

NewAutoReader returns a new io.Reader that will update the progress bar as it reads from the underlying reader up to the expected total (pass a negative total for just spinner updates for unknown end/total).

func (*AutoProgressReader) Close added in v0.5.0

func (r *AutoProgressReader) Close() error

func (*AutoProgressReader) Read added in v0.5.0

func (r *AutoProgressReader) Read(p []byte) (n int, err error)

type AutoProgressWriter added in v0.5.0

type AutoProgressWriter struct {
	AutoProgress
	// contains filtered or unexported fields
}

AutoProgressWriter is a writer proxy associated with a progress bar.

func NewAutoWriter added in v0.5.0

func NewAutoWriter(bar *Bar, w io.Writer, total int64) *AutoProgressWriter

NewAutoWriter returns a new io.Writer that will update the progress bar as it writes from the underlying writer up to the expected total (pass a negative total for just spinner updates for unknown end/total).

func (*AutoProgressWriter) Close added in v0.5.0

func (w *AutoProgressWriter) Close() error

func (*AutoProgressWriter) Write added in v0.5.0

func (w *AutoProgressWriter) Write(p []byte) (n int, err error)

type Bar added in v0.10.0

type Bar struct {
	Config
	// Extra string to show after the progress bar. Keep nil for no extra.
	Extra func(cfg *Bar, progressPercent float64) string
	// contains filtered or unexported fields
}

func NewBar added in v0.7.0

func NewBar() *Bar

NewBar returns a new progress bar with default settings (DefaultWidth, color and spinner on, no extra nor prefix) and using the shared global ScreenWriter. Use cfg.NewBar() to create a new progress bar with a specific/different config.

func (*Bar) End added in v0.10.0

func (bar *Bar) End()

End the progress bar: writes a newline and last update if it was skipped earlier due to rate limits. This is called automatically upon Close() by the Auto* wrappers.

func (*Bar) MoveCursorUp added in v0.10.0

func (bar *Bar) MoveCursorUp(n int)

MoveCursorUp moves the cursor up n lines and clears that line. If NoAnsi is configured, this just issue a new line.

func (*Bar) Progress added in v0.10.0

func (bar *Bar) Progress(progressPercent float64)

Progress shows a progress bar percentage (0-100%). On the same line as current line, so when call repeatedly it will overwrite/update itself. Use MoveCursorUp to move up to update other lines as needed or use Writer() to write output without mixing with a progress bar. This is thread safe / acquires a shared lock to avoid issues on the output. Of note it will work best if every output to the Writer() ends with a \n. The bar state must be obtained from NewBar() or cfg.NewBar() to setup the shared lock.

func (*Bar) Redraw added in v0.10.0

func (bar *Bar) Redraw()

Redraw force the redraw the progress bar with last known percentage.

func (*Bar) UpdatePrefix added in v0.10.0

func (bar *Bar) UpdatePrefix(p string)

UpdatePrefix changes the prefix while the progress bar is running. This is thread safe / acquires a shared lock to avoid issues on the output.

func (*Bar) UpdateSuffix added in v1.1.0

func (bar *Bar) UpdateSuffix(s string)

UpdateSuffix changes the suffix while the progress bar is running. This is thread safe / acquires a shared lock to avoid issues on the output.

func (*Bar) WriteAbove added in v0.10.0

func (bar *Bar) WriteAbove(msg string)

WriteAbove is for multibars with extra lines, writes (1 line) above the bar.

func (*Bar) Writer added in v0.10.0

func (bar *Bar) Writer() io.Writer

Writer returns the io.Writer that can be safely used concurrently with associated with the progress bar. Any writes will clear the current line/progress bar and write the new content, and then rewrite the progress bar at the next update.

type Config

type Config struct {
	// Width of the progress bar in characters (0 will use DefaultWidth).
	Width int
	// UseColors to use colors in the progress bar (default is true).
	UseColors bool
	// Which color to use for the bar (default is green) if UseColors is true.
	Color string
	// Spinner to also show a spinner in front of the progress bar.
	Spinner bool
	// Prefix to show before the progress bar (can be updated while running using UpdatePrefix() or through Extra()).
	Prefix string
	// Suffix to show after the percentage information on the bar (can be updated while running using UpdateSuffix()).
	Suffix string
	// If NoPercent is true, the percentage is not shown on the bar (if the default %.1f%% format is not adequate).
	NoPercent bool
	// Minimum duration between updates (0 to update every time).
	UpdateInterval time.Duration
	// Option to avoid all ANSI sequences (useful for non terminal output/test/go playground),
	// Implies UseColors=false. Not applicable to multi bars (which need ANSI cursor moves to update each bar).
	NoAnsi bool
	// Underlying specific destination writer for the screen/terminal.
	// (defaults when nil will use the shared screen writer based on os.Stderr).
	// Sets to os.Stdout or os.Stderr or any other Writer (that ends up outputting to ANSI aware terminal) to use
	// this with your existing code if the os.Stderr default global shared screen writer doesn't work for you.
	ScreenWriter io.Writer
	// Extra lines between each bar for multibars.
	ExtraLines int
}

Config is the common configuration for the progress bar and multi bars.

func DefaultConfig added in v0.5.0

func DefaultConfig() Config

DefaultConfig returns a default configuration for the progress bar with default values: DefaultWidth, color and spinner on, no extra nor prefix, a default update interval of 100ms.

func (Config) NewBar added in v0.10.0

func (cfg Config) NewBar() *Bar

NewBar creates a new progress bar from the config.

func (Config) NewMultiBar added in v0.10.0

func (cfg Config) NewMultiBar(mbars ...*Bar) *MultiBar

NewMultiBar sets up a multibar from already created progress bars (for instance AutoProgressReader/Writers). It will reserve space for the new bars and move the cursor up/down as needed as well as align the prefixes of each bar.

func (Config) NewMultiBarPrefixes added in v0.10.0

func (cfg Config) NewMultiBarPrefixes(prefixes ...string) *MultiBar

NewMultiBarPrefixes creates an array of progress bars with the same settings and a prefix for each and with cfg.ExtraLines in between each. ANSI must be supported by the terminal as this relies on moving the cursor up/down for each bar.

type MultiBar added in v0.9.0

type MultiBar struct {
	// Common config used to create the bars.
	Config
	// The progress bars that are part of this multi bar set.
	Bars []*Bar
}

func (*MultiBar) Add added in v0.10.0

func (mb *MultiBar) Add(mbars ...*Bar) *MultiBar

Add adds 1 or more progress bars to an existing multibar. Add should be called before the added bars are started/updated. It will reserve space for the new bars and move the cursor up/down as needed for a bar that was already created with NewMultiBar() or NewMultiBarPrefixes().

func (*MultiBar) End added in v0.10.0

func (mb *MultiBar) End()

End should be called at the end to move the cursor to the line after the last multi bar.

func (*MultiBar) PrefixesAlign added in v0.10.0

func (mb *MultiBar) PrefixesAlign()

PrefixesAlign iterates over the prefixes to left align them such as all the bars are also aligned. Adds 1 space to the longest prefix and updates the prefix of each bar and refreshes them. (Used in multi bar during initial setup as well as when Add()ing new bars whose prefix might be longer).

Directories

Path Synopsis
examples
auto command
Demonstrate using the AutoReader to show a progress bar while fetching a url.
Demonstrate using the AutoReader to show a progress bar while fetching a url.
multi command
simple command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL