pin
is a lightweight, customizable terminal spinner library for Go applications. It provides an elegant way to show progress and status in CLI applications with support for colors, custom symbols, and flexible positioning.
- π¨ Customizable colors for all spinner elements via functional options
- π Smooth braille-pattern animation
- π― Flexible positioning (spinner before/after message)
- π« Configurable prefix and separator
- π€ UTF-8 symbol support
- β¨ Ability to update the spinner message dynamically
- πΌοΈ Customizable spinner frames for unique animation effects
- βοΈ No external dependencies β uses only the Go standard library
- π Compatible with Go 1.11 and later
- βΉ Automatically disables animations in non-interactive (piped) environments to prevent output corruption
go get github.com/yarlson/pin
p := pin.New("Loading...",
pin.WithSpinnerColor(pin.ColorCyan),
pin.WithTextColor(pin.ColorYellow),
)
cancel := p.Start(context.Background())
defer cancel()
// do some work
p.Stop("Done!")
You can direct spinner output to an alternative writer (for example, os.Stderr
) using the WithWriter
option:
p := pin.New("Processing...",
pin.WithSpinnerColor(pin.ColorCyan),
pin.WithTextColor(pin.ColorYellow),
pin.WithWriter(os.Stderr), // output will be written to stderr
)
cancel := p.Start(context.Background())
defer cancel()
// perform your work
p.Stop("Done!")
When the spinner detects that stdout
is not connected to an interactive terminal (for example, when output is piped), it disables animations and outputs messages as plain text. In this mode:
- The initial message is printed immediately when the spinner starts.
- Any updated messages are printed as soon as you call
UpdateMessage()
. - The final done message is printed when you call
Stop()
.
p := pin.New("Processing data")
cancel := p.Start(context.Background())
defer cancel()
// ... do work ...
p.UpdateMessage("Almost there...")
// finish work
p.Stop("Completed!")
p := pin.New("Uploading",
pin.WithPrefix("Transfer"),
pin.WithSeparator("β"),
pin.WithSpinnerColor(pin.ColorBlue),
pin.WithTextColor(pin.ColorCyan),
pin.WithPrefixColor(pin.ColorYellow),
)
p.Start()
// ... do work ...
p.Stop("Upload complete")
p := pin.New("Downloading", pin.WithPosition(pin.PositionRight))
cancel := p.Start(context.Background())
defer cancel()
// ... do work ...
p.Stop("Downloaded")
p := pin.New("Processing",
pin.WithPrefix("Task"),
pin.WithSeparator(":"),
pin.WithSeparatorColor(pin.ColorWhite),
pin.WithDoneSymbol('β'),
pin.WithDoneSymbolColor(pin.ColorGreen),
)
cancel := p.Start(context.Background())
defer cancel()
// ... do work ...
p.UpdateMessage("Almost done...")
// finish work
p.Stop("Success")
You can express a failure state with the spinner using the new Fail()
method. Customize the failure appearance with WithFailSymbol
, WithFailSymbolColor
, and (optionally) WithFailColor
.
p := pin.New("Deploying",
pin.WithFailSymbol('β'),
pin.WithFailSymbolColor(pin.ColorRed),
)
cancel := p.Start(context.Background())
defer cancel()
// ... perform tasks ...
p.Fail("Deployment failed")
p := pin.New("message", /* options... */)
WithSpinnerColor(color Color)
β sets the spinner's animation color.WithTextColor(color Color)
β sets the color of the message text.WithPrefix(prefix string)
β sets text to display before the spinner.WithPrefixColor(color Color)
β sets the color of the prefix text.WithSeparator(separator string)
β sets the separator text between prefix and message.WithSeparatorColor(color Color)
β sets the color of the separator.WithDoneSymbol(symbol rune)
β sets the symbol displayed upon completion.WithDoneSymbolColor(color Color)
β sets the color of the done symbol.WithFailSymbol(symbol rune)
β sets the symbol displayed upon failure.WithFailSymbolColor(color Color)
β sets the color of the failure symbol.WithFailColor(color Color)
β sets the color of the failure message text.WithPosition(pos Position)
β sets the spinner's position relative to the message.WithSpinnerFrames(frames []rune)
β sets the spinner's frames.WithWriter(w io.Writer)
β sets a custom writer for spinner output.
ColorDefault
ColorBlack
ColorRed
ColorGreen
ColorYellow
ColorBlue
ColorMagenta
ColorCyan
ColorGray
ColorWhite
This library is written using only the Go standard library and supports Go version 1.11 and later.
go test -v ./...
The LLM prompt example in example/prompt.md shows you how to quickly integrate pin into your codebase.
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
MIT License β see LICENSE for details
Inspired by elegant CLI spinners and the need for a simple, flexible progress indicator in Go applications.