plugins

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.