# rama: a network framework where you compose the stack yourself

> rama is an Apache-2.0 and MIT dual licensed Rust framework for building network clients, servers and proxies, with the deliberate constraint that the stack is built from services, layers, transports, protocols and state that you compose. The MITM proxy support is one capability among ten proxy types rather than the point of the project.

**plabayo/rama** — modular service framework to move and transform network packets

- Repository: https://github.com/plabayo/rama
- Website: https://ramaproxy.org
- Stars: 1,258 · Forks: 113
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/plabayo-rama

## Explicit stacks, on purpose

rama is a modular service framework for the Rust language that provides a cohesive foundation for building network clients, servers, proxies and combinations thereof, and its central design statement is that the framework is intentionally explicit.

Your network stack is built from services, layers, transports, protocols and state that you compose yourself. The stated consequence is that the shape of the system becomes visible in the code, instead of hidden behind framework magic or configuration.

That is a strong position to take in a networking library, and it is the opposite of what a lot of Rust web frameworks do. The reasoning is that Rama is a good fit not only for proxies but for network services where the stack itself matters: how traffic enters, how it is decoded, where state lives, what gets inspected, what gets transformed, and where it goes next. The listed use cases are inspecting traffic for security analysis, writing a web service, emulating clients with custom user agents, controlling connection behavior for advanced testing, and building high-performance proxies.

The framework is described as a clean and composable Tokio-native foundation for network services in Rust, and the Tokio-native part is what makes the composition practical rather than theoretical.

The project is developed and maintained by Plabayo, a European software studio based in Gent, Belgium, focused on building resilient, interoperable and secure digital infrastructure. Rama is stated to be used in production for network security, data extraction, API gateways, routing and other networked systems, and commercial support and partner offerings are available separately.

## Ten kinds of proxy come out of the same composition

The capability table in the README lists the proxy types the framework supports, and the list is the clearest evidence that this is a general network stack rather than a proxy tool.

There are reverse proxies, TLS termination proxies, HTTP(S) proxies, SOCKS5 proxies, SNI proxies, MITM proxies, transparent proxies, distortion proxies, network proxies, and HAProxy PROXY protocol support.

Read as a set, that list covers the layers where a proxy can intervene. SNI proxies work at the TLS handshake, before any payload is decrypted, and route by the requested name. TLS termination proxies decrypt at the edge. HTTP proxies work on the HTTP layer. MITM proxies sit between the client and the origin and can see the plaintext. Transparent proxies intercept without the client knowing, typically at the network layer. Distortion proxies deliberately alter traffic. And the HAProxy PROXY protocol support means the framework speaks the de facto standard for carrying the original client address through a chain of proxies.

The interesting consequence is that an MITM proxy and an SNI proxy are not different products, they are different arrangements of the same primitives. A stack that decrypts, inspects and re-encrypts differs from one that inspects the handshake only by which layers you compose. For a team that needs both a filtering proxy and a monitoring proxy in the same codebase, that is the argument for the framework rather than for two separate tools.

The MITM capability here is a legitimate network engineering feature. Interception and re-encryption is what a corporate egress gateway, a debugging tool or a test harness does, and the same project ships ten other proxy types alongside it.

## The crate split is the architecture

The repository listing is long, and it is not a list of examples. It is a list of crates, one per protocol or concern.

There is rama-core/, rama-error/, rama-macros/, rama-net/ and rama-fp/, the last being a functional programming layer, plus rama-crypto/, rama-dns/, rama-pac/ for proxy auto configuration, rama-json/ and rama-js/. Then the protocol crates: rama-http/, rama-http-core/, rama-http-headers/, rama-http-types/, rama-http-backend/, rama-http-hyperium/ for the Hyper integration, rama-http-macros/, rama-grpc/ with rama-grpc-build/ and rama-grpc-macros/, rama-quic/ and rama-quic-proto/, rama-socks5/, rama-haproxy/, rama-fastcgi/ and rama-icap/ for the ICAP protocol used by content filtering appliances.

