Skip to main content
A plug-in implements one function over bytes: given a chunk of a connection, return the statements it completes and the number of bytes it consumed. The SDKs wrap the ABI so you write that function in your language and get the exports, the allocator and the JSON for free. Start from hoophq/plugins: one worked example per language, each with the fixtures the conformance tool replays and a config that runs it. examples/resp (Redis, Rust), examples/memcache (memcached, Go) and examples/sqlframe (a binary framing over SQL, C++) cover every capability between them. The SDK source and the x-acmewire reference live in the Sidecar repository under sidecar/codec/wasm.

The contract in one paragraph

decode(dir, bytes) returns statements and a consumed count. An incomplete trailing message is not an error: return the statements before it and stop consumed at its first byte. The Sidecar keeps the rest and passes it again, prefixed to the next read. Malformed bytes are an error, and the Sidecar drops the connection. The Sidecar fills the protocol field itself; the module sets operation from the Sidecar’s vocabulary and puts its native verb under metadata["<protocol>.verb"]. Table and relation names are lowercased by the module. The policy compares them as they arrive.

Rust

Add the crate from crates.io and the wasm32 target:
Cargo.toml
Implement Codec, describe the module in a Manifest, and let the macro emit the exports for the capabilities you list:
src/lib.rs
frame returns Ok(None) on a partial header or payload, so consumed stops there. The capability list in export_codec! and manifest.capabilities must name the same set; describe traps when they differ, which the conformance tool reports as check 1. Build and test:
The optional methods (filter, rewrite, flush, take_credential, content, open) have defaults, so add one at a time and list its capability when you do.

Go (TinyGo)

Package codec is the module github.com/hoophq/hoop/sidecar/codec/wasm/sdk/tinygo; add it with go get github.com/hoophq/hoop/sidecar/codec/wasm/sdk/tinygo@v0.1.0. The tag carries the module path as a prefix because the module sits below the repository root. A plug-in implements codec.Codec, the capability interfaces it supports, and calls codec.Serve from init:
main.go
Each optional export sits behind a build tag, so the module’s exports and the manifest’s capabilities cannot disagree:
-target wasm-unknown is the freestanding target: no WASI, no scheduler, and main never runs, so Serve goes in init. The package also compiles with the standard Go toolchain, so go test exercises your decoder on the host.

C

hoop_codec.h is a single header: import declarations, an export macro, packed-return helpers and an optional arena allocator. It carries a skeleton you fill in. Fetch it from the hoophq/plugins repository, where each SDK release places it beside sdk/VERSION: curl -fsSLO https://raw.githubusercontent.com/hoophq/plugins/main/sdk/c/hoop_codec.h.
HOOP_EXPORT uses export_name, so you need no --export flags. A module calls only the imports it needs; the linker drops the rest.

Other languages

The ABI is a C ABI over linear memory with JSON payloads. Zig and AssemblyScript target it directly. JavaScript and Python work through an engine compiled into the module (Javy, componentize-py); such a module sets "wasi": true in its manifest and "instances": "per_lane", because one instance per connection costs megabytes each. See the ABI reference.

Fixtures

Fixtures are scripts the conformance tool replays: bytes in, expectations out. Keep them beside the module.
acmewire.fixtures.json
expect.statements compares only the fields it names. expect.error: true means decode must report an error on that step, and the script ends there.

Prove it

Checks 1 to 5 need no fixtures. Check 7 is the one that catches most decoders: the tool feeds each script one byte at a time through the Sidecar’s reassembly and requires the same statements as the whole replay. Check 8 interleaves two scripts on two connections and requires each connection to see only its own statements. The tool exits non-zero on any failure and names the step, so it runs in CI.

Ship it

One .wasm file runs on amd64 and arm64. Publish it with its sha256 and the fixtures, then hand operators a plugins entry:
The Sidecar verifies the digest before it compiles the module and refuses a mismatch at startup.

Next

ABI Reference

Every export and import, the manifest, the payloads and the failure rules.

Codec Plug-ins

Configure a lane and understand how a plug-in fails.