// the find
ninenines/cowboy
Small, fast, modern HTTP server for Erlang/OTP.
Cowboy is a production-grade HTTP server for Erlang/OTP, sitting at the core of many Elixir/Phoenix and pure Erlang stacks. It handles HTTP/1.1, HTTP/2, HTTP/3 (via QUIC), WebSockets, and WebTransport from a single library. If you're running Erlang in production and need an HTTP server, this is the default answer.
1. Protocol breadth is real and well-maintained — HTTP/3 and WebTransport support are not checkbox features; cowboy_http3.erl and cowboy_webtransport.erl are first-class modules actively updated as recently as yesterday. 2. The REST handler (cowboy_rest) implements the full HTTP decision tree with proper content negotiation, ETags, conditional requests, and range support — not a simplified approximation. The flowchart docs are genuinely useful for understanding HTTP semantics. 3. Stream handlers (cowboy_stream) give you a composable middleware chain at the protocol level, which is architecturally cleaner than most HTTP frameworks' middleware bolted onto routing. 4. Documentation is thorough and versioned — migration guides exist for every minor release from 2.0 to 2.16, which matters when you're upgrading a production system.
1. Erlang-only — if your team isn't already in the BEAM ecosystem, adopting Cowboy means adopting Erlang, not just a library. Elixir users get this via Phoenix/Plug, but there's no escape hatch for other languages. 2. HTTP/3 depends on the quicer NIF (Erlang bindings to msquic), which adds a native dependency and complicates deployment in environments that restrict compiled extensions or need static linking. 3. No built-in JSON handling, authentication, or session management — you're assembling those from separate libraries, which is philosophically correct for Erlang but means more integration work compared to batteries-included frameworks. 4. The build system uses erlang.mk, a large auto-generated Makefile that many teams find opaque and hard to debug when something goes wrong; rebar3 support exists but feels secondary.