Library / SDK
mtrudel/bandit avatar
mtrudel/bandit

Bandit: The Pure Elixir HTTP Server Behind Phoenix

Bandit is a pure Elixir HTTP server for Plug & WebSock applications.

1,924 stars119 forksElixirMIT

At a glance

What is it?
Bandit is a pure Elixir HTTP server for Plug and WebSock applications, built entirely atop the Thousand Island TCP server library. It is the default HTTP adapter for Phoenix since version 1.7.11 and achieves 100% conformance on both the h2spec HTTP/2 test suite and the Autobahn WebSocket test suite in CI.
Who is it for?
Bandit is the appropriate HTTP server for any Phoenix application on Phoenix 1.7.11 or later, and the simplest way to adopt it is the two-line change to mix.exs and config/config.exs shown in the README. For standalone Plug applications, it requires no framework dependency at all.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly Elixir, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Bandit Is and Why It Exists

Bandit is an HTTP server written entirely in Elixir for Plug and WebSock applications. It supports HTTP/1.x, HTTP/2, and WebSocket clients over both HTTP and HTTPS, and it is built on top of Thousand Island, the author's companion TCP server library. The stated priority order for the project is correctness first, then clarity, then performance.

Before Bandit, the default HTTP server in the Elixir ecosystem for Phoenix and Plug applications was Cowboy, an Erlang library. Bandit was written as an alternative built from the ground up for the Plug interface, rather than adapted from a general-purpose HTTP server. The README states that this focus pays dividends in both performance and the approachability of the codebase.

Phoenix made Bandit its default HTTP adapter in release 1.7.11. Any Phoenix application on that version or later can switch to Bandit by adding two configuration lines. Applications on earlier Phoenix versions require Phoenix 1.7+ to use WebSocket features such as Channels or LiveView with Bandit.

The project is licensed under MIT and hosted at mtrudel/bandit on GitHub. Documentation is published on HexDocs at bandit.hexdocs.pm, and the package is available on Hex.pm.

Protocol Support and Conformance Testing

Bandit implements server-side HTTP/1.0, HTTP/1.x, HTTP/2, and WebSockets. The HTTP/1.x implementation follows RFC 9112 and RFC 9110. The HTTP/2 implementation follows RFC 9113 and RFC 9110. WebSocket support follows RFC 6455, with per-message compression defined in RFC 7692.

Conformance is verified automatically in CI. The HTTP/2 implementation scores 100% on the h2spec conformance suite in strict mode. The WebSocket implementation scores 100% on the Autobahn test suite. These are the same test suites used to verify correctness in other production HTTP server implementations. Scoring 100% in strict mode on h2spec indicates the server correctly handles all edge cases in the HTTP/2 specification, not just the common paths.

The HTTP content encoding compression for both HTTP/1.x and HTTP/2 supports gzip and deflate per RFC 9110, section 8.4.1.2 and 8.4.1.3.

In automated performance benchmarks run as part of CI, Bandit's HTTP/1.x engine is reported to be up to 4x faster than Cowboy depending on concurrency, and up to 1.5x faster on HTTP/2. These numbers come from the project's own ongoing automated benchmark workflow, not from an independent benchmark. The README attributes the performance gain to Bandit's design being purpose-built for Plug rather than adapted from a general HTTP server.

Adding Bandit to a Phoenix or Plug Application

For a Phoenix application, the README gives a two-step process. First, add the dependency to `mix.exs`:

elixir
{:bandit, "~> 1.8"}

Then add the `adapter:` line to the endpoint configuration in `config/config.exs`:

elixir
config :your_app, YourAppWeb.Endpoint,
  adapter: Bandit.PhoenixAdapter,
  url: [host: "localhost"],
  render_errors: ...

The README states that after this change, startup messages will confirm Phoenix is using Bandit. Existing endpoint configuration should work without changes in most cases. Applications with exotic configuration options may need to update those settings for compatibility with Bandit, and the BanditPhoenixAdapter documentation on HexDocs covers the details.

For a standalone Plug application, Bandit can be started directly in the application supervisor:

elixir
children = [
  {Bandit, plug: MyApp.MyPlug}
]

Or started directly for less formal usage:

