Silgi
Protocols

Protocols

Silgi supports three wire formats — JSON, MessagePack, and devalue — plus WebSocket for persistent connections.

When a client sends a request, the server needs to agree on how to encode the data. Silgi handles this automatically through content negotiation — the client says what format it wants via the Accept header, and the server responds accordingly. No configuration needed.

The three formats

FormatPayload sizeRich typesBinaryBest for
JSONBaselineNoNoDefault, universal compatibility
MessagePack~30% smallerDate, Set, MapYesMobile apps, bandwidth-sensitive
devalue~Same as JSONDate, Map, Set, BigInt, RegExp, circular refsNoAPIs returning rich JavaScript types

JSON is the default. Every client and every tool understands it. If you don't configure anything, this is what you get.

MessagePack is a binary format. Same data, fewer bytes. If you're building a mobile app or sending large payloads, switching to MessagePack can noticeably reduce bandwidth and improve parse speed.

devalue preserves JavaScript types that JSON loses. If your API returns Date objects, Map, Set, or BigInt, devalue keeps them intact instead of converting them to strings or empty objects.

How content negotiation works

The client sends an Accept header, and the server picks the matching format:

Accept: application/json              --> JSON (default)
Accept: application/x-msgpack         --> MessagePack
Accept: application/x-devalue+json    --> devalue

For request bodies, the server checks Content-Type and decodes accordingly. This all happens inside Silgi — you don't need to configure anything on the server.

On the client side, setting binary: true in createLink switches to MessagePack automatically:

import {  } from 'silgi/client/ofetch'

const  = ({
  : 'http://localhost:3000',
  : true, // uses MessagePack for all requests
})

You can also use these formats over WebSocket. Pass binary: true to attachWebSocket for MessagePack over WebSocket.

Choose a format

Most applications work great with plain JSON. Consider switching when:

  • You need smaller payloads (mobile, IoT, high-traffic) --> MessagePack
  • Your API returns Date, Map, Set, or BigInt --> devalue
  • You want the lowest possible latency for repeated calls --> WebSocket

On this page