And then the layers that make the composition idea concrete: rama-proxy/, rama-inspect/, rama-pac/ and rama-net/.

There are also platform-specific crates, rama-net-apple-networkextension/ and rama-net-apple-xpc/, which is how a macOS system extension integrates with the framework, an ffi/ directory for the Swift Package integration, and a Package.swift at the root. The presence of the Swift package alongside the Rust crates is unusual and worth noting, since it means the framework is meant to be embedded in a macOS application that is partly Swift.

The Cargo.toml confirms the workspace is enormous, with dozens of members listed and the top level package named rama, version taken from the workspace, and rust-version from the workspace too. The resolver is set to 3, and the docs.rs metadata enables all features but restricts the build to x86_64-unknown-linux-gnu because the native C dependencies cannot cross-compile in the docs.rs builder.

The practical consequence for a consumer is that dependency selection is per protocol. You take rama-http/ if you need HTTP, rama-grpc/ if you need gRPC, rama-socks5/ if you need SOCKS5, and you do not pay for the rest.

## The book, the examples, and the three ways to learn it

The README's start-here table is unusually well organised for a project of this size, and it splits learning into three modes.

The first is reading. The book explains the ideas, the examples show working stacks, and the Rust docs are the API reference. The book has a Why Rama chapter for the motivation, an Intro to Rama for the core model, and then specific chapters for proxies, operating proxies, web servers, HTTP clients and the rama CLI. There is a Rama 101 blog series and a collection of Rama articles, and a Netstack.FM podcast with episodes on building and testing network stacks with Rama, MITM proxies and transparent L4 interception, the dial9 crate, and gRPC.

The second is running code. The examples directory is a standalone crate in the workspace, with its own Cargo.toml, build.rs, proto/ and grpc/ subdirectories and tests/, and the README links specific example files such as http_high_level_client.rs.

The third is looking things up, with docs.rs and an edge docs site at ramaproxy.org/docs/rama.

That structure tells you something about the maturity of the project. A framework this composable has a learning cost, and the maintainer is treating that as a first-class problem rather than leaving it to the API docs. It also means the examples are part of the documentation, so they are held to a higher standard than usual example code.

## How the build is set up, and the flags that matter

The justfile at the repository root is where the day-to-day development workflow lives, and it contains a few decisions worth understanding.

Warnings are errors by default. The RUSTFLAGS export adds -D warnings unless ALLOW_WARNINGS=true is set, and the comment explains why it is an export rather than a .cargo/config.toml entry, because justfile's export of RUSTFLAGS overrides cargo's config either way. So the same setting applies whether you run just or cargo.

There is a separate export for rustdoc, RUSTDOCFLAGS, and the comment explains the reason: it mirrors CI's doc job, where rustdoc warnings such as private intra-doc links fail locally too, unless ALLOW_WARNINGS=true. Rustdoc reads RUSTDOCFLAGS and not RUSTFLAGS, so it needs its own export. That is a small but real trap, and the file documents it.

There is a third export, RAMA_DEV_DENY_C_WARNINGS, which mirrors the same flag for the C dependencies, since a native C dependency can emit warnings that would fail a build configured to deny them.

A separate switch, TOKIO_UNSTABLE=true, adds --cfg tokio_unstable, which widens dial9's task coverage, the crate that provides the black-box testing of network stacks. That crate and the Netstack.FM episode on dial9, from black box to insight in Tokio, are the clearest sign of how seriously the project takes testing a network stack where the failure modes are timing dependent.

The tool installation is handled by a recipe that probes for a missing tool and installs it, with separate implementations for Unix and Windows because Windows PowerShell has neither command nor the or operator, as the comment says.

The repository also has benches/ for benchmarks, fuzz/ for fuzzing, a Cross.toml for cross-compilation, a .taplo.toml for formatting TOML, a deny.toml for dependency auditing, a lychee.toml for link checking, and a _typos.toml for the typo checker.

## Where rama is the wrong choice

