Skip to content

raygui-jlt

CI Site

24 raygui examples written in jolt (native Clojure on Chez Scheme, no JVM), calling raygui directly over its C ABI through jolt.ffi. No wrapper library, no codegen: one shared bindings namespace and a suite of small example programs on top of it. raygui draws through raylib, so a small raylib bindings layer hosts the window and the frame loop underneath every example.

Quick start

brew install raylib   # macOS; see docs/guide/building-libraygui.md for other platforms
bb lib:build           # compile the vendored raygui header into lib/libraygui.dylib
bb basic-controls      # run the smallest example (opens a window)

Every example task builds the native library automatically if it is missing, so in practice bb basic-controls alone is enough on a fresh clone: it runs bb lib:build for you the first time.

Why there is a build step at all

Unlike raylib, raygui is header-only: there is no libraygui to install and no Homebrew formula for it. This repo vendors vendor/raygui.h and compiles it into lib/libraygui.dylib (lib/libraygui.so on Linux) so that jolt.ffi has a shared library to load.

The examples

The suite is 24 examples across 7 groups, every one with a committed screenshot. Click any preview for the full-size image, or browse them on the documentation site.

The gallery below is generated from the registry by bb readme:examples, so it cannot drift: bb readme:examples-check fails if it is stale or if any example is missing its screenshot. Run bb info for the grouped text version, or bb examples for a flat list.

basics (4)

button, label and a live click counter
bb basic-controls
button, label and a live click counter
the embedded 1-bit icon pack on buttons
bb icon-buttons
the embedded 1-bit icon pack on buttons
labels, separators and a status bar
bb labels-lines
labels, separators and a status bar
toggle, toggle group and toggle slider
bb toggles
toggle, toggle group and toggle slider

inputs (5)

an editable text box with edit mode
bb text-box
an editable text box with edit mode
a modal text prompt with secret toggle
bb text-input-box
a modal text prompt with secret toggle
spinner and value box, clamped and typed
bb spinner-value-box
spinner and value box, clamped and typed
slider, slider bar and their value cells
bb sliders
slider, slider bar and their value cells
a progress bar driven by a timer
bb progress-bar
a progress bar driven by a timer

collections (5)

a dropdown that owns its edit mode
bb dropdown-box
a dropdown that owns its edit mode
a combo box cycling through options
bb combo-box
a combo box cycling through options
a scrollable list with an active row
bb list-view
a scrollable list with an active row
a list view reporting focus and scroll
bb list-view-ex
a list view reporting focus and scroll
tabs with close requests
bb tab-bar
tabs with close requests

containers (4)

panels and group boxes as containers
bb panel-group-box
panels and group boxes as containers
a scroll panel over oversized content
bb scroll-panel
a scroll panel over oversized content
a window box you can close and reopen
bb window-box
a window box you can close and reopen
two draggable floating windows
bb floating-window
two draggable floating windows

dialogs (2)

a modal message box with two buttons
bb message-box
a modal message box with two buttons
a hand-built input dialog over a panel
bb custom-input-box
a hand-built input dialog over a panel

color (2)

an RGB picker with an alpha bar
bb color-picker
an RGB picker with an alpha bar
the HSV picker and panel
bb color-picker-hsv
the HSV picker and panel

styling (2)

cycle six vendored .rgs style themes
bb style-selector
cycle six vendored .rgs style themes
forced states, alpha and lock
bb gui-state
forced states, alpha and lock

How it works

raygui's API is 61 functions, and nearly all of them share one shape: a bounding Rectangle passed by value, application state passed through a pointer, and an int result telling the caller what happened. That one recurring signature is what makes a small, direct FFI binding practical here, with no callback machinery and no retained widget tree to model. See docs/guide/the-ffi-shape.md for the full account, including the scratch-buffer trick that keeps every control from allocating inside a frame.

Verifying without a display

Every example honors two environment variables so it can prove itself with nobody watching:

RAYGUI_APP_AUTO_QUIT_MS=1500 jolt -M:basic-controls   # close the window after 1.5s
RAYGUI_APP_SHOT=proof.png    jolt -M:basic-controls   # dump one frame as a PNG

The shot path must be relative: raylib prepends the working directory to it, so an absolute path writes nothing. The helper verifies the file appeared and prints SHOT FAILED rather than reporting a success it did not have.

The PNG is the gate. For a GUI toolkit, a headless compile check proves the code loads, not that it renders correctly; several traps documented in the guide render a plausible, wrong result rather than throwing. Looking at the screenshot is what actually catches them.

The AOT gate

bb check and every example run under jolt run, which cannot see a bug that exists only in a built binary. jolt#757 was one of those: jolt.ffi's own defns were interned but unbound in a jolt build image while jolt run compiled them from source and worked. It is fixed now (jolt#756), and this repo sits directly on the surface it broke, because raygui.clj calls ffi/layout-size inside two top-level defs and rect-> writes all four Rectangle fields with ffi/write-field, which is the path every Gui* control takes.

bb aot        # build basic-controls as a native binary, run it for 800ms

It builds a real example rather than the headless check entry point on purpose. check only requires namespaces, so it would never call an accessor, and it would pass while the binary was broken.

Two things it deliberately does not do. It runs from the repo root rather than a temp directory, because deps.edn declares raygui at the repo-relative lib/libraygui.dylib, which means a built binary is not relocatable: run it anywhere else and it exits 255 with required native library not found. It is also not part of bb check or CI, since it opens a real window and both of those are headless.

Documentation

License and attribution

Released under the Eclipse Public License 2.0, matching the rest of jlt-commons and jolt itself. SPDX identifier: EPL-2.0. It was zlib until 2026-09-05, chosen to match raygui and raylib. Third-party attribution, including the vendored raygui header and the ported examples, lives in NOTICE; vendor/raygui.h and the ported examples keep raygui's zlib terms, which EPL 2.0 does not and cannot change.

About

24 raygui examples in Jolt: raylib's immediate-mode GUI library called from native Clojure over its C ABI through jolt.ffi

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages