← Blog

clogs: Shoes programs on plain CRuby

Shoes is the little GUI toolkit that _why the lucky stiff created for Ruby. Instead of widget classes and layout managers, you describe a window in a few lines of Ruby: stacks and flows for layout, para for text, button with a block for what happens on click. Hackety Hack, a programming starter kit with an editor and helpful coding tools, was built on top of it.

Hackety Hack stopped working when Shoes did. Shoes 4, a JRuby rewrite, never got far enough to run it. I wanted to see it run again, so in my fork at github.com/Largo/hacketyhack I took a different route and wrote a Shoes implementation that runs on the Ruby you already have. That implementation is clogs: Shoes, worn over libui.

Hello, Shoes

This is the example from the README:

require "clogs"

Shoes.app(title: "Hello", width: 400, height: 200) do
  para "Hello, ", strong("Shoes"), "!", size: :title
  button("Push me") { @note.replace "Aha! Clicked." }
  @note = para "Nothing pushed so far"
end

Save it as hello.rb, then:

gem install clogs
ruby hello.rb

The gem needs Ruby 3.2 or newer. It depends on lacci, on libui (libui-ng plus prebuilt shared libraries for Linux, macOS and Windows) and on chunky_png, because libui cannot load an image file by itself. No compiler, no browser engine, no JVM.

How it fits together

clogs does not reimplement the Shoes DSL. That part comes from Lacci, the display-independent half of Scarpe. Lacci owns the DSL, the tree of drawables and the events. clogs is a Lacci display service: it does the layout, painting, widgets and input, and libui-ng provides one native window and one canvas.

your Shoes program
        |
      Lacci          the Shoes DSL, drawable tree, events
        |
      Clogs          layout, painting, widgets, input
        |
      libui          one native window, one canvas

Because it plugs into Lacci, you can also select it explicitly. That is handy when the same program should also run under Scarpe’s webview backend:

SCARPE_DISPLAY_SERVICE=clogs ruby my_app.rb

One design decision is worth knowing about: clogs paints the entire Shoes document into a single libui canvas, widgets included. libui has no way to place a native control at an arbitrary position, and Shoes needs exactly that. The trade-off is that buttons and text fields look like Shoes widgets rather than native ones, and they do not get platform accessibility or input method support. Native libui controls are still used where they fit: menus, message boxes, file pickers and the ask/confirm dialogs.

What works

According to the README: layout, text, links, art drawables, images, widgets, events, animation and dialogs. Video, sound, blur and multiple windows do not. The feature-by-feature matrix in libui_shoes_coverage.md records what was tested, and on what: libui-ng from the libui gem 0.2.4 on Linux with Ruby 3.3.

The gem includes examples/kitchen_sink.rb, a tour of what clogs can draw. Here is a shortened piece of it:

require "clogs"

Shoes.app(title: "Clogs kitchen sink", width: 640, height: 620) do
  stack(width: 620, height: 170) do
    background rgb(255, 255, 255)
    border rgb(200, 200, 210), strokewidth: 2

    fill rgb(220, 60, 60)
    stroke rgb(60, 0, 0)
    rect 20, 20, 120, 60

    fill rgb(60, 120, 220)
    oval 170, 20, 100, 60

    nostroke
    fill rgb(250, 200, 40)
    star 320, 20, 6, 34, 16
  end
end

Two environment variables make Shoes apps scriptable. This is how clogs tests itself, and you can use it to take a screenshot of an app in CI:

CLOGS_EXIT_AFTER_MS=800 CLOGS_SCREENSHOT=shot.png ruby hello.rb

Since 0.1.0

The gem on RubyGems is version 0.1.0 from August 2026. Work has continued in the clogs/ folder of the repository since then:

And Hackety Hack?

The IDE runs again. In the repository, ruby hacketyhack.rb opens Hackety Hack on clogs: the splash animation, the side tabs and the Home tab all render. Eleven of the twelve original Shoes samples run unmodified. The Shoes 3 compatibility fixes that Hackety Hack needs live in the Hackety Hack tree (lib/compat/shoes3.rb), not in the gem.

It is still rough in places. The editor takes text now but is not finished, and the online features point at a server that no longer exists.

If you have an old Shoes program lying around, give it a try and tell me what breaks. The code is MIT licensed and lives at github.com/Largo/hacketyhack. And if the browser build caught your interest, I also wrote about jsg, a small helper for ruby.wasm projects.