NEW Read the Introduction → A Glamorous Christmas
 ██████╗██╗  ██╗ █████╗ ██████╗ ███╗   ███╗
██╔════╝██║  ██║██╔══██╗██╔══██╗████╗ ████║
██║     ███████║███████║██████╔╝██╔████╔██║
██║     ██╔══██║██╔══██║██╔══██╗██║╚██╔╝██║
╚██████╗██║  ██║██║  ██║██║  ██║██║ ╚═╝ ██║
       ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝  RUBY

Ruby ports of the beloved Charm terminal libraries.

Build glamorous TUIs, style terminal output, create beautiful forms,
and make your Ruby CLIs sparkle.

gem install bubbletea lipgloss bubbles glamour

The Library Collection

Build Terminal Apps

🫧

Bubbletea

Build terminal UIs from the future, today.

A powerful TUI framework using the Elm Architecture. Handle keyboard, mouse, and window events with commands for side effects.

gem "bubbletea"
🧩

Bubbles

The Bubble Tea component toolkit.

Pre-built components: Spinner, Progress, Timer, TextInput, TextArea, Viewport, List, Table, FilePicker, and more.

gem "bubbles"
🔲

Bubblezone

Track clickable regions in terminal UIs.

Mark zones with IDs, check mouse coordinates, and handle click events in your Bubble Tea applications.

gem "bubblezone"

Style Your Output

💄

Lipgloss

Your terminal style and layout toolkit.

Borders, padding, margins, colors (hex, ANSI, adaptive), tables, lists, trees, and layout utilities.

gem "lipgloss"

Glamour

The stylesheet-driven markdown renderer.

Render markdown in your terminal with built-in themes (dark, light, dracula), custom styles via DSL, and emoji support.

gem "glamour"
📊

NTCharts

Terminal charts for beautiful data viz.

Sparkline, Barchart, LineChart, WaveLineChart, StreamLineChart (real-time), and TimeSeriesLineChart.

gem "ntcharts"

Interactive Tools

🤔

Huh?

Simple, powerful forms in the terminal.

Input, Text, Select, MultiSelect, Confirm, Note, Spinner. Built-in validation, themes, and a block-based DSL.

gem "huh", github: "marcoroth/huh-ruby"
🍬

Gum

A tool for glamorous shell scripts.

Ruby wrapper with idiomatic API: input, write, choose, filter, confirm, file, pager, spin, style, format. Bundles the gum binary.

gem "gum"
🎵

Harmonica

A physics-based animation library.

Damped harmonic oscillator (Spring), projectile motion, Point & Vector math, and frame rate helpers for smooth UI animations.

gem "harmonica"

Getting Started

## Installation

Add the gems you need to your Gemfile:

# Gemfile

# Core TUI framework
gem "bubbletea"

# Styling
gem "lipgloss"

# Components
gem "bubbles"

# Markdown rendering
gem "glamour"

# Shell scripts
gem "gum"

# Animations
gem "harmonica"

# Charts
gem "ntcharts"

# Mouse tracking
gem "bubblezone"

## Your First TUI

A simple Bubbletea app with Lipgloss styling:

require "bubbletea"
require "lipgloss"

class HelloWorld
  include Bubbletea::Model

  def initialize
    @style = Lipgloss::Style.new
      .border(:rounded)
      .border_foreground("#7D56F4")
      .padding(1, 2)
  end

  def init = [self, nil]

  def update(message)
    case message
    when Bubbletea::KeyMessage
      return [self, Bubbletea.quit] if message.to_s == "q"
    end

    [self, nil]
  end

  def view
    @style.render("Hello, Charm Ruby!\n\nPress q to quit")
  end
end

Bubbletea.run(HelloWorld.new)

Examples

Counter with Styling

require "bubbletea"
require "lipgloss"

class Counter
  include Bubbletea::Model

  def initialize
    @count = 0
    @style = Lipgloss::Style.new
      .bold(true)
      .foreground("#FF6B6B")
  end

  def update(message)
    case message
    when Bubbletea::KeyMessage
      case message.to_s
      when "q", "ctrl+c"
        return [self, Bubbletea.quit]
      when "up" then @count += 1
      when "down" then @count -= 1
      end
    end

    [self, nil]
  end

  def view
    @style.render("Count: #{@count}\n\nPress q to quit")
  end
end

Bubbletea.run(Counter.new)

Spinner Component

require "bubbletea"
require "bubbles"

class LoadingApp
  include Bubbletea::Model

  def initialize
    @spinner = Bubbles::Spinner.new
  end

  def init
    [self, @spinner.tick]
  end

  def update(message)
    case message
    when Bubbletea::KeyMessage
      case message.to_s
      when "q", "ctrl+c"
        return [self, Bubbletea.quit]
      end
    end

    @spinner, command = @spinner.update(message)

    [self, command]
  end

  def view
    "#{@spinner.view} Loading..."
  end
end

Bubbletea.run(LoadingApp.new)

Terminal Form

require "huh"

form = Huh.form(
  Huh.group(
    Huh.input
      .key("name")
      .title("What's your name?")
      .placeholder("Enter name..."),

    Huh.select
      .key("color")
      .title("Favorite color?")
      .options(*Huh.options(
        "Red", "Green", "Blue"
      ))
  )
).with_theme(Huh::Themes.charm)

form.run

puts "Hello, #{form["name"]}!"

Styled Table

require "lipgloss"

headers = ["Name", "Language", "Stars"]

rows = [
  ["bubbletea", "Ruby", "✨"],
  ["lipgloss", "Ruby", "💄"],
  ["glamour", "Ruby", "✨"]
]

table = Lipgloss::Table.new
  .headers(headers)
  .rows(rows)
  .border(:rounded)

puts table.render

Markdown Rendering

require "glamour"

markdown = <<~MD
  # Hello Glamour :sparkles:

  This is **bold** and *italic*.

  - Item one
  - Item two
  - Item three

  ```ruby
  puts "Hello, World!"
  ```
MD

puts Glamour.render(markdown,
  style: "dark",
  width: 80,
  emoji: true
)

Real-time Charts

require "ntcharts"

chart = Ntcharts::Streamlinechart.new(60, 12)

loop do
  chart.push(Math.sin(Time.now.to_f) * 4 + 5)

  print "\e[H\e[2J"
  puts chart.render
  sleep 0.1
end

The Ecosystem

These Ruby gems are ports and bindings of the original Go libraries from Charm. They bring the same elegant APIs and glamorous terminal experiences to Ruby developers.

Some gems use native C extensions that link to compiled Go shared libraries, while others are pure Ruby implementations.

Ruby 3.2+ MIT License