One handler set. Every version of HTTP.
A BEAM-native web framework that serves the same router and middleware over HTTP/1.1, HTTP/2, and HTTP/3 from a single runtime. Axum + Tower + Hyper ergonomics, on Erlang/OTP.
{livery, {git, "https://github.com/benoitc/livery.git", {branch, "main"}}}
One start_service/1 call brings up H3 on UDP, H2 on TLS, and
H1 on TCP, sharing the router and middleware, with Alt-Svc upgrade.
%% one router, served over every protocol Router = livery_router:compile([ {<<"GET">>, <<"/">>, fun(_Req) -> livery_resp:text(200, <<"hello from livery">>) end}, {<<"GET">>, <<"/users/:id">>, {users, show}} ]), livery:start_service(#{ http => #{port => 80, redirect => https}, https => #{port => 443, cert => Cert, key => Key, alpn => [h2, http1]}, http3 => #{port => 443, cert => Cert, key => Key}, router => Router, middleware => [{livery_request_id, undefined}, {livery_access_log, #{}}], alt_svc => advertise }).
The things you would otherwise assemble from a dozen libraries, in one place.
Write a handler once; it serves over H1, H2, and H3. The wire layer lives in sibling libraries; adapters stay thin.
Value-based call(Req, Next, State) pipelines, composable per service or per route. No mutate-and-next.
Chunked responses, Server-Sent Events, NDJSON, WebSocket and WebTransport over H2/H3, plus file streaming with ranges.
Generate an OpenAPI 3.1 doc from your routes, serve Redoc or Swagger UI, and reject bad bodies with a JSON-Schema validator.
Serve the Model Context Protocol Streamable HTTP transport on your main listener with one handler. No sidecar.
OpenTelemetry-style traces and metrics, trace-correlated logs, JWT/JWKS/OIDC, signed sessions, and token introspection.