Overview

View Source

Livery is a BEAM-native web framework that serves one handler set over HTTP/1.1, HTTP/2, and HTTP/3 from a single service runtime, with WebSocket, WebTransport, Server-Sent Events, OpenAPI, MCP, and OpenTelemetry-style observability as built-in modules.

It is written in the spirit of Axum + Tower + Hyper on the BEAM.

When to use Livery

  • You are building a REST or GraphQL API and want HTTP/2 and HTTP/3 out of the box without composing several libraries.
  • You need browser-friendly streaming (SSE) or WebSocket on H1, H2, and H3 from the same handler.
  • You are building an agent or tool server and want MCP Streamable HTTP on the main listener, not a sidecar.
  • You already run Erlang/OTP and want to stop assembling a stack out of Cowboy plus a dozen adjunct libraries.
  • You have used Axum, Fastify, or FastAPI and expect the same ergonomics.

When not to use Livery

  • You only need a static file server. Cowboy or httpd is simpler.
  • You need a battle-tested 1.0 today. Livery is still under heavy rewrite; the H1/H2/H3 wire adapters land in Phases 2 to 4. Until then only the test adapter is wired.

Design principles

  1. Protocol neutrality. The handler does not know whether it is talking H1, H2, or H3. The request value is the same. The response value is the same. Capability flags surface where features differ.
  2. Race H3, fall back to H2, fall back to H1. One service runs all three on the same host. Alt-Svc advertises H3 so clients upgrade on the next request.
  3. Thin adapters. Each protocol adapter is a translator, not a state machine. Flow control, HPACK, QPACK, QUIC, TLS, framing all live upstream in the wire libraries.
  4. Axum + Tower ergonomics. Plain function handlers. Extractors for typed input. An ordered middleware stack with request and response transformation.
  5. Data, not processes. Requests and responses are immutable values. Middleware transforms values. Processes only exist where they earn their keep.
  6. Backpressure by default. Streaming bodies read on demand. A stalled client applies backpressure to the handler, not the other way around.
  7. Composable integrations. Auth, MCP, OpenAPI, WebTransport, instrumentation are modules in the same app, engaged only when the user mounts them. They share the adapter stack and middleware pipeline.
  8. No secret sauce on the wire. Anything visible on the network is the wire libraries' problem. If something is wrong at the frame or stream level, the fix lands there, not in Livery.

What is in the box

LayerModule(s)
Public facadelivery
Request valuelivery_req, livery_ext
Response builderslivery_resp
Routerlivery_router
Middlewarelivery_middleware, built-ins
Body readerlivery_body
Adapter behaviourlivery_adapter
In-memory driverlivery_test_adapter
Per-request workerlivery_req_proc, livery_req_sup

The wire adapters and service runtime are livery_h1, livery_h2, livery_h3, and livery_service; streaming, upgrades, shutdown, auth, OpenAPI, MCP, and observability are livery_ws, livery_wt, livery_drain, livery_auth*, livery_openapi*, livery_mcp, and livery_instrument_*. SSE and NDJSON are builders on livery_resp.

How Livery differs from Cowboy

CowboyLivery
HTTP versionsH1, H2H1, H2, H3
Wire layerin-treesibling libraries
Middleware shapecallback per handler familyone call(Req, Next, State)
Extractorsmanual cowboy_req:* threadinglivery_ext:json/1, query/2, etc.
Streamingcowboy_loop + info/3producer fun with Emit, free to receive
OpenAPIexternalbuilt-in
MCPsecond listenerfirst-class endpoint type
Alt-Svc upgradenot providedbuilt into livery_service

See Migrate from Cowboy for the full mapping table.