proxy-wasm Rust SDK: writing proxy filters in Rust and WebAssembly
WebAssembly for Proxies (Rust SDK)
At a glance
- What is it?
- The proxy-wasm Rust SDK is an Apache-2.0 crate that lets you write proxy filters in Rust and compile them to WebAssembly modules, with examples covering HTTP, gRPC and TCP. It is a thin layer over a host ABI rather than a framework, and the manifest version sits ahead of the published 0.2 releases.
- Who is it for?
- The proxy-wasm Rust SDK suits a team that wants to extend a proxy with custom HTTP, gRPC or TCP logic in Rust rather than in the proxy's native language, and that accepts shipping a WebAssembly module alongside its proxy configuration.
- Can I use it commercially?
- Yes. Apache-2.0 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 65 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A crate over a host ABI, not a framework
The proxy-wasm Rust SDK is the Rust implementation of the proxy-wasm idea: writing proxy logic in WebAssembly, so the same module can be loaded by different proxy implementations rather than being compiled into one of them. The repository is small in the way a good SDK is small, and the packaging metadata says what it is:
[package]
name = "proxy-wasm"
version = "0.3.0-dev"
authors = ["Piotr Sikora <[email protected]>"]
rust-version = "1.85"
description = "WebAssembly for Proxies"
readme = "README.md"
license = "Apache-2.0"
edition = "2024"
build = "build.rs"Three things in that block matter. The crate is published on crates.io under the name `proxy-wasm`, without the `proxy-wasm-rust-sdk` suffix the repository carries, so a dependency line and a repository URL do not look alike. The Rust edition is 2024 and the minimum Rust version is 1.85, which sets the floor for the toolchain in a build. And there is a `build.rs`, a build script, which is the standard way a crate that compiles to WebAssembly handles the target-specific setup.
What the SDK is not is a framework. There is no configuration layer, no plugin registry and no deployment tooling here. The repository holds `src/`, a `build.rs`, the examples and the build files. The work of shipping the module and wiring it into a proxy configuration happens outside this repository, which is why the README is mostly a list of examples and links to the community articles and to the contributing and development guides.
The licence is Apache-2.0, with the copyright header in the manifest naming Google LLC, and the documentation is published on docs.rs under the same crate name.
Eight examples that map the extension points
The example list is the most useful documentation in the repository, because it is organised by the extension point rather than by feature. There are eight of them.
Four are HTTP: a Hello World, HTTP Auth with a random response, HTTP Headers, HTTP Response body, and HTTP Configuration. The auth example is a pattern many teams need first, since injecting an authorisation check into every request is the classic first proxy extension. The headers and body examples cover the two places where a filter can read or rewrite a message, and the configuration example shows how a filter takes parameters from the proxy configuration rather than hard-coding them.
One is gRPC, again an auth example with a random response. The presence of a gRPC example tells you the SDK covers more than HTTP, which matters because gRPC has its own metadata and status model rather than being HTTP with different framing.
The remaining two are Envoy specific. Envoy filter metadata covers reading and writing the dynamic metadata that Envoy attaches to a request, which is how a filter passes structured information to the next one in the chain. Envoy TCP Routing covers working at the TCP level, where there is no HTTP path to hook. That last one is the harder case and the better test of whether the SDK is enough for your problem, since TCP filtering works on byte streams rather than on structured requests.
A reader picking a starting point should read the example closest to the problem rather than the simplest one. The Hello World exists to show the build and load path, and the TCP routing example shows what the SDK looks like when there is no HTTP involved at all.
Bazel and Cargo in the same tree
The repository carries two build systems, and the file list explains why. There is a `Cargo.toml` for the crate itself, and then a full Bazel setup: `BUILD`, `WORKSPACE`, `WORKSPACE.bzlmod`, `MODULE.bazel` with a `MODULE.bazel.lock`, a `.bazelrc`, a pinned `.bazelversion`, a `bazel/` directory and a `.bcr/` directory.
Bazel is not incidental here. The examples are standalone modules that have to be built to WebAssembly and loaded into a proxy, and a monorepo build system is a reasonable way to build several of them consistently and to publish them. The `.bcr/` directory is the layout used by the Bazel Central Registry, which is how Rust crates get published for Bazel users, and `.actrc` is a configuration file for act, a tool that runs GitHub Actions workflows locally.
The `src/` directory holds the SDK code, `build.rs` is the crate's build script, and `examples/` contains the eight example directories. `CODEOWNERS`, `CHANGELOG.md`, `CONTRIBUTING.md` and `DEVELOPMENT.md` complete a conventional open source layout, and the README points at the contributing and development files for anyone changing the SDK itself.
The practical consequence for a user is that you can use Cargo alone. The Bazel machinery is what the project uses for itself and for the examples, and it is not a requirement on someone who just wants to depend on the crate from an application.
A no_std shaped dependency list and an aborting release profile
The dependency list is three entries long, which is a strong signal about the environment the compiled module runs in:
[dependencies]
hashbrown = "0.17"
log = "0.4"
mockalloc = { version = "0.1", optional = true }`hashbrown` is a hash map implementation that does not depend on the standard library's allocator, and `mockalloc` is an optional crate that provides a trivial allocator for programs that must not touch the host allocator. There is no `std` dependency listed and no serde, no async runtime and no HTTP client. A WebAssembly module that a proxy loads into its own process has a restricted environment, and a dependency list of this size is what respecting that looks like.
The release profile confirms the intent:
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"Link time optimisation, a single codegen unit and maximum optimisation are the usual settings for a size and speed sensitive artefact, and `panic = "abort"` means a panic in the filter aborts the module rather than unwinding, which is the right choice when the host has no unwinder to catch it. The test and bench profiles inherit from release and re-enable debug information, so profiling a filter still gives you symbols.
The `log` dependency is the logging facade, and it is the only channel a filter has for telling the operator what it is doing, since a module cannot write to the host's standard output. That single detail is often what decides whether a proxy filter is debuggable in production.
A 0.3.0-dev manifest sitting on top of published 0.2 releases
The version numbers deserve a careful look, because they tell you how to depend on this crate.
The manifest in the repository declares `version = "0.3.0-dev"`, which is a development version. The published releases are v0.2.5 on 2026-05-20, v0.2.4 on 2025-10-01 and v0.2.3 on 2025-06-04. So the main branch is already working towards 0.3, while the newest artefact on crates.io is 0.2.5.
For a user this means the choice is between a published 0.2.x release and whatever is on the main branch. The `-dev` suffix is the Rust convention for a version that is not intended to be published as is, and it signals that the API between 0.2 and 0.3 may not be identical. Anyone planning to depend on the crate should pin a crates.io version and read `CHANGELOG.md` in the repository before moving, rather than tracking the branch and discovering the breaking change in a build log.
The licence deserves a similar look. The manifest records Apache-2.0 and the README carries an Apache 2.0 badge pointing at the `LICENSE` file, which is permissive and includes an explicit patent grant, so embedding a module built with this SDK in a commercial product is straightforward from a licensing point of view. The Apache-2.0 terms are what apply, and that is a statement about the licence text rather than advice on your obligations.
On upkeep, the repository is not archived and the last push was on 2026-08-19, with a release about two months before that. The gap between the last push and the last release is normal for a project whose main branch sits on a development version.
When a Rust WebAssembly filter is the wrong choice
There is a case where this SDK is the wrong tool, and it is worth naming before anyone spends a week on it.
The first is when the filter has to be as fast as a native filter. A WebAssembly module is loaded and executed by the host proxy, and the host has to cross the module boundary on every call. The SDK's own release profile is tuned for size and speed, which tells you the team cares about that cost, but no amount of tuning removes the boundary itself. A filter that sits in the hot path of every request and does heavy work is a better candidate for the proxy's native filter API, where the code is compiled into the proxy and there is no boundary to cross. The trade is the one the WebAssembly approach exists to solve: native filters are tied to one proxy and one language, while a module is portable and sandboxed.
The second is when the team does not want Rust. The SDK is the Rust route into the WebAssembly proxy filter model, so a team whose proxy filters are written in another language has to bring its own toolchain or use a different approach entirely. The examples in the repository are the scope of what this SDK supports, HTTP, gRPC and TCP, and a filter that needs something outside that set is going to hit limits.
The third is a project that needs a guaranteed supported release. The published version is 0.2.5 and the branch is a development version, so there is no stability commitment to lean on.
For everything else, a filter that needs to be deployed independently of the proxy's release cycle, written by a team that prefers Rust, and updated without rebuilding the proxy, is exactly the case this SDK serves.
Editorial conclusion
The proxy-wasm Rust SDK suits a team that wants to extend a proxy with custom HTTP, gRPC or TCP logic in Rust rather than in the proxy's native language, and that accepts shipping a WebAssembly module alongside its proxy configuration. It does not suit a team that needs the lowest possible per-request overhead and would rather build a native filter into the proxy, and it does not suit a project that needs a stable published version today, because the manifest carries 0.3.0-dev while the newest published release is v0.2.5 from 2026-05-20. Before starting, read DEVELOPMENT.md and CONTRIBUTING.md, and pin the crates.io version you build against rather than the branch.
Frequently asked questions
What is the proxy-wasm Rust SDK and what is it for?
It is the Rust implementation of WebAssembly for Proxies, published on crates.io as `proxy-wasm`. It lets you write proxy filter logic in Rust and compile it to a WebAssembly module that a proxy loads, instead of writing a filter in the proxy's own native language.
Which kinds of proxy filters does the proxy-wasm Rust SDK cover?
The bundled examples cover HTTP, with Hello World, random HTTP auth, header manipulation, response body handling and configuration, plus gRPC auth, Envoy filter metadata and Envoy TCP routing. The TCP example is the one to look at when there is no HTTP path to hook.
Which version of the proxy-wasm crate should I depend on?
The newest published release is v0.2.5 from 2026-05-20, while the repository manifest declares `0.3.0-dev`, so the main branch is ahead of what is on crates.io. Pin a published version and read the CHANGELOG before moving between them.
What Rust version and toolchain does the proxy-wasm Rust SDK need?
The manifest sets `rust-version = "1.85"` and `edition = "2024"`. The crate also has a `build.rs` build script, and the repository keeps both Cargo and a full Bazel setup with a pinned `.bazelversion`.
What licence is the proxy-wasm Rust SDK released under?
Apache-2.0, recorded in the manifest and shown by the README badge that points at the LICENSE file. The copyright header in the manifest names Google LLC.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/proxy-wasm-proxy-wasm-rust-sdk)Was this useful?