Skip to content

Commit 2a40a9f

Browse files
committed
Initialbook
1 parent 4031448 commit 2a40a9f

26 files changed

Lines changed: 1912 additions & 0 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
book

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# uzumibi-book-draft
2+
Draft file for uzumibi book version 1

book.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[book]
2+
title = "Introduction to Uzumibi"
3+
authors = ["Uchio Kondo"]
4+
language = "en"

src/LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2026, Kondo Uchio
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

src/SUMMARY.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Summary
2+
3+
- [Introduction](./ch01/index.md)
4+
- [What is mruby/edge](./ch01/mruby_edge.md)
5+
- [What is Uzumibi](./ch01/uzumibi.md)
6+
- [Project Setup and Hello World](./ch02/index.md)
7+
- [Installing uzumibi-cli](./ch02/install_cli.md)
8+
- [Creating a Project](./ch02/create_project.md)
9+
- [Implementing Hello World](./ch02/hello_world.md)
10+
- [Starting the Dev Server](./ch02/dev_server.md)
11+
- [Deployment](./ch02/deploy.md)
12+
- [Uzumibi and External Services](./ch03/index.md)
13+
- [Calling External APIs with Fetch](./ch04/index.md)
14+
- [Saving Memos with Durable Object](./ch05/index.md)
15+
- [Communicating with Cloudflare Queue](./ch06/index.md)
16+
- [Queue Use Cases](./ch06/use_cases.md)
17+
- [Queue Architecture and Setup](./ch06/overview.md)
18+
- [Publisher Implementation](./ch06/publisher.md)
19+
- [Consumer Implementation](./ch06/consumer.md)
20+
- [Appendix](./ch07/index.md)
21+
- [Supported Platforms](./ch07/platforms.md)
22+
- [Current Limitations](./ch07/limitations.md)
23+
- [References](./references.md)

src/ch01/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Introduction
2+
3+
Before discussing Uzumibi, let's first organize the concepts around mruby/edge, the mruby implementation that serves as Uzumibi's foundation. After that, we'll provide an overview of Uzumibi itself.

src/ch01/mruby_edge.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# What is mruby/edge
2+
3+
mruby/edge is a lightweight mruby implementation specialized for WebAssembly (Wasm) environments. It leverages the bytecode specification of mruby, a lightweight Ruby VM, and was developed with the goal of running efficiently in edge computing and serverless environments.
4+
5+
## What is mruby
6+
7+
[mruby](https://mruby.org/) is a lightweight implementation of the Ruby language designed to run in embedded environments and resource-constrained systems. It is primarily developed under the leadership of Yukihiro Matsumoto, the creator of Ruby. Compared to CRuby (the standard Ruby implementation), mruby has a smaller binary size and lower memory usage, making it suitable for embedding in various environments such as IoT devices and game engines.
8+
9+
<https://mruby.org/>
10+
11+
Recently, other implementations compatible with mruby's bytecode have been developed and are gaining attention, such as the even smaller [mruby/c](https://github.com/mrubyc/mrubyc) and [PicoRuby](https://picoruby.org/), which offers a more practical embedded ecosystem.
12+
13+
## Features of mruby/edge
14+
15+
mruby/edge is a re-implementation of the VM that executes mruby bytecode (`.mrb` files) written in Rust. It has the following features:
16+
17+
- **First-class WebAssembly support**: Designed to generate portable Wasm code. Currently supports compilation to `wasm32-unknown-unknown` and `wasm32-wasip1` targets, running on browsers, Wasmtime, Cloudflare Workers, Fastly Compute@Edge, and various other WASM runtimes.
18+
- **Rust implementation**: Since the VM is written in Rust, it offers high memory safety and smooth compilation to Wasm.
19+
- **mruby 3.2.0 compatibility**: Supports opcodes from mruby 3.2.0 through 3.4.0, enabling use of basic Ruby syntax and data types.
20+
- **SharedMemory**: Provides a mechanism for efficient data exchange with the host environment (JavaScript, etc.) by utilizing Wasm's linear memory.
21+
22+
## From mruby Code to WASM
23+
24+
The flow of converting Ruby code to Wasm with mruby/edge is as follows:
25+
26+
```
27+
Ruby source code (.rb)
28+
↓ Compile with mruby compiler (mrbc, mruby-compiler2, etc.)
29+
mruby bytecode (.mrb)
30+
↓ Embed in Rust binary
31+
↓ Compile to Wasm with cargo
32+
Wasm module (.wasm)
33+
```
34+
35+
This Wasm module can run in browsers. Additionally, by executing it on edge platforms such as Cloudflare Workers or Fastly, applications written in Ruby can be run at the edge.
36+
37+
It is also possible to embed mruby-compiler2 into Rust to directly execute Ruby scripts with mruby/edge. You can try it out on the [Playground](https://mrubyedge.github.io/playground/).
38+
39+
<https://mrubyedge.github.io/playground/>
40+
41+
## Supported Ruby Features
42+
43+
The following Ruby language features are supported in mruby/edge:
44+
45+
- Basic operations (arithmetic, comparison)
46+
- Conditional branching (`if/elsif/else`, `case/when`)
47+
- Method definition and recursive calls
48+
- Class definition and instance variables
49+
- `attr_reader` declarations
50+
- Global variables (`$var`)
51+
- Arrays (`Array`), Hashes (`Hash`), Strings (`String`)
52+
- Range objects (`Range`)
53+
- Blocks and iterators
54+
- Exception handling (`raise`/`rescue`)
55+
- String `unpack`/`pack` (binary data processing)
56+
57+
The specific supported methods can be checked in the [`COVERAGE.md`](https://github.com/mrubyedge/mrubyedge/blob/v1.1.10/mrubyedge/COVERAGE.md) file. It may also be useful to have AI reference this file.
58+
59+
Additionally, the following libraries are available as mrubyedge gems:
60+
61+
- `mruby-random`
62+
- `mruby-regexp`
63+
- `mruby-math`
64+
- `mruby-serde-json`
65+
- `mruby-time`
66+
67+
## Summary of mruby/edge
68+
69+
mruby/edge plays a crucial role as the foundation of the Uzumibi framework, enabling Ruby-written web application logic to run in edge environments.

src/ch01/uzumibi.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# What is Uzumibi
2+
3+
Uzumibi is a lightweight framework for building web applications in Ruby on edge computing platforms, built on top of mruby/edge.
4+
5+
The name "Uzumibi" is inspired by the popular edge framework [Hono](https://hono.dev/). Hono + Embedded (埋まっている / "buried") = Uzumibi (うずみび / "buried embers") 😅
6+
7+
## Overview of Uzumibi
8+
9+
Uzumibi is a web application framework that allows you to define routing using a Sinatra-like DSL. You can write applications that handle HTTP requests with Ruby code like the following:
10+
11+
```ruby
12+
class App < Uzumibi::Router
13+
get "/" do |req, res|
14+
res.status_code = 200
15+
res.headers = {
16+
"content-type" => "text/plain",
17+
"x-powered-by" => "#{RUBY_ENGINE} #{RUBY_VERSION}"
18+
}
19+
res.body = "It works!\n"
20+
res
21+
end
22+
23+
get "/greet/to/:name" do |req, res|
24+
res.status_code = 200
25+
res.headers = {
26+
"content-type" => "text/plain",
27+
}
28+
res.body = "Hello, #{req.params[:name]}!!\n"
29+
res
30+
end
31+
end
32+
33+
$APP = App.new
34+
```
35+
36+
## How It Works
37+
38+
Uzumibi applications operate in a two-layer architecture:
39+
40+
1. **Wasm layer (Rust + mruby/edge)**: Ruby code is compiled into mruby bytecode and embedded in a Wasm module. Request processing is handled by Ruby code running on the mruby/edge VM.
41+
2. **Platform layer (JavaScript / Rust)**: Glue code that bridges the edge platform's native APIs with the Wasm module. It handles binary serialization of HTTP requests/responses.
42+
43+
The request flow looks like this:
44+
45+
```
46+
Client
47+
→ Edge platform
48+
→ Glue code (JS/Rust) serializes request to binary
49+
→ Ruby code executes on mruby/edge VM inside WASM module
50+
→ Response is deserialized from binary
51+
→ Response returned to client
52+
```
53+
54+
## Routing
55+
56+
Uzumibi's router supports the following HTTP methods:
57+
58+
- `get`
59+
- `post`
60+
- `put`
61+
- `delete`
62+
- `head`
63+
- `options`
64+
65+
URL paths can include dynamic parameters (`:name`) and wildcards (`*`). Parameters are accessible via `req.params`, which is a Hash.
66+
67+
```ruby
68+
# Dynamic parameter example
69+
get "/users/:id" do |req, res|
70+
user_id = req.params[:id]
71+
# ...
72+
end
73+
```
74+
75+
In this book, we refer to the Ruby blocks defined with `get`, `post`, etc. as "route handlers".
76+
77+
## Request Object
78+
79+
The `req` object (`Uzumibi::Request`) passed to the route handler block holds the following information:
80+
81+
- `req.method` - HTTP method (GET, POST, etc.)
82+
- `req.path` - Request path
83+
- `req.query` - Query string
84+
- `req.headers` - Request headers (Hash)
85+
- `req.body` - Request body
86+
- `req.params` - A Hash that integrates URL parameters, query parameters, and form data
87+
88+
## Response Object
89+
90+
The `res` object (`Uzumibi::Response`) is used to construct the response by setting the following properties:
91+
92+
- `res.status_code` - HTTP status code (integer)
93+
- `res.headers` - Response headers (Hash)
94+
- `res.body` - Response body (string)
95+
96+
The route handler block must always return the `res` object.
97+
98+
## External Service Integration
99+
100+
Uzumibi also supports access to external services provided by edge platforms. On Cloudflare Workers, the following are available:
101+
102+
- **`Uzumibi::Fetch`** - Call external HTTP APIs
103+
- **`Uzumibi::KV`** - Key-Value store using Durable Objects
104+
- **`Uzumibi::Queue`** - Asynchronous messaging with Cloudflare Queues
105+
106+
These features are explained in detail in later chapters.
107+
108+
> **Note:** As of March 14, 2026, external services are not available on platforms other than Cloudflare Workers. Support for other platforms will be added progressively. Pull requests are always welcome!

src/ch02/create_project.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Creating a Project
2+
3+
Use the `uzumibi new` command to create a project for Cloudflare Workers.
4+
5+
## Generating the Project
6+
7+
Create a project named `hello-uzumibi` with the following command:
8+
9+
```bash
10+
uzumibi new --template cloudflare hello-uzumibi
11+
```
12+
13+
Running this command will create a project directory and generate the necessary files:
14+
15+
```
16+
Creating project 'hello-uzumibi'...
17+
generate hello-uzumibi/.gitignore
18+
generate hello-uzumibi/Cargo.toml
19+
generate hello-uzumibi/package.json
20+
generate hello-uzumibi/vitest.config.js
21+
generate hello-uzumibi/wrangler.jsonc
22+
generate hello-uzumibi/lib/app.rb
23+
generate hello-uzumibi/public/assets/index.html
24+
generate hello-uzumibi/src/index.js
25+
generate hello-uzumibi/wasm-app/Cargo.toml
26+
generate hello-uzumibi/wasm-app/build.rs
27+
generate hello-uzumibi/wasm-app/src/lib.rs
28+
29+
✓ Successfully created project from template 'cloudflare'
30+
Run 'cd hello-uzumibi' to get started!
31+
```
32+
33+
## Project Directory Structure
34+
35+
The generated project has the following structure:
36+
37+
```
38+
hello-uzumibi/
39+
├── Cargo.toml # Rust workspace configuration
40+
├── package.json # Node.js dependencies and scripts
41+
├── wrangler.jsonc # Wrangler (Cloudflare Workers CLI) configuration
42+
├── lib/
43+
│ └── app.rb # Ruby application code (main)
44+
├── public/
45+
│ └── assets/... # Static assets (HTML, CSS, images, etc.)
46+
├── src/
47+
│ └── index.js # JavaScript glue code (entry point)
48+
└── wasm-app/
49+
├── Cargo.toml # WASM crate configuration
50+
├── build.rs # Build script (compiles Ruby code)
51+
├── src/
52+
│ └── lib.rs # Rust code for the WASM module
53+
└── .cargo/
54+
└── config.toml # Cargo target settings (may not exist)
55+
```
56+
57+
## Role of Each File
58+
59+
### `lib/app.rb`
60+
61+
**This is the main file that developers edit.** You write Uzumibi's routing and request handling logic in Ruby here.
62+
63+
### `src/index.js`
64+
65+
The entry point for Cloudflare Workers. It receives HTTP requests, serializes them to binary format and passes them to the WASM module, then deserializes the response and returns it to the client. Normally, you don't need to edit this file.
66+
67+
### `wasm-app/`
68+
69+
A Rust crate for compiling Ruby code into mruby bytecode and packaging it as a WASM module. Normally, you don't need to edit these files.
70+
71+
- `build.rs` contains configuration to compile `lib/app.rb` into mruby bytecode (`.mrb`) at build time.
72+
- `src/lib.rs` handles mruby/edge VM initialization and export function definitions.
73+
74+
### `wrangler.jsonc`
75+
76+
The Cloudflare Workers configuration file. It contains the application name, static asset settings, and more.
77+
78+
```jsonc
79+
{
80+
"name": "hello-uzumibi",
81+
"main": "src/index.js",
82+
"compatibility_date": "2025-12-30",
83+
"assets": {
84+
"directory": "./public",
85+
"binding": "ASSETS"
86+
}
87+
}
88+
```
89+
90+
### `package.json`
91+
92+
Defines npm/pnpm scripts and dependencies.
93+
94+
```json
95+
{
96+
"scripts": {
97+
"deploy": "wrangler deploy",
98+
"dev": "cargo build --package hello-uzumibi --target wasm32-unknown-unknown --release && cp -v -f target/wasm32-unknown-unknown/release/hello_uzumibi.wasm src/ && wrangler dev",
99+
"start": "wrangler dev",
100+
"test": "vitest"
101+
}
102+
}
103+
```
104+
105+
The `dev` script performs both the Rust build (WASM compilation) and Wrangler dev server startup in one step.
106+
107+
## Installing Dependencies
108+
109+
Navigate to the project directory and install the Node.js dependencies:
110+
111+
```bash
112+
cd hello-uzumibi
113+
pnpm install
114+
```
115+
116+
This installs development tools including Wrangler locally within the project.

0 commit comments

Comments
 (0)