jsontoolskit.org
JSON and JSON Schema utilities, in the browser
Say hi →

JSON ↔ MessagePack

encode · decode · hex, base64, byte array or the binary itself

MessagePack is JSON's shape without JSON's punctuation: the same objects, arrays, strings and numbers, written as bytes. Paste JSON to see exactly what it encodes to and how many bytes that saves, or paste the hex your service logged and read it back as JSON.

Paste JSON, or paste hex / base64 to decode.

How to use it

  1. Paste JSON. The output pane shows the encoded bytes and the status line compares them with the minified JSON.
  2. Pick the view you need — hex to paste into a test, base64 to put in a config or a header, byte array to paste into source code.
  3. Download writes the real binary as data.msgpack, not the hex view of it.
  4. Going the other way, switch Direction to decode and paste hex or base64 — it works out which one you gave it.

What it encodes to

Every JSON type has a direct MessagePack counterpart, and the encoder always picks the shortest representation the spec allows:

When it is not smaller

Often enough that it is worth checking rather than assuming. A short document can grow: a three-character string costs one prefix byte where JSON spends two quotes, but a 40-character string costs two prefix bytes and JSON still spends two quotes. A document dominated by long text barely moves, because the text is the same bytes either way. The saving comes from structure — many small objects, many small numbers, deep nesting — which is exactly the shape of the API payloads and telemetry that people reach for MessagePack for.

And compression changes the argument entirely. Gzip is very good at repeated key names, which is where MessagePack's advantage mostly lies, so gzipped JSON and gzipped MessagePack are usually much closer than the raw sizes suggest. The size analyser prints all of them side by side — raw, minified, gzipped, and the measured MessagePack — before you commit to changing a format.

Decoding

Paste hex (with or without 0x, spaces or commas) or base64. Everything the spec defines is understood, including the types JSON has no equivalent for:

If there are bytes left after the first complete value — which is what a stream of concatenated messages looks like — the status line says how many were ignored rather than pretending the input was one message.

FAQ

Is a library being loaded for this?

No. The codec is written out in the page's script, both directions. Nothing is fetched and nothing is uploaded, which also means it keeps working with the network off.

Is the encoding canonical?

It is deterministic — the same input always gives the same bytes, always in the shortest form the spec allows, with object keys in their original order. MessagePack itself defines no canonical form, so a different encoder may produce different (equally valid) bytes, most often by using a wider integer type than it needs. If you need a canonical form for hashing, RFC 8785 canonical JSON is the specified way to get one.

What about CBOR?

Not here. CBOR (RFC 8949) is a near relative with a different byte layout and its own tag registry; the two are not interchangeable, so a CBOR payload pasted into the decoder will either fail or produce nonsense.

Why does my object come back with keys in a different order?

It should not — the decoder preserves the order the bytes were in. What does change: a non-string map key, which MessagePack allows and JSON does not, comes back as the JSON text of that key so the document stays valid.