elixir
Bandit.start_link(plug: MyPlug)

HTTPS requires configuring key and certificate data. The README provides a working HTTPS example that uses the `scheme: :https` option and passes key and certificate paths in the configuration.

Architecture: Thousand Island and the Plug Contract

Bandit's architecture has two visible layers. The lower layer is Thousand Island, which handles TCP and TLS connections, process supervision, and connection lifecycle management. Bandit sits above Thousand Island and implements the HTTP semantics on top of the connections Thousand Island provides.

The Plug API defines the contract between the HTTP server and the application code. Bandit implements this contract fully, which means any application written against the Plug interface works with Bandit without modification. The WebSock API, which defines the contract for WebSocket handling, is also fully implemented.

The README states a deliberate design goal: minimal internal policy and HTTP-level configuration. Bandit interprets requests only as far as necessary to manage the connection safely and fulfill protocol correctness requirements. Everything beyond that is delegated to the Plug or WebSock handler. This keeps the codebase small and the behavior predictable from the application's perspective.

The project emphasizes codebase approachability as a first-class goal alongside correctness and performance. The README states explicitly that Bandit exists to demystify lower layers of infrastructure code, in contrast to a trend of adding abstraction on top of abstraction.

Where Bandit Does Not Apply

Bandit serves Plug and WebSock applications in the Elixir ecosystem. It has no relevance outside Elixir. Developers using Erlang directly with Cowboy, or using Phoenix on a version before 1.7.11, will need to handle the upgrade path themselves before Bandit becomes available as the default.

The README notes that any Phoenix or Plug app should work with Bandit as a drop-in replacement for Cowboy, with exceptions treated as bugs to be reported. The caveat is the same one mentioned for the install steps: applications with exotic endpoint configuration may encounter compatibility issues that require adjustments.

Bandit is a server, not a client. It does not provide HTTP client functionality. Elixir applications that make outbound HTTP requests typically use Finch or Mint for that purpose, both of which are separate libraries.

The Cowboy alternative for the Elixir ecosystem is Plug-compatible and is the prior default for Phoenix. Cowboy is an Erlang library with a long production history and a different performance profile. The choice between them for new Phoenix applications on 1.7.11+ is largely settled by Phoenix's default.

Maintenance, CI, and License

The last push to the Bandit repository was on 2026-09-14. The repository has a comprehensive CI setup that includes unit tests, credo static analysis, dialyzer type checking, h2spec conformance runs, Autobahn conformance runs, and performance regression benchmarks. This combination makes the test suite more than a basic correctness check; it actively prevents performance regressions and specification drift.

The repository includes a CHANGELOG.md, a CODE_OF_CONDUCT.md, and a SECURITY.md. The project is listed on Hex.pm with version tracking. The HexDocs documentation is generated from the source and published automatically.

The license is MIT. The package is available from Hex.pm at `{:bandit, "~> 1.8"}` for the current stable release family.

Editorial conclusion

Bandit is the appropriate HTTP server for any Phoenix application on Phoenix 1.7.11 or later, and the simplest way to adopt it is the two-line change to mix.exs and config/config.exs shown in the README. For standalone Plug applications, it requires no framework dependency at all. The main case to check before switching from Cowboy is whether the existing application uses exotic endpoint configuration options that have no direct Bandit equivalent. The last push was on 2026-09-14.

Frequently asked questions

Is Bandit the default HTTP server for Phoenix applications?

Bandit became the default HTTP server adapter for Phoenix in Phoenix 1.7.11. New Phoenix applications on that version or later use Bandit by default unless the developer explicitly configures Cowboy.

How does Bandit compare to Cowboy in performance?

In automated performance benchmarks run in the Bandit CI, the HTTP/1.x engine is reported up to 4x faster than Cowboy and the HTTP/2 engine up to 1.5x faster, depending on concurrency. These benchmarks are part of the project's own CI suite.

Does Bandit pass the h2spec HTTP/2 conformance test suite?

Yes. The README states that Bandit's HTTP/2 implementation scores 100% on the h2spec suite in strict mode, and this test runs as part of the project's comprehensive CI suite on every push.

Official sources

  1. Official README
  2. Project repository