The first limit is that the framework does less for you than its counterparts. If you want a web service with routing, middleware, body extraction and a serialiser already wired, you are assembling that from rama-http crates yourself. A team whose members are new to Rust networking will spend their first weeks composing layers rather than shipping endpoints, and that is the cost of the explicit design.

The second is the scale of the dependency surface. A workspace with dozens of crates, a proxy protocol list that includes QUIC, ICAP, FastCGI, gRPC, SOCKS5, HAProxy PROXY protocol and PAC files is a lot of code to audit, and the workspace inheritance of version, edition, rust-version and licence means you do not get to choose your own versions of anything. That is a reasonable choice for a maintained framework and a poor one for a team with strict supply-chain requirements.

The third is the release trajectory. The versions listed are rama-0.4.0 from 2026-08-19, rama-0.3.0 from 2026-07-07, and rama-0.3.0-rc.1 from 2026-07-04, so the 0.x line means the API is explicitly not stable, and the presence of a release candidate a fortnight before the final release shows how quickly things move. The last push was on 2026-10-15, so the work is current, but a 0.4 version of a framework this ambitious is a moving target for production use.

The fourth is the commercial angle. The project is maintained by a software studio that sells commercial support and partner offerings, and the framework is used in production for network security, data extraction and API gateways. That is not a problem, but a team that expects a community-driven open source project with a slow and predictable API may find the release pace and the commercial emphasis surprising.

## Conclusion

rama is a good pick for a team building a proxy, a scraper, an API gateway or a custom client where the shape of the network stack is itself a design decision, because the crate split lets you depend on only the protocols you need and the composable layers make an intercepting proxy a stack rather than a fork; it is the wrong pick if you want a batteries-included web framework with routing and middleware already wired, since you assemble that yourself, and before you commit you should check which crate covers your transport, because the protocol crates are separate and versioned independently of the top level rama crate.

## FAQ

### What is rama and what is its core design idea?

It is a modular service framework for the Rust language for building network clients, servers and proxies. The framework is intentionally explicit: your network stack is built from services, layers, transports, protocols and state that you compose yourself, so the shape of the system is visible in the code rather than hidden behind framework magic.

### Which proxy types does rama support?

The capability table lists reverse proxies, TLS termination proxies, HTTP(S) proxies, SOCKS5 proxies, SNI proxies, MITM proxies, transparent proxies, distortion proxies, network proxies and HAProxy PROXY protocol support, all built from the same composable primitives.

### How is the rama project structured?

As a Cargo workspace of separate crates per protocol or concern, including rama-core, rama-net, rama-http and its core, headers, types, backend and hyperium variants, rama-grpc with build and macros crates, rama-quic, rama-socks5, rama-haproxy, rama-fastcgi, rama-icap, rama-proxy and rama-inspect, plus platform-specific rama-net-apple-networkextension and rama-net-apple-xpc crates and an ffi directory for the Swift package.

### How do I build and test rama?

The justfile is the entry point. It exports RUSTFLAGS with -D warnings unless ALLOW_WARNINGS=true, exports RUSTDOCFLAGS separately because rustdoc does not read RUSTFLAGS, and a TOKIO_UNSTABLE=true switch adds --cfg tokio_unstable to widen dial9 task coverage. Tools are installed on demand by a recipe with separate Unix and Windows implementations.

### What licence is rama released under?

Dual licensed, with both an MIT and an Apache 2.0 licence file in the repository root. The most recent releases are rama-0.4.0 from 2026-08-19 and rama-0.3.0 from 2026-07-07, and the last push was on 2026-10-15.

## Sources

- [License: Apache-2.0](https://github.com/plabayo/rama/blob/main/LICENSE)
- [plabayo/rama on GitHub](https://github.com/plabayo/rama)
- [Project website](https://ramaproxy.org)
- [README](https://github.com/plabayo/rama/blob/main/README.md)
- [Releases](https://github.com/plabayo/rama/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/plabayo-rama
