Webvas
Write Ruby graphics sketches and run them in a browser.
Playground · Ruby API · CLI · Security
Webvas connects RBGL's software renderer to an OffscreenCanvas and advances one frame at a time with requestAnimationFrame. The playground includes RBGL, Gesso, and RLSL examples, shareable source links, and single-file HTML downloads.
Features
- RBGL canvas backend with pointer, keyboard, and wheel input
- Gesso sketch runner and RLSL WGSL compute shaders
- Fresh Ruby worker for each playground run, with visible errors and frame measurements
- Deflate-compressed source in URL fragments; source is not sent to a Webvas service
-
webvas new,serve, andbuildfor standalone sketch projects - Browser runtime built with Webvas, RBGL, Tessel, Gesso, Glyphic, and RLSL
Quick start
Add the loader and a Ruby source file to an HTML page:
<canvas id="screen" width="320" height="240"></canvas>
<script type="text/ruby" data-webvas data-canvas="#screen" src="app.rb"></script>
<script src="https://rbgfx.github.io/webvas/loader.js"
data-runtime="https://rbgfx.github.io/webvas/assets/webvas.wasm"></script>In app.rb:
require "gesso"
Gesso.run(width: 320, height: 240, runner: :web) do
draw do
background "#101827"
no_stroke
fill "#f07850"
circle width / 2, height / 2, 36
end
endThe official runtime is built with these gems already included. A runtime URL can be set with data-runtime; use the same URL for sketches that bundle their own dependencies.
Ruby API
Create an RBGL::GUI::Window with Webvas::Backend.new, then call Webvas.run(window) with a frame block. The block receives the RBGL context and delta time. Webvas.run reuses one animation callback, closes the window on stop or error, and reports exceptions through the bridge.
Webvas::Backend accepts width, height, canvas, title, and pixelated. Canvas drawing dimensions set render resolution; CSS scales its display. Pointer coordinates are mapped from CSS pixels to render pixels. Focus the canvas to send keyboard input.
RLSL can generate the WGSL source for WebGPU:
require "rlsl"
require "webvas"
wgsl = RLSL.to_wgsl(:plasma) do
uniforms { float :time }
fragment do |frag_coord, resolution, uniforms|
uv = frag_coord / resolution.y
vec3(sin(uv.x + uniforms.time), uv.y, 0.6)
end
end
Webvas.run_shader(Webvas::Shader.new(wgsl))WebGPU requires a supported browser, secure context, and GPU adapter. The shader runner updates the resolution and time uniforms automatically.
CLI
gem install webvas
webvas new my-sketch
cd my-sketch
webvas serve
webvas build -o distserve binds to 127.0.0.1:8000, serves .wasm as application/wasm, and reloads when project files change. Use --host, --port, or --root to change its defaults. build writes a static site that loads the official runtime. To bundle a custom runtime, add ruby_wasm and js to the project's Gemfile, install it, then run webvas build --runtime custom; the project's bundle is passed to rbwasm build.
Playground
Open the Webvas playground. Choose a mode and example, edit the Ruby, then press Run or Ctrl/Cmd + Enter. Each run starts a fresh worker and canvas. Share compresses the source with CompressionStream into the URL fragment; Download HTML embeds the source as escaped JSON and keeps the runtime on its CDN URL.
Security and limitations
- Ruby runs in a worker, but the worker is not a security sandbox. Sketches can call browser APIs and make network requests allowed by the page's Content Security Policy. Inspect shared code before running it.
- Webvas does not set cookies, store source, or send code to a Webvas service. The GitHub Pages project URL shares the
rbgfx.github.ioorigin; a dedicated hostname requires a separate hosting or domain decision. - Runtime downloads omit browser credentials. Pages need to allow the chosen loader, worker, and runtime in their Content Security Policy.
- The
jsgem evaluates Ruby-to-JavaScript bridge code, so the playground policy requiresunsafe-evalandwasm-unsafe-eval. This weakens script restrictions; use a dedicated origin for untrusted sketches. - The 0.3.0 candidate was verified locally in Chromium 153 on macOS arm64. Firefox, Safari, and mobile browsers are not verified; the software renderer needs
OffscreenCanvasand module workers, and RLSL also needs WebGPU. - Blocking loops and
sleepstop browser frame progress. WebAssembly threads and compiling native extensions in the browser are unsupported. - Ruby source is limited to 32 KiB. RGBA frames use base64 transfer; a 320×240 frame is 307,200 bytes before encoding.
- RLSL mode requires WebGPU; RBGL and Gesso modes use the software renderer.
See browser security notes and runtime/performance records.
Development
The repository expects adjacent checkouts of Larb, RBGL, Tessel, Gesso, Glyphic, and RLSL. Ruby unit tests run under CRuby; the browser integration tests use Chromium and the locally built runtime.
bundle install
BUNDLE_GEMFILE=runtime/Gemfile bundle install
BUNDLE_GEMFILE=runtime/Gemfile bundle exec rbwasm build \
--ruby-version 4.0 --target wasm32-unknown-wasip1 \
--build-profile full --patch "$(pwd)/patches/psych-wasi.patch" -o build/webvas.wasm
ruby script/build_site
bundle exec rake verify
npm ci
npx playwright install chromium
npm run test:browserLicense
MIT. See LICENSE.txt.