Serialization

Pick the encoding for the environment, not for the interface.

Canopy generates the serialisation code for every format you ask for from the same IDL. The wire format is a property of the connection — not something baked into the interface — so the same service speaks binary to one peer and JSON to another.

Supported formats

YAS binary The high-performance C++-to-C++ path, with many scalar round-trips in the tens of nanoseconds. The default choice for throughput between C++ services.
YAS compressed binary The same binary encoding with compression — for large payloads or constrained links, trading CPU for bandwidth.
JSON Human-readable and inspectable. Used for debugging and generated configuration and MCP-oriented schemas; the current generated browser RPC client uses Protocol Buffers.
Protocol Buffers Schema-driven cross-language encoding, in two runtimes: the full Google C++ protobuf, and Nanopb for SGX enclaves and other small-runtime builds where the full runtime is too heavy.

The list is open, not fixed

The formats above are what Canopy supports today — not a ceiling. Because the wire format is decoupled from the interface (the IDL describes the types; a serializer decides how they become bytes), adding a new one means implementing encode and decode for the IDL types, with no change to any service. FlatBuffers, Thrift, CBOR, or a bespoke in-house format can be slotted in exactly the way YAS, Protocol Buffers, and Nanopb already are, then requested from CanopyGenerate like any other.

Chosen at build, selected at runtime

The CMake CanopyGenerate command lists the formats to generate from a single IDL source — request as many as you need and the generator emits the encode/decode code for each. At runtime a connection uses its owning service's default encoding, which you set with CANOPY_DEFAULT_ENCODING for the process or service->set_default_encoding(...) per service before creating new proxies.

CanopyGenerate(
  my_interface
  idl/my_interface.idl
  ...
  yas_binary
  yas_compressed_binary
  yas_json
  protocol_buffers)

Because every format comes from the same definition, there is no drift between them and no lock-in: move a deployment from binary to JSON for inspectability, or add a protobuf peer, without changing the interface or the implementation.