roadrunner_gleam
Run Gleam web apps on Roadrunner, the pure-Erlang HTTP/1.1, HTTP/2, HTTP/3 and WebSocket server.
Requirements
Requires OTP 27+ and Gleam 1.19+, with rebar3 installed to build
Roadrunner.
🚧 Status
roadrunner_gleam is in 0.x. The core is functional and covered by tests,
but the API may change between minor versions. Pin an exact version in your
deps if you need stability across upgrades.
Installation
gleam add roadrunner_gleam
Usage
import gleam/erlang/process
import roadrunner_gleam
import roadrunner_gleam/request.{type Request}
import roadrunner_gleam/response.{type Response}
pub fn main() {
let assert Ok(_) =
roadrunner_gleam.new(handle)
|> roadrunner_gleam.port(8080)
|> roadrunner_gleam.start
process.sleep_forever()
}
fn handle(request: Request) -> Response {
case request.path_segments(request) {
[] -> response.text("hello, roadrunner!")
["hello", name] -> response.text("hello, " <> name <> "!")
_ -> response.new(404)
}
}
$ curl localhost:8080/hello/gleam
hello, gleam!
To run the listener under a gleam/otp supervisor, add
roadrunner_gleam.supervised(builder) as a child.
TLS, HTTP/2 and HTTP/3
roadrunner_gleam.new(handle)
|> roadrunner_gleam.port(8443)
|> roadrunner_gleam.tls(certfile: "cert.pem", keyfile: "key.pem")
|> roadrunner_gleam.http3
|> roadrunner_gleam.start
A TLS listener serves HTTP/1.1 and HTTP/2 on the TCP port. http3 also
serves HTTP/3 over QUIC on the UDP port with the same number, or, with
port 0, on a UDP port of its own that listener_quic_port returns.
Any other Roadrunner listener option, such as max_content_length or
keep_alive_timeout, can be set with roadrunner_gleam.option.
What works
- Handlers are plain Gleam functions, the same on HTTP/1.1, HTTP/2 and HTTP/3
- Requests are read in place, at the same cost as an Erlang handler
- Request bodies read before the handler, or on demand in pieces so large uploads never sit in memory whole
- Responses: complete, chunked and files sent by the kernel
content-lengthset for you on complete and file responses- Response compression with
gzipordeflate(roadrunner_gleam.compress) - Cookies, the client’s address, the connection’s peer and local address, and the client’s TLS certificate
request.from_httpto test handlers without starting a listener- WebSocket sessions over HTTP/1.1, with typed state, a
Subjectother processes can push through, and aSelectorfor anything else, such as monitors - Responses that stay open and push data as messages arrive, such as server-sent events with a builder for them, on HTTP/1.1, HTTP/2 and HTTP/3
- Responses are
gleam_httpresponses, sogleam/http/response’sset_header,set_cookie,redirectand the rest work on them, andrequest.to_httpgives agleam_httprequest - Start, stop and drain listeners, or run them under a
gleam/otpsupervisor
Sponsors
roadrunner_gleam is open source and maintained on personal time. If you or your company find it useful, consider sponsoring.
I also accept coffees ☕
License
Copyright (c) 2026 William Fank Thomé
roadrunner_gleam is open-source under the Apache 2.0 License on GitHub.
See LICENSE.md for more information.
