BareProxy Plugins Go WebAssembly, Starting With RenderCache and AI Crawler Control
BareProxy’s core stays bare. Everything else comes as plugins, and a plugin is now a WebAssembly module that BareProxy loads at run time. That replaces the earlier plan of modules compiled into the binary.
Three things change for anyone running it. A plugin is a .wasm file named in the config, so adding or upgrading one is a config change: plan shows it, apply makes it live, rollback takes it back. No rebuild, no restart. A plugin runs in a sandbox, with no files, sockets or processes unless the config grants them, so a broken one can’t take the server down. And a plugin can be written in anything that compiles to WebAssembly. Rust, Go, C++, Zig, AssemblyScript.
Two Choices Underneath
The runtime is wazero. It’s written in pure Go with no C underneath, so BareProxy is still one static binary on Linux, macOS and Windows.
The plugin interface is Proxy-Wasm, the one Envoy and Istio already use. Plugin authors get existing SDKs instead of an API only BareProxy has, and some plugins written for those proxies should run here with little change. BareProxy adds one thing of its own on top: a plugin can write a note into explain and into the request’s record. So when you ask BareProxy what happened to a request and why, the answer includes what every plugin did. Plugins don’t become a blind spot.
The Program
Twelve items, roughly in order of demand:
| Plugin | What it does |
|---|---|
| RenderCache | Prerendered HTML snapshots for search bots, AI crawlers and link previews |
| AI crawler control | Allow, block, rate-limit or charge each bot, with a log of who scrapes what |
| Auto TLS | Let’s Encrypt certificates out of the box (already in the core) |
| Rate limiting and basic WAF | Limits per address and path, simple bad-request rules |
| Auth gate | Password, OAuth or SSO in front of an app that has none |
| Response cache | Micro-caching for dynamic sites |
| Image optimizer | Resize and WebP/AVIF conversion on the fly |
| Analytics without JavaScript | Visit stats from the proxy’s own records, no cookies, no script |
| Maintenance and failover pages | A static page when the backend is down |
| Header and rewrite rules | Security headers, redirects, URL rewrites |
| Markdown serving | .md files rendered straight from the folder, no build step |
| Plan and explain | Already the core’s own; every plugin reports into it |
Bots First
The first two go together. AI crawler control decides whether a bot gets in, how often and on what terms. GPTBot, ClaudeBot, PerplexityBot and the rest, each one checked against its published address ranges, because a user agent is easy to fake. RenderCache decides what an admitted bot sees.
That second part matters more than it sounds. Most AI crawlers don’t run JavaScript. Point one at a single-page app and it reads an empty shell. RenderCache keeps fully rendered snapshots and hands those to bots, while people get the live app. The heavy work, a headless browser making the snapshots, runs as a separate worker next to BareProxy. The plugin itself only decides and serves.
Put together, BareProxy decides what bots see and on what terms.
What Comes First
The plugin host is first: the runtime, the Proxy-Wasm functions, the hook points, and plugins showing up in explain, plan and the history. Then AI crawler control, the smaller of the pair, which proves the host end to end. Then RenderCache.
The design note and the full program are in the code repository. The plugins page has the list, and the roadmap the order.