Run Plug and Phoenix apps on Roadrunner, the pure-Erlang HTTP/1.1, HTTP/2, HTTP/3 and WebSocket server.
Requirements
Requires OTP 27+ and Elixir 1.18+.
🚧 Status
Roadrunner.Plug is in 0.x. The core is functional and covered by tests,
but the API may change between minor versions. Pin an exact version in your
deps if you need stability across upgrades.
Installation
Add roadrunner_plug to your deps in mix.exs (latest version on
Hex):
def deps do
[
{:roadrunner_plug, ">= 0.0.0"}
]
endPlug
Add the listener to your supervision tree:
children = [
{Roadrunner.Plug, plug: MyApp.Router, port: 4000}
]See Roadrunner.Plug for the options: :port, :ip, :scheme and TLS,
and :roadrunner for any Roadrunner listener option.
Phoenix
Set the endpoint's adapter:
# config/config.exs
config :my_app, MyAppWeb.Endpoint,
adapter: Roadrunner.PhoenixAdapter,
url: [host: "localhost"]The :http and :https settings work as in a generated Phoenix app.
What works
- Responses: complete, chunked, files and
103 Early Hints - Request bodies read on demand, so
Plug.Parserssets the limits get_peer_data/1(with the client's TLS certificate),get_sock_data/1,get_ssl_data/1andget_http_protocol/1- WebSocket upgrades through
Plug.Conn.upgrade_adapter/3with aWebSockhandler, over HTTP/1.1 - Phoenix endpoints, including the code reloader
Phoenix Channels and LiveView reach WebSockets through WebSockAdapter,
which only knows the servers it lists, so they need Roadrunner to be added
there first.
Sponsors
Roadrunner.Plug is open source and maintained on personal time. If you or your company find it useful, consider sponsoring.
I also accept coffees ☕
License
Copyright (c) 2026 William Fank Thomé
Roadrunner.Plug is open-source under the Apache 2.0 License on GitHub.
See LICENSE.md for more information.
