Type-safe web framework with automatic TypeScript client generation
Website • Documentation • Getting Started • Examples
Ultimo is a modern Rust web framework built on Hyper + Tokio:
secure-by-default, fast, and type-safe end to end — with automatic TypeScript
client generation from your Rust API. REST and JSON-RPC live in one app, and
the framework is 100% safe Rust (#![forbid(unsafe_code)]).
- 🚀 Automatic TypeScript clients — define your API in Rust, get a fully typed TS client generated for you.
- 🔄 REST + JSON-RPC 2.0 in one app — plain HTTP routes and RPC procedures side by side, with batch requests and notifications.
- 🔌 WebSockets — RFC 6455 with a built-in pub/sub system (zero extra deps).
- 🌊 Streaming responses — chunked/streaming bodies via
ctx.stream(...). - 📡 Server-Sent Events — typed server→client push via
ctx.sse(...)+EventSource. - 🔐 Auth, built in — JWT and API-key middleware plus scope-based authorization guards.
- 🛡️ Secure by default — 100% safe Rust, secure sessions/cookies, CSRF, security-headers middleware, request body-size limits, and supply-chain CI.
- ⚡ Fast — native Rust on the Hyper + Tokio core, O(1) constant-time routing, benchmarks regression-guarded in CI (details).
- 🗄️ Databases — first-class SQLx and Diesel integration (PostgreSQL / MySQL / SQLite).
- 🧪 Testing utilities — in-process
TestClient, response assertions, and fixtures. - 🤖 Built for coding agents — typed Rust→TS codegen, scaffolds that build,
llms.txtdocs, and Context7. See Using Ultimo with AI coding agents.
[dependencies]
ultimo = "0.9"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }use ultimo::prelude::*;
#[derive(Serialize, Deserialize)]
struct User {
id: u32,
name: String,
}
#[tokio::main]
async fn main() -> ultimo::Result<()> {
let mut app = Ultimo::new();
app.get("/users/:id", |ctx: Context| async move {
let id: u32 = ctx
.req
.param("id")?
.parse()
.map_err(|_| UltimoError::BadRequest("invalid id".into()))?;
ctx.json(User { id, name: format!("User {id}") }).await
});
println!("→ http://127.0.0.1:3000");
app.listen("127.0.0.1:3000").await
}MSRV: Rust 1.86. Everything beyond the core is opt-in via Cargo features (see below).
Ultimo's headline feature: define an API once in Rust and generate a typed TypeScript client — no hand-written types, no drift.
# Generate a TypeScript client from your RPC definitions
cargo run -p ultimo-cli -- generate --project ./backend --output ./client// Generated, fully typed — autocomplete + compile-time checks
const user = await client.getUser({ id: 1 });
console.log(user.name);See TypeScript Clients for the full workflow.
Everything is opt-in (default = []):
| Feature | What it enables |
|---|---|
websocket |
RFC 6455 WebSocket support + pub/sub |
session |
Cookie-based session management |
jwt |
JWT authentication middleware (HS256) |
api-key |
API-key authentication with a pluggable store |
csrf |
CSRF protection (double-submit cookie) |
static-files |
Static file serving + SPA fallback (serve_static, serve_spa) |
compression |
Automatic gzip/brotli response compression (pure Rust, no C deps) |
client-gen |
Derive RPC client TypeScript types from Rust types (via ts-rs) |
oidc |
Verify OIDC/JWKS (RS256/ES256) tokens — Clerk, Auth0, Cognito, Supabase |
testing |
In-process TestClient, assertions, fixtures |
test-helpers |
WebSocket test helpers (for integration tests) |
sqlx-postgres · sqlx-mysql · sqlx-sqlite |
SQLx integration per backend |
diesel-postgres · diesel-mysql · diesel-sqlite |
Diesel integration per backend |
ultimo = { version = "0.9", features = ["websocket", "jwt", "sqlx-postgres"] }cargo install ultimo-cli # installs the `ultimo` binary
ultimo new my-app --template fullstack # scaffold a new project
ultimo generate --project ./backend --output ./client # generate the TypeScript clientultimo dev --port 3000 # hot-reload dev server (watches src/, restarts on change)
ultimo buildis not implemented yet — usecargo build --releasefor now. See the roadmap.
Full guides at docs.ultimo.dev — getting started, routing, middleware, RPC + TypeScript clients, OpenAPI, sessions, authentication, WebSockets, database integration, testing, and performance.
Runnable examples live in examples/.
Run one locally with:
cargo run -p jwt-auth-exampleTry them without cloning (hosted on Render free tier — first request may take ~30s):
| Demo | What it shows |
|---|---|
| basic-example | Routing, JSON, query params, HTML |
| session-auth | Cookie sessions + CSRF protection |
| jwt-auth | JWT authentication + scope guards |
| websocket-chat | WebSocket pub/sub chat room |
| spa-demo | Static files + SPA fallback |
| openapi-demo | Swagger UI + OpenAPI spec |
Issues and PRs welcome. See CONTRIBUTING.md and the roadmap. Security policy: SECURITY.md.
MIT © Ultimo Contributors. See LICENSE.