Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

https://www.ruby.or.jp/en/news/20251030

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

https://my-ruby-tutorial.com Browser runtime Rails app Ruby interpreter Filesystem Database

Slide 8

Slide 8 text

Cheap authoring More tutorials Growing ecosystem More users

Slide 9

Slide 9 text

User Builder Magician

Slide 10

Slide 10 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next

Slide 11

Slide 11 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next : "Let's jump in!"

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

rails-tutorial.evilmartians.io

Slide 14

Slide 14 text

tutorial.actionpolicy.evilmartians.io

Slide 15

Slide 15 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next : "Let's build!"

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

my-tutorial/ ├── src/ │ ├── content/tutorial/ │ │ ├── 1-getting-started/ │ │ └── meta.md │ └── templates/default/ │ ├── app/ │ ├── config/ │ └── Gemfile ├── ruby-wasm/ │ ├── Gemfile │ └── boot.rb # lesson content (MDX) # the Rails app (runs in the browser) # the Rails app for ruby.wasm module

Slide 18

Slide 18 text

├── package.json └── astro.config.mjs 1-welcome/ ├── content.mdx # lesson text ├── _files/ # starting state │ ├── app/controllers/pages_controller.rb │ ├── app/views/pages/home.html.erb │ └── config/routes.rb └── _solution/ ├── app/controllers/pages_controller.rb # finished state ├── app/views/pages/home.html.erb └── config/routes.rb

Slide 19

Slide 19 text

content.mdx --type: lesson title: Welcome focus: /app/controllers/pages.rb previews: - [3000, "Rails app"] filesystem: watch: true --- # sidebar label # file opened in editor # live-preview port # reflect edits live # Welcome This lesson covers the basics: - how Rails routes a request - how a controller responds - how ERB renders a view Edit the controller to return a greeting, then reload the preview.

Slide 20

Slide 20 text

npm run pack:wasm npm run dev # package Ruby gems # start the dev server

Slide 21

Slide 21 text

❤️

Slide 22

Slide 22 text

my-tutorial/ ├── AGENTS.md └── .agents/ └── skills/ ├── tutorial-quickstart/ ├── tutorial-content-structure/ ├── tutorial-lesson-config/ ├── rails-lesson-recipes/ ├── rails-file-management/ └── rails-wasm-author-constraints/

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Deploy

Slide 25

Slide 25 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next : "Let me show you how it works!"

Slide 26

Slide 26 text

TODO: Rails in a browser Ruby interpreter Static filesystem Dynamic filesystem Processes & shell Web server Database UI

Slide 27

Slide 27 text

WebAssembly

Slide 28

Slide 28 text

WebAssembly System Interface

Slide 29

Slide 29 text

https://github.com/ruby/ruby.wasm

Slide 30

Slide 30 text

TODO: Rails in a browser Ruby interpreter Static filesystem Dynamic filesystem Processes & shell Web server Database UI

Slide 31

Slide 31 text

wasi-vfs

Slide 32

Slide 32 text

https://github.com/palkan/wasmify-rails

Slide 33

Slide 33 text

bin/rails wasmify:build

Slide 34

Slide 34 text

TODO: Rails in a browser Ruby interpreter Static filesystem Dynamic filesystem Processes & shell Web server Database UI

Slide 35

Slide 35 text

2-layer filesystem /usr/ 🔨 BUILD TIME ▶️ RUNTIME ruby.wasm host FS stdlib /workspace/ /rails-vm/ user app gems · boot · Gemfile wasi-vfs · read-only WASI preopen · read-write

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

https://webcontainers.io

Slide 38

Slide 38 text

https://my-ruby-tutorial.com Web Application (main JS thread) WebContainer API Client ↓ (shell I/O) Terminal UI (files) Editor (HTTP) Preview Iframe WebContainer runtime (isolated Web Worker) Node.js Runtime (V8-based) ↓ (HTTP Traffic) ↔ Virtual File System (in memory) Service Worker (browser-level network proxy)

Slide 39

Slide 39 text

TODO: Rails in a browser Ruby interpreter Static filesystem Dynamic filesystem Processes & shell Web server Database UI

Slide 40

Slide 40 text

