Ruby UI toolkit with native GPU windows, headless rendering, and a terminal backend
Features · Installation · Quick Start · Platforms · Documentation
Zaniah is a pure Ruby UI toolkit for building desktop and terminal interfaces. It renders through native GPU APIs, a deterministic headless backend, or an ANSI terminal without extension compilation or a rendering subprocess.
Zaniah is named for a star in Virgo. The toolkit is the drawing surface beneath the editor, providing the native rendering layer for its UI.
Features
- Flex, Grid, sticky, absolute, wrapping, and baseline-aware layouts
- Gradients, transforms, paths, SVG, shadows, clipping, and GPU glyph atlases
- Retained element state, subscriptions, and non-blocking background tasks
- Validated declarative element trees with event IDs, minimal diffs, and keyed reuse
- Scroll views, inertial input, and uniform or variable-height virtual lists
- Stable-ID pointer and keyboard reordering without materializing virtual collections
- Stable-ID split-pane grids with fixed, fractional, and minmax tracks
- Two-axis virtual data grids with frozen panes, range selection, and editable rich text with IME
- OpenType shaping, font fallback, Japanese wrapping, text overlays, low-resolution text caching, selection, editing, and IME
- PNG, GIF, and baseline JPEG image decoding with Exif orientation
- Themes, state styles, keyed animation, springs, and reduced-motion support
- Opt-in controls, overlays, tables, externally completable lazy virtual trees, charts, forms, and terminal fallbacks
- Spatial keyboard focus and a stable-ID, event-diffed cross-platform accessibility tree
- F12 inspector, frame statistics, hot reload, and headless golden-image tests
- Native input, IME, clipboard, file-drop, display, and filesystem events
- RBS declarations for the public API
Installation
Add Zaniah to your Gemfile:
gem "zaniah"Then install:
bundle installRequirements
- CRuby 3.1 or later
- YJIT recommended
Quick Start
Create hello.rb:
require "zaniah"
window = Zaniah::Platform.open_window(
backend: :headless,
width: 480,
height: 240
)
window.text_system = Zaniah::TextSystem::Renderer.new
window.draw do
Zaniah::Div.new.flex_col.p(24).gap(12).bg("#161b22")
.child(Zaniah::Text.new("Hello, Ruby", size: 24))
.child(Zaniah::Text.new("A native toolkit, written in Ruby."))
end
window.tick
window.write_png("hello.png")
window.closeRun it to write hello.png:
bundle exec ruby hello.rbFor an interactive window, choose backend: :mac, :linux, :windows, or
:tui, then call window.run instead of window.tick.
Platforms
| Backend | Renderer | Notes |
|---|---|---|
:mac |
Metal or OpenGL | Native macOS window |
:linux |
Wayland/EGL or X11/GLX | Selected from the current display environment |
:windows |
Win32/WGL | Requires 64-bit Ruby and Windows 10 APIs |
:headless |
Pure Ruby software renderer | Deterministic rendering and PNG output |
:tui |
ANSI terminal | Text-grid rendering and terminal input |
Native backends use the operating system libraries through Ruby's Fiddle. See Native backends for platform requirements.
Native macOS, Windows, and X11 windows can be moved to a display returned by
Zaniah::Platform.displays with window.move_to_display(display). Headless and
terminal windows cannot be placed on physical displays. Wayland does not permit
arbitrary client window placement; its fullscreen_on(display) asks the
compositor to fullscreen on that output, but the compositor may choose otherwise.
Documentation
- Getting started — installation and your first render
- Guides — platforms, layout, text, themes, accessibility, and advanced APIs
- Components — rendered examples, code, and API summaries
- Component API reference — all constructors and variants in one table
- Contributing guidelines — development and platform checks
- Architecture decisions — implementation rationale
- RBS declarations — public API signatures
Contributing
Bug reports and pull requests are welcome. See the contributing guidelines for checks and documentation updates.
License
Zaniah is released under the MIT License. Included font notices remain alongside the font files.

