Changelog
All notable changes to the Ultimo framework are documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.6.0] - 2026-07-08
Security
- Session
clear()now correctly destroys the store entry and expires the cookie — previously it was marked dirty-and-empty but neither persisted nor removed, silently leaving the old session data resolvable via the still-valid cookie. (#157) MemoryStore::with_max_sessions(n)bounds session-store memory under sustained load, evicting the soonest-to-expire entry once at capacity (opt-in, non-breaking;MemoryStore::new()remains unbounded). (#157)- Rate-limiter buckets are now evicted once idle for a full window, bounding memory growth from many distinct keys (e.g. spoofed
X-Forwarded-Forvalues undertrust_proxy). (#157) - Internal error variants (
UltimoError::Io/Hyper/HttpError) no longer echo raw OS/protocol error text to clients — they now return a generic message, avoiding leaking filesystem paths or internals. (#157) - WebSocket
Originallow-list (Cross-Site WebSocket Hijacking defense): browsers don't enforce same-origin for WebSocket connections the way they do forfetch. Restrict the handshake to trusted origins viaWebSocketUpgrade::with_allowed_origins/Ultimo::websocket_with_config_and_origins(empty/default preserves prior behavior — no check). (#157) - Bumped
jsonwebtoken9 → 10, fixing CVE-2026-25537 (a type-confusion vulnerability in JWT claim validation). (#158) - BREAKING: bumped
sqlx0.7 → 0.8, fixing RUSTSEC-2024-0363 (binary protocol misinterpretation, all backends). Becauseultimo's SQLx integration re-exposessqlxtypes directly through its public API (SqlxPool<DB: sqlx::Database>,PgPoolOptions, …), downstream consumers of thesqlx/sqlx-postgres/sqlx-mysql/sqlx-sqlitefeatures need to bump their ownsqlxdependency to"0.8"in lockstep. (#159)
Added
- Rate limiting middleware (token bucket):
RateLimiter/rate_limiter(), keyed by client IP, a request header, or globally; returns429withRetry-After. (#154) serve_docs()— one-line interactive Swagger UI + OpenAPI JSON, the Ultimo equivalent of FastAPI's/docs. (#153)- IP allow/deny middleware (
IpFilter) with CIDR support, for allow-listing or blocking client IP ranges. (#131) ultimo generate --watchand scaffoldedgenerate-clientsupport in project templates. (#155)
[0.5.1] - 2026-06-15
Added
ultimo dev— hot-reload development server with file watching (#15)
[0.5.0] - 2026-06-09
Added
- TypeScript client type derivation (
client-genfeature): RPC client types are now derived from your Rust types viats-rs.#[derive(TS)]on your input/output structs and the generated client emits realtype X = {...}declarations — no more hand-written type strings or dangling references.ts_rs::TSis re-exported asultimo::rpc::TS. (#107)
Changed
- BREAKING:
RpcRegistry::query/mutationnow take(name, handler)and derive their TypeScript input/output types from the Rust types (boundsI: TS, O: TS, gated behindclient-gen). The previous string-typed signatures are preserved asquery_with_types/mutation_with_types. (#107) ts-rsis now an optional dependency behindclient-gen(previously an unused hard dependency) and was upgraded 8.1 → 12. Default builds no longer pull it. (#107)- Removed the hardcoded
Userinterface that was previously injected into every generated client. (#107)
[0.4.1] - 2026-06-09
Added
- Static file serving (
static-filesfeature):serve_staticserves assets from disk with automaticContent-Type,ETag, and304 Not Modified;serve_spaadds Single Page Application fallback routing; path traversal is blocked at the filesystem level. Adds catch-all (*name) wildcard segments to the router. (#101) - Response compression (
compressionfeature): automatic gzip/brotli middleware (brotli preferred), pure Rust with no C dependencies, configurable via theCompressionbuilder. Skips binary content types, already-encoded responses, and small bodies; always setsVary: Accept-Encoding. (#101)
Changed
- Crate install snippets (
ultimo = "…") across the README and docs pages are now derived from the workspace version and enforced by theversion-syncCI gate, eliminating version drift. (#102)
[0.4.0] - 2026-06-08
The Security & Performance milestone.
Added
- JWT authentication (
jwtfeature): HS256 verify + sign, algorithm pinned (alg: nonerejected),expvalidated, claims onContext. (#84) - API-key authentication (
api-keyfeature): pluggableApiKeyStore+ built-inStaticKeys(SHA-256 hashed, constant-time), resolving to an identity (id + scopes). (#86) - Authorization guards: unified
auth::Principal;ctx.require_auth/require_scope/require_any_scope/require_all_scopes, fed by both JWT and API-key. (#87) - Security-headers middleware (HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy; opt-in CSP). (#56, #71)
- CSRF protection (
csrffeature): double-submit cookie, constant-time compare. (#57, #80) - Request body-size limit (
max_body_size) — 413 on oversize, without buffering the whole body. (#58, #72) - Real client IP (
ctx.client_ip), trusted-proxy aware viatrust_proxy. (#65, #76) # +SECURITY.mddisclosure policy. (#69)
Performance
- O(1) static route lookup via a hash index — was O(N) in route count. (#90)
- Framework-overhead benchmark suite (criterion) +
BENCHMARKS.mdmethodology + an advisory CI regression check. (#88, #13)
Docs
- New
/performance,/jwt,/api-keys, and/authorizationpages; an "Authentication" docs group; and an honest "Secure & Fast" website (removed unsubstantiated benchmark numbers).
[0.3.0] - 2026-06-04
Added
- Sessions (
sessionfeature): cookie-based session management —SessionStore+MemoryStore,ctx.session(), secure middleware (256-bit ids, HttpOnly/Secure/SameSite, anti-fixation/DoS),SessionConfig. See the session-auth example. - Cookie helper (
ultimo::cookie): parsing +Set-Cookieformatting andctx.cookie/set_cookie/remove_cookie. - Testing utilities (
testingfeature): in-processTestClient, request builder, response assertions, macros, middleware/DB/fixture helpers. Ultimo::oneshotfor in-process dispatch;Request::raw_body().
Fixed
- Router precedence: static routes win over parameterized ones regardless of registration order.
Changed
- MSRV raised to 1.86.0 (breaking). Dependency floors hardened for RUSTSEC advisories.
[0.2.1] - 2026-01-04
Fixed
- Updated WebSocket pubsub benchmark to match new ChannelManager API
- Removed unused imports in React example projects
Coming Soon
- Server-Sent Events (SSE)
- Session management
- Testing utilities
- Multi-language client generation
- Per-message deflate compression (RFC 7692)
[0.2.0] - 2026-01-04
Added
WebSocket Support (Complete) 🔌
- Zero-dependency RFC 6455 compliant WebSocket implementation
- Built on hyper's upgrade mechanism (no tokio-tungstenite required)
- Type-safe WebSocketHandler trait with typed context data
- Built-in pub/sub system (ChannelManager) for topic-based messaging
- Seamless router integration with
app.websocket()method - Router optimization: Migrated to Radix Tree for O(L) lookups
- 279 comprehensive tests (128 unit, 151 integration)
- Production-ready features:
- Configuration System (
WebSocketConfig) with size limits, timeouts, and buffer sizes - Message Fragmentation for large payloads with automatic reassembly
- Automatic Ping/Pong heartbeat with configurable intervals and timeout detection
- Graceful Shutdown with
broadcast_all()and proper close handshakes - Backpressure Handling with bounded channels,
on_drain()callback, and capacity tracking
- Configuration System (
- Two working examples:
- Simple HTML/JS chat application
- Modern React + TypeScript chat with shadcn/ui
- Frame codec supporting all opcodes (text, binary, ping, pong, close, continuation)
- Frame masking/unmasking (client frames must be masked per RFC 6455)
- Control frame handling (close, ping, pong)
- Automatic message fragmentation for large payloads (>max_frame_size)
- Fragment reassembly with
FragmentAccumulator - Subscribe/unsubscribe to topics
- Publish messages to all topic subscribers with backpressure handling
- Automatic cleanup on disconnect
- Connection lifecycle callbacks (on_open, on_message, on_close, on_drain)
- Type-safe context data per connection (
WebSocket<T>) - JSON message helpers (send_json, recv_json)
- Configurable size limits (max_message_size: 10MB, max_frame_size: 1MB)
- Bounded channels with configurable buffer (default 1024)
- Automatic ping/pong heartbeat (configurable interval, default 30s)
- Timeout detection for unresponsive clients (default 10s)
- Backpressure notifications via
on_drain()callback - Capacity tracking:
capacity(),max_capacity(),has_capacity() - Graceful shutdown with
broadcast_all()for server-wide notifications - Custom close frames with reason codes
- Zero additional dependencies (uses existing hyper, tokio, bytes)
- Efficient memory usage with BytesMut for frame parsing
- O(L) router lookups with Radix Tree optimization
- WEBSOCKET_DESIGN.md - Architecture and design decisions
- WEBSOCKET_TESTING.md - Testing strategy and coverage
- Example READMEs with setup instructions
[0.1.0] - 2025-11-21
Core Features
Framework- ⚡ High-performance HTTP server built on Hyper
- 🎯 Type-safe routing with path parameters
- 🔧 Composable middleware system (CORS, Logger, PoweredBy, Custom)
- 📊 Built-in RPC support (REST & JSON-RPC modes)
- 📝 OpenAPI 3.0 specification generation
- ✨ Automatic TypeScript client generation
- ✅ Request validation with detailed errors
- 🛡️ Comprehensive error handling
- 🧪 70.7% test coverage (124 tests)
- 📈 Custom coverage tool with modern HTML reports
- 🔍 Git hooks for code quality (pre-commit, pre-push)
- 📚 Complete documentation and examples
- 🛠️ CLI tool for client generation
- 📦 Monorepo management with Moonrepo
- Basic REST API
- Database integration (SQLx & Diesel)
- OpenAPI documentation
- React full-stack applications
- RPC modes demonstration
- Benchmark comparisons
Technical Details
- MSRV: Rust 1.75.0
- Runtime: Tokio (async)
- HTTP: Hyper 1.x
- Performance: Benchmark suite and comparison examples included
Initial Release - Complete type-safe web framework with automatic client generation and comprehensive testing.