Zero-allocation HTTP routing engine
Masterless. Disciplined. Self-contained.
Named after the masterless samurai - fast, disciplined, and self-contained. RONIN carries no excess. No dependencies. No allocations it doesn't need. A single warrior, purpose-built for routing.
Performance
Every design decision optimizes for throughput and minimal overhead.
Compressed radix trie. Lookup time proportional to key length, not route count.
Only the Rust standard library. No external crates. Full control over every byte.
Request parsing borrows directly from the receive buffer. No unnecessary copies.
Capabilities
A focused feature set for building HTTP services in Rust.
Routes stored in a compressed trie for O(k) lookup. Shared prefixes merged automatically.
Named parameters like /users/:id with zero-copy extraction from the request path.
Catch-all patterns with *wildcard for static file serving and flexible routing.
Nest routers under shared prefixes. Organize APIs cleanly without duplication.
Each connection handled on its own thread. Simple concurrency model, no runtime needed.
Persistent connections supported out of the box. Reuse TCP connections across requests.
Quick Start
A minimal HTTP server with routing, path parameters, and JSON responses.
use ronin::{Router, Request, Response}; fn main() { let mut router = Router::new(); // Simple GET route router.get("/", |_req: &Request, res: &mut Response| { res.send("Hello, Ronin."); }); // Path parameters router.get("/users/:id", |req: &Request, res: &mut Response| { let id = req.param("id").unwrap(); res.json(&format!(r#"{{"user_id": "{}"}}"#, id)); }); // Route groups let mut api = Router::new(); api.get("/health", |_req, res| { res.json(r#"{"status": "ok"}"#); }); router.group("/api", api); // Wildcard route for static files router.get("/static/*path", |req: &Request, res: &mut Response| { let path = req.param("path").unwrap(); res.send(&format!("Serving: {}", path)); }); router.listen("0.0.0.0:3000"); }
Reference
Core types and their methods.
| Method | Signature | Description |
|---|---|---|
| new | Router::new() -> Router | Create a new router instance |
| get | router.get(path, handler) | Register a GET handler |
| post | router.post(path, handler) | Register a POST handler |
| put | router.put(path, handler) | Register a PUT handler |
| delete | router.delete(path, handler) | Register a DELETE handler |
| group | router.group(prefix, sub_router) | Nest a router under a prefix |
| listen | router.listen(addr) | Start accepting connections |
| Method | Signature | Description |
|---|---|---|
| method | req.method() -> &str | HTTP method |
| path | req.path() -> &str | Request path |
| param | req.param(name) -> Option<&str> | Extract path parameter |
| header | req.header(name) -> Option<&str> | Get header value |
| body | req.body() -> &[u8] | Raw request body |
| Method | Signature | Description |
|---|---|---|
| status | res.status(code) | Set HTTP status code |
| header | res.header(name, value) | Set response header |
| send | res.send(body) | Send text response |
| json | res.json(body) | Send JSON response |
Installation
Add RONIN to your Rust project with cargo.
cargo add ronin
Or add to Cargo.toml:
ronin = "0.1"
use ronin::{Router, Request, Response}; fn main() { let mut router = Router::new(); router.get("/", |_req, res| { res.send("Hello, Ronin."); }); router.listen("0.0.0.0:3000"); }