CLI UI is a small framework for generating nice command-line user interfaces
gem install cli-uior add the following to your Gemfile:
gem'cli-ui'In your code, simply add a require 'cli/ui'. Most options assume CLI::UI::StdoutRouter.enable has been called.
This may not be an exhaustive list. Please check our documentation for more information.
To handle content flow (see example below)
CLI::UI::StdoutRouter.enableCLI::UI::Frame.open('Frame 1')doCLI::UI::Frame.open('Frame 2'){puts"inside frame 2"}puts"inside frame 1"endPrompt user with options and ask them to choose. Can answer using arrow keys, vim bindings (j/k), or numbers (or y/n for yes/no questions).
For large numbers of options, using e, :, or G will toggle "line select" mode which allows numbers greater than 9 to be typed and
f or / will allow the user to filter options using a free-form text input.
CLI::UI.ask('What language/framework do you use?',options: %w(railsgorubypython))To set the color of instruction text:
CLI::UI::Prompt.instructions_color=CLI::UI::Color::GRAYCan also assign callbacks to each option
CLI::UI::Prompt.ask('What language/framework do you use?')do |handler|
handler.option('rails'){ |selection| selection}handler.option('go'){ |selection| selection}handler.option('ruby'){ |selection| selection}handler.option('python'){ |selection| selection}end- Note that the two examples provided above are identical in functionality
CLI::UI.ask('Is CLI UI Awesome?',default: 'It is great!')Handle many multi-threaded processes while suppressing output unless there is an issue. Can update title to show state.
CLI::UI::SpinGroup.newdo |spin_group|
spin_group.add('Title'){ |spinner| sleep3.0}spin_group.add('Title 2'){ |spinner| sleep3.0;spinner.update_title('New Title');sleep3.0}ende.g. {{red:Red}} {{green:Green}}
putsCLI::UI.fmt"{{red:Red}} {{green:Green}}"e.g. {{*}} => a yellow ⭑
putsCLI::UI.fmt"{{*}} {{v}} {{?}} {{x}}"CLI::UI::Spinner.spin("building packages: {{@widget/status:1:2:3:4}}")do |spinner|
# spinner.update_title(...)sleep(3)endShow progress of a process or operation.
CLI::UI::Progress.progressdo |bar|
100.timesdobar.tickendendModify the appearance of CLI::UI both globally and on an individual frame level.
To set the default style:
CLI::UI.frame_style=:boxTo style an individual frame:
CLI::UI.frame('New Style!',frame_style: :bracket){puts"It's pretty cool!"}The default style - :box - is what has been used up until now. The other style - :bracket - looks like this:
CLI::UI.frame_style=:bracketCLI::UI::StdoutRouter.enableCLI::UI::Frame.open('Frame 1')doCLI::UI::Frame.open('Frame 2'){puts"inside frame 2"}puts"inside frame 1"endWe make use of Sorbet in cli-ui. We provide stubs for Sorbet so that you can use this gem even
if you aren't using Sorbet. We activate these stubs if T is undefined when the gem is loaded. For this reason, if you
would like to use this gem and your project does use Sorbet, ensure you load Sorbet before loading cli-ui.
The following code makes use of nested-framing, multi-threaded spinners, formatted text, and more.
require'cli/ui'CLI::UI::StdoutRouter.enableCLI::UI::Frame.open('{{*}} {{bold:a}}',color: :green)doCLI::UI::Frame.open('{{i}} b',color: :magenta)doCLI::UI::Frame.open('{{?}} c',color: :cyan)doCLI::UI::SpinGroup.newdo |sg|
sg.add('wow')do |spinner|
sleep(2.5)spinner.update_title('second round!')sleep(1.0)endsg.add('such spin'){sleep(1.6)}sg.add('many glyph'){sleep(2.0)}endendendCLI::UI::Frame.divider('{{v}} lol')putsCLI::UI.fmt'{{info:words}} {{red:oh no!}} {{green:success!}}'CLI::UI::SpinGroup.newdo |sg|
sg.add('more spins'){sleep(0.5);raise'oh no'}endendOutput:
- Run tests using
bundle exec rake test. All code should be tested. - No code, outside of development and tests needs, should use dependencies. This is a self contained library
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/cli-ui.
The code is available as open source under the terms of the MIT License.









