The 100% Pure Ruby Frontend Web Framework in WebAssembly.
Build interactive Single-Page Applications (SPAs) entirely in Ruby running inside the browser via ruby.wasm — Zero JavaScript, Zero React, Zero Node, and Zero NPM dependencies.
- ⚡ 100% Pure Ruby Frontend: Write interactive web components, event listeners, and state management in native Ruby.
- 🔄 Reactive State Management: Define
state :count, default: 0. Updating state (self.count += 1) automatically re-renders component views. - 🌳 Virtual DOM Diffing: In-memory
VNodetree generation and diffing engine for optimal browser DOM rendering. - 🗺️ Client-Side SPA Routing: Single-page application route matching (
Router) for multi-view Ruby web apps. - 🛠️ Dev Server & CLI Tooling:
web_ruby_ui devlaunches a local WebAssembly dev server with instant browser hot-loading.
┌─────────────────────────────────────────────────────────────┐
BROWSER (WebAssembly Environment)
┌─────────────────────────────────────────────────────────┐
JS::Object (Browser DOM APIs)
▲
│ DOM Events (onclick, oninput) & Render Patches
▼
WebRubyUI::DOM (Event Bridge & JS Interop)
▲
│ In-Memory VNode Tree & Patch Diffing
▼
WebRubyUI::Component (Reactive State & HTML DSL)
└─────────────────────────────────────────────────────────┘
└─────────────────────────────────────────────────────────────┘
Add this line to your application's Gemfile:
gem'web_ruby_ui'And then execute:
bundle installCreate a reactive Single-Page Application without touching JavaScript:
require'web_ruby_ui'classTodoApp < WebRubyUI::Componentstate:items,default: [{id: 1,title: 'Learn Ruby WebAssembly',completed: true},{id: 2,title: 'Build WebRubyUI frontend framework',completed: true}]state:new_title,default: ''defrenderdiv(class: 'max-w-md mx-auto my-10 p-6 bg-white rounded-xl shadow-lg')doh1(class: 'text-2xl font-bold text-indigo-600 mb-4'){'RubyWasm Todo App 💎'}# Add Todo Formdiv(class: 'flex mb-4 gap-2')doinput(type: 'text',class: 'flex-1 px-4 py-2 border rounded-lg',placeholder: 'What needs to be done?',value: new_title,oninput: ->(e){self.new_title=e[:target][:value]})button(class: 'px-4 py-2 bg-indigo-600 text-white rounded-lg font-semibold',onclick: ->{add_todo}){'Add'}end# Todo Listul(class: 'divide-y divide-gray-200')doitems.eachdo |item|
li(class: 'py-3 flex items-center justify-between')dospan(class: item[:completed] ? 'line-through text-gray-400' : 'text-gray-800')doitem[:title]endendendendendendprivatedefadd_todoreturnifnew_title.nil? || new_title.strip.empty?self.items=items + [{id: Time.now.to_i,title: new_title.strip,completed: false}]self.new_title=''endend| Command | Description |
|---|---|
web_ruby_ui new my_app | Generates a new WebRubyUI project structure |
web_ruby_ui dev | Launches a local WebAssembly web server at http://localhost:8000 |
web_ruby_ui build | Packages standalone index.html for production deployment |
MIT License.