Preview iframe Express (WebContainer) JS globals Ruby (Rack) GET /articles req-42 = {method, path, headers, body} res-42 = {} evalAsync(handle("42")) read req-42 build Rack env · dispatch res-42 ← {status, headers, body} promise resolves HTTP response Preview iframe Express (WebContainer) JS globals Ruby (Rack)

Slide 41

Slide 41 text

TODO: Rails in a browser Ruby interpreter Static filesystem Dynamic filesystem Processes & shell Web server Database UI

Slide 42

Slide 42 text

https://github.com/electric-sql/pglite

Slide 43

Slide 43 text

https://github.com/stackblitz/tutorialkit

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

TutorialKit UI WebContainer runtime Rackcompatible web server PGLite Lesson files Terminal UI ruby.wasm Gems Native extensions System tools Ruby VM: WASM + WASI App code Preview Iframe

Slide 46

Slide 46 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next

Slide 47

Slide 47 text

Grant goals TutorialKit 1.0.0-rc1 Action Policy tutorial Outbound HTTP ruby.wasm build optimization

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

runruby.dev

Slide 50

Slide 50 text

class Gem::Request def perform_request(req) response = JS.eval(<<~JS).await return fetch(#{uri.to_s.to_json}, { ... }) .then(response => { ... }) JS Net::HTTPResponse.new("1.1", response[:status], "OK").tap do |r| r.body = response[:body] response[:headers].each { |k, v| r[k] = v } end end end

Slide 51

Slide 51 text

Net::HTTP.prepend(Module.new do def request(req, body = nil, &block) uri = reconstruct_url(req) response = WasmHTTP::Connection.new.request( uri, method: req.method, headers: headers(req), body: req.body ) yield response if block # Faraday's :net_http adapter reads status here response end def connect; end def do_start; @started = true; self; end def do_finish; @started = false; end end)

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

https://ruby-llm-tutorial.fly.dev/1-ruby-llm-demo/1-chat-with-llm/

Slide 54

Slide 54 text

Grant goals TutorialKit 1.0.0-rc1 Action Policy tutorial Outbound HTTP ruby.wasm build optimization

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

github.com/kateinoigakukun/mastodon.wasm

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

: "Something is off..."

Slide 59

Slide 59 text

WASI preopen (fd → /gems) Ruby VM (WASM) JS host require "rails" fd_stat(fd, "rails.rb") WASM ↔ JS boundary — imported JS fn stat(path) WebContainer FS lookup stat struct return value Ruby VM (WASM) WASI preopen (fd → /gems) JS host

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

npm run pack:wasm npm run build:wasm # pure-Ruby gems only: seconds # C extensions changed: minutes

Slide 62

Slide 62 text

: "Why keep the old one?"

Slide 63

Slide 63 text

gem install Gem author Ruby runtime cross-compile per platform pick matching .gem bcrypt_ext.so (x86_64-linux) require "bcrypt" dlopen("bcrypt_ext.so") native functions available gem install Ruby runtime

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

TODO: the talk Framework overview Tutorial capabilities Framework capabilities Framework architecture Ruby Association Grant work What comes next

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

WASI Preview 1 — today WASI Preview 2 — ahead Files, clocks, random, stdio ❌ Sockets ❌ Threads Everything in P1 ✅ Native sockets ✅ Better component model ✅ Standardized capabilities →

Slide 68

Slide 68 text

Two gates before we can experiment 🔬 ruby.wasm WASI P2 support Experimental branch already exists. Soft blocker. ⏳ WebContainer WASI P2 support StackBlitz would need to add support. External dependency.

Slide 69

Slide 69 text

TODO: drop WebContainer Swap HTTP serving to a Service Worker (mastodon.wasm pattern) Build a virtual filesystem + editor sync Terminal + process layer ( rails , bundle , etc.)

Slide 70

Slide 70 text

: "I learned something." : "Shipped." : "…still more to figure out."

Slide 71

Slide 71 text

Kudos Yuta Saito Vladimir Dementyev Svyatoslav Kruykov Grant mentor Rails tutorial POC runruby.dev ruby.wasm Action Policy tutorial JS-bridge HTTP pattern "Rails on Wasm" book

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

https://github.com/Bakaface/tutorialkit.rb

Slide 74

Slide 74 text

🙏