I’ve been playing around with progress bars in the terminal, and I think I’ve
created something genuinely useful.
Yes, I know there are multiple options
already available for this, this is mostly just an experiment for me. I wanted to build a Ruby library that
could be used for command-line scripting, with CLI executables that made it easy
to use when scripting in any language — not just Ruby, with a few
options I didn’t see elsewhere.
The result is ruby-progress, a gem that provides four different animated
progress indicators, each with its own visual style and use cases.
If you’re scripting in Ruby, I do highly recommend the TTY tools from
Piotr Murach, such as
tty-progress. Piotr’s
TTY tools have Ruby APIs. ruby-progress is designed more for use in
other shell scripts than it is for detailed Ruby scripting.
This tool owes a lot to Piotr’s work.
The Four Progress Indicators
Ripple
Creates a wave-like effect across text, with the characters rippling
through different visual states. It supports rainbow colors, inverse
highlighting, and case transformations. Perfect for text-heavy operations where
you want something more dynamic than a simple spinner.
Worm
Displays a moving dot pattern that crawls across the screen using
Unicode characters. It includes multiple styles (circles, blocks, geometric
shapes) and can move in any direction. Great for file operations, network
transfers, or any continuous background task.
Twirl
Provides classic spinning indicators with over 35 different spinner
styles — from simple dots to complex geometric patterns. It’s the most
traditional of the four, but with way more visual variety than typical spinners.
Fill
The only determinate indicator in the bunch — an actual progress bar
that shows completion percentage. It can be controlled via command execution or
updated programmatically through daemon control messages.
Installation and Quick Start
Installation is straightforward:
gem install ruby-progress
All four indicators are available through a unified prg command:
# Basic usage
prg ripple "Processing files..."
prg worm --message"Loading..."--style blocks
prg twirl --message"Working..."--style dots --speed fast
prg fill --total 100 --report# With command execution
prg ripple "Building..."--command"make build"--success"Build complete!"--checkmark
You can also use the individual commands directly: ripple, worm, twirl, and fill.
The Killer Feature: Daemon Mode
Here’s where things get interesting. All four indicators support daemon mode,
which lets you run a progress indicator in the background while your scripts
execute other commands. This is useful for complex workflows.
# Start a background spinner
prg worm --daemon-as deployment --message"Deploying application..."# Execute your actual deployment steps
git push production main
kubectl apply -f manifests/
./run-migrations.sh
# Stop the spinner with a success message
prg job stop --daemon-name deployment --message"Deployment complete!"--checkmark
The daemon mode uses Process.fork and Process.detach, so there are no shell
job notifications cluttering your output. The progress indicator runs cleanly in
the background, providing visual feedback without interfering with your script’s
execution.
Keeping Output Clean
One of the challenges with daemon mode is preventing command output from
disrupting the animation. By default, when you run a progress indicator in
daemon mode, any STDOUT or STDERR output from commands executed in your script
will appear on the terminal and potentially mess up the animation display.
Ruby-progress handles this intelligently. When running in daemon mode, the
animation continues on its dedicated line while your commands execute. However,
if you want to see the output from those commands, you have options:
# Run command with animation, show output after completion
prg ripple "Building..."--command"make build"--stdout# Stream output live while animation runs (reserves terminal rows)
prg worm "Installing..."--command"npm install"--stdout-live--output-lines 5
# Run daemon and manually capture output from your script commands
prg worm --daemon-as build --message"Building..."
make build > /tmp/build.log 2>&1
prg job stop --daemon-name build --message"Build complete!"--checkmarkcat /tmp/build.log
The --stdout-live flag is particularly useful — it reserves a section of the
terminal to display live command output while the animation continues above or
below it. You control how many lines to reserve with --output-lines and where
they appear with --output-position (above or below the animation).
Job Control Commands
The prg job command provides subcommands for controlling background indicators:
prg job stop — Stop a running daemon with an optional message
prg job status — Check if a daemon is running and show its PID
prg job advance — Update a fill progress bar by a specific amount
# Check if a daemon is running
prg job status --daemon-name mytask
# Advance a progress bar remotely
prg fill --daemon-as progress --total 100
prg job advance --daemon-name progress --amount 10
# Stop with error state
prg job stop --daemon-name mytask --message"Build failed!"--error
Or check out the GitHub repository
for full documentation, examples, and the complete API reference. The README
includes detailed guides for each indicator type and advanced usage patterns.
The gem is also available on
RubyGems, and the latest release
includes significant improvements to daemon mode handling and job control
commands.