Skip to content
/ pin Public

pin is a lightweight, customizable terminal spinner library for Go applications

License

Notifications You must be signed in to change notification settings

yarlson/pin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

pin

Go Reference codecov

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.

Demo

Features

  • 🎨 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

Installation

go get github.com/yarlson/pin

Quick Start

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!")

Custom Output Writer

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!")

Non-interactive Behavior

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().

Examples

Basic Progress Indicator

p := pin.New("Processing data")
cancel := p.Start(context.Background())
defer cancel()
// ... do work ...
p.UpdateMessage("Almost there...")
// finish work
p.Stop("Completed!")

Styled Output

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")

Right-side Spinner

p := pin.New("Downloading", pin.WithPosition(pin.PositionRight))
cancel := p.Start(context.Background())
defer cancel()
// ... do work ...
p.Stop("Downloaded")

Custom Styling & Message Updating

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")

Failure Indicator

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")

API Reference

Creating a New Spinner

p := pin.New("message", /* options... */)

Available 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.

Available Colors

  • ColorDefault
  • ColorBlack
  • ColorRed
  • ColorGreen
  • ColorYellow
  • ColorBlue
  • ColorMagenta
  • ColorCyan
  • ColorGray
  • ColorWhite

Development & Compatibility

This library is written using only the Go standard library and supports Go version 1.11 and later.

Running Tests

go test -v ./...

Prompt

The LLM prompt example in example/prompt.md shows you how to quickly integrate pin into your codebase.

Contributing

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

License

MIT License – see LICENSE for details

Acknowledgments

Inspired by elegant CLI spinners and the need for a simple, flexible progress indicator in Go applications.

About

pin is a lightweight, customizable terminal spinner library for Go applications

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages