- π Support multi runtimes
Supports JavaScript runtimes (Node.js, Deno, Bun), CloudFlare Workers, and Erlang with Mist. - π§© Module first
Features are divided into modules, generating JavaScript that is advantageous for Tree-shaking. Additionally, no extra FFI code is mixed in during bundling. - π§ Custom context
TheHinototype can contain arbitrary context, allowing runtime-specific information to be handled in the same way. - β‘ Promise-based async (v2.0.0+)
JavaScript targets use Promise-based handlers for async operations, while Erlang remains synchronous.
import gleam/http/request
import gleam/http/response
import gleam/javascript/promise
import gleam/option.{None}
import gleam/string
import hinoto
import hinoto/runtime/node
pub fn main() -> Nil {
let fetch_handler =
node.handler(fn(hinoto_instance) {
use updated_hinoto <- promise.await(
hinoto_instance
|> hinoto.handle(handler),
)
promise.resolve(updated_hinoto)
})
node.start_server(fetch_handler, None, None)
}
pub fn handler(req) {
case request.path_segments(req) {
[] -> create_response(404, "<h1>Hello, Hinoto with Node.js!</h1>")
["greet", name] ->
create_response(200, string.concat(["Hello! ", name, "!"]))
_ -> create_response(404, "<h1>Not Found</h1>")
}
|> promise.resolve
}
pub fn create_response(status: Int, html: String) {
response.new(status)
|> response.set_body(html)
|> response.set_header("content-type", "text/html")
}import gleam/http/request
import gleam/http/response
import gleam/javascript/promise.{type Promise}
import gleam/string
import hinoto.{type Hinoto}
import hinoto/runtime/workers.{type WorkersContext}
pub fn main() {
workers.serve(fn(hinoto: Hinoto(WorkersContext, String)) -> Promise(
Hinoto(WorkersContext, String),
) {
use hinoto <- promise.await(
hinoto
|> hinoto.handle(handler),
)
promise.resolve(hinoto)
})
}
pub fn handler(req) {
case request.path_segments(req) {
[] ->
create_response(200, "<h1>Hello, Hinoto with Cloudflare Workers!</h1>")
_ -> create_response(404, "<h1>Not Found</h1>")
}
|> promise.resolve
}
pub fn create_response(status: Int, html: String) {
response.new(status)
|> response.set_body(html)
|> response.set_header("content-type", "text/html")
}Note: v2.0.0 introduces Promise-based async handlers for JavaScript targets. See the Migration Guide below for upgrading from v1.x.
Add dependencies for hinoto and hinoto_cli to the dependencies section of gleam.toml.
hinoto = { git = "https://github.com/Comamoca/hinoto", ref = "main" }
hinoto_cli = { git = "https://github.com/Comamoca/hinoto_cli", ref = "main" }gleam run -m hinoto/cli -- workers init
wrangler devFor developing with various target JavaScript runtimes and CloudFlare Workers, wrangler is required.
cd example/
# For CF Workers
cd workers
wrangler dev
# For node.js
cd node_server
# For deno
cd deno_server
# For bun
cd bun_server
See todo.md
Each runtime uses an optimal body type for its environment:
| Runtime | Body Type | Description |
|---|---|---|
| Mist (Erlang) | Connection |
Native streaming body support for efficient handling of large uploads |
| Node.js | String |
String-based bodies via Hinoto abstraction |
| Deno | JsRequest |
Runtime-specific type handled via FFI |
| Bun | JsRequest |
Runtime-specific type handled via FFI |
| Cloudflare Workers | String |
String-based bodies via Hinoto abstraction |
Why different types?
- Erlang/Mist: Uses
Connectionto support streaming request bodies, enabling efficient handling of large file uploads and chunked data - JavaScript runtimes: Use
Stringor runtime-specific types for simpler, stateless request handling
MIT