radiant

A focused, type-safe HTTP router for Gleam on BEAM.
Built on a prefix tree with specificity-based priority, no global state, no macros.
gleam add radiant
Quick start
import gleam/int
import radiant
pub const user_id = radiant.int("id")
pub fn router() -> radiant.Router {
radiant.new()
|> radiant.get("/", fn(_req) { radiant.ok("hello") })
|> radiant.get1("/users/<id:int>", user_id, fn(_req, id) {
radiant.json("{\"id\":" <> int.to_string(id) <> "}")
})
|> radiant.scope("/api/v1", fn(r) {
r |> radiant.post("/items", create_item)
})
}
get1 hands the parsed Int directly to the handler — no let assert, no int.parse.
Why Radiant?
Gleam’s native routing is case wisp.path_segments(req) — great for small apps. Radiant adds:
| Native pattern matching | Radiant |
| Type-safe path params | ❌ | ✅ |
| Specificity-based priority | ❌ | ✅ |
| 405 Method Not Allowed | manual | ✅ automatic |
| HEAD support (RFC 9110) | manual | ✅ automatic |
| Reverse routing | ❌ | ✅ |
| Route introspection | ❌ | ✅ |
| Built-in test helpers | ❌ | ✅ |
| CORS middleware | ❌ | ✅ |
| Query params (typed) | manual | ✅ |
Features
- Prefix tree: O(1) literal lookup; cost grows with path depth, not route count.
- Specificity priority:
Literal > <id:int> > <name:string> > *wildcard, regardless of registration order.
- Typed routes (
get1–get6): handlers receive parsed Int/String values directly.
- Type-safe context: pass data through middlewares via
Key(a) — no Dynamic, no manual decoding.
- Automatic 405 + HEAD: correct
Allow header and HEAD→GET fallback built in.
- Startup validations: wildcard position, duplicate capture names, and capture ambiguity checked at registration, not at request time.
- Swappable static server:
FileSystem interface works with simplifile or any IO library.
- Testing helpers: synthetic requests and fluent assertions — no running server needed.
Documentation
Non-goals
Radiant does not provide: template rendering, sessions, cookies, authentication, or WebSockets.
Use the underlying server (Mist) or a full framework (Wisp) directly for those.
Development
gleam test # Run the test suite
gleam dev # Start the demo server on :4000