Roxane

A pure-Ruby desktop shell: a native window over the operating system's webview (WebView2 / WKWebView / WebKitGTK, via the webview C library), with a Ruby⇄JS operation bridge. A lightweight, Tauri-shaped way to ship a web frontend as a desktop app — in Ruby.

Named for Cyrano's Roxane.

What it is (and isn't)

Roxane is the host and data plane — a window, the system webview, an invoke/emit bridge, and a loopback asset server. It serves whatever frontend you give it and is agnostic to look-and-feel (no CSS, no widgets, no layout opinions). The same frontend can run in the desktop shell and in a hosted browser.

Example

require "roxane"

win = Roxane::Window.new(title: "Hello", size: [900, 600])

# JS → Ruby:  await window.roxane.invoke("greet", "world")
win.on("greet") { |name| "Hello, #{name}!" }

# Ruby → JS:  window.roxane.on("tick", ({ at }) => ...)
win.emit("tick", { at: Time.now.to_i })

win.serve(File.expand_path("ui"))   # serve a built frontend bundle, or:
# win.load("http://localhost:5173") # point at a dev server, or:
# win.html("<!doctype html>…")      # inline HTML

win.run

Invocation handlers run off the UI thread, and emit/eval are safe from any thread — so long-running work (e.g. an AI call) never freezes the window.

Requirements

The webview C library (libwebview) must be available at runtime. The precompiled platform gem (e.g. x86_64-linux) vendors it, so you only need the system webview runtime (WebKitGTK on Linux). Otherwise set ROXANE_LIBWEBVIEW to a libwebview path, or have it on the loader path.

Packaging (precompiled platform gems)

Roxane ships a prebuilt libwebview per platform (the nokogiri model) so users need no toolchain. For x86_64-linux:

rake vendor:linux   # build libwebview into vendor/x86_64-linux/
rake gem:linux      # build roxane-<ver>-x86_64-linux.gem (vendoring the lib)
rake verify:linux   # install that gem in a clean container and smoke-test it

macOS / Windows / aarch64 cross-builds are next.

Testing

./run.sh        # Docker: Ruby + libwebview + headless Xvfb → full suite
rake test       # host: unit tests only (the asset server); the windowed
                # smoke test self-skips unless ROXANE_INTEGRATION=1

Linux / Wayland note (window size)

On GTK3, upstream libwebview implements WEBVIEW_HINT_NONE with gtk_window_resize. Under Wayland that does not set the initial xdg geometry, so floating compositors (e.g. Hyprland) often map the window at a tiny 200×200 square; GNOME hides the same bug. Roxane compensates on Linux by calling gtk_window_set_default_size and briefly pinning a size-request through first map (then releasing it so the window stays resizable).

Status

Early but working. The runtime (window + system webview + invoke/emit bridge + loopback asset server) is green headlessly, and precompiled x86_64-linux packaging worksrake verify:linux builds the platform gem and proves it installs and runs on a clean machine (system WebKitGTK only, no toolchain). Next: macOS / Windows / aarch64 cross-builds + RubyGems publish, then richer window options (menus, frameless).

License

MIT