b2KIT

Protobuf to JSON Converter

Convert Protocol Buffer definitions to JSON representation and vice versa with field mapping.

Tested tool guide Tested browser tools Checked August 16, 2026

What Protobuf to JSON Converter does, with a checked example

This tool converts Protocol Buffer definitions into the JSON representation that protobuf-JSON APIs and gRPC gateways expect, and it converts JSON back into proto3 message definitions. It parses the .proto text, then applies the protobuf JSON mapping to each field: snake_case names become lowerCamelCase, 64-bit integers become strings, bytes become base64, enums become their value names. The surprise for most users is that this renaming is not the tool's choice; the specification mandates it, so order_id legitimately appears as orderId in the output.

Worked example

A concrete input and expected output from the current implementation.

Input

syntax = "proto3";

message Book {
  string title = 1;
  string author_name = 2;
  int64 isbn = 3;
  repeated string tags = 4;
}

Expected output

{
  "title": "",
  "authorName": "",
  "isbn": "0",
  "tags": []
}

author_name becomes authorName because the JSON mapping names fields in lowerCamelCase, and isbn is an int64, which the mapping requires to be a string. The values shown are defaults; a real serialized message would omit empty string, empty array, and zero-valued fields entirely.

How the result is produced

1

Field name mapping

Every field gets a JSON name: the lowerCamelCase form of the proto field name by default, or the explicit json_name option when the .proto declares one. In the JSON-to-proto direction the tool accepts both the camelCase name and the original proto name, matching how protoc-generated code parses JSON.

2

Type mapping

int32, uint32, and other 32-bit integers stay JSON numbers; int64, uint64, sint64, fixed64, and sfixed64 become strings; float and double become numbers, with NaN, Infinity, and -Infinity encoded as strings; bytes become base64; enums become their value names; repeated fields become arrays; map fields become objects; nested messages become nested objects. Going from JSON back to proto, the tool infers types from values, which forces guesses such as int32 versus double for a plain number.

Good uses

  • Drafting the JSON payload an existing .proto service will accept: paste the message definition and copy the camelCase field names and string-form 64-bit values straight into a curl command or frontend code.
  • Starting a schema from a JSON sample captured from an old REST API or a log file: the reverse direction produces a proto3 message you then tighten by hand, since inferred types are provisional.
  • Debugging a rejected protobuf-JSON request: compare the payload against the mapped representation to spot the wrong field name (user_id instead of userId) or an int64 sent as a number instead of a string.

Limits and checks

  • The JSON-to-proto direction is lossy. A JSON number could be int32, uint32, float, or double; a string could be a string, an enum name, bytes, or a 64-bit integer. The generated definition is a starting guess, not a reversible transformation, and needs review before it describes your data.
  • Proto3 serialization omits fields holding default values: empty string, zero, false, and empty arrays are dropped from emitted JSON. What the tool shows for a message is the field shape; the bytes actually transmitted for an empty message are an empty object.
  • JSON carries no field numbers, so a round trip does not reproduce the original .proto: field ordering and numbers can change, and enums appear as names even though the wire format stores their numbers. Treat the output as a new schema, not a mirror of the input.

Common questions

Why is my int64 field rendered as a string in the JSON?

Because JSON numbers are IEEE-754 doubles and cannot represent every 64-bit integer exactly, the protobuf JSON mapping specification requires 64-bit integer types to be encoded as strings while 32-bit types stay numbers. Any conforming serializer does the same; there is no option to turn it off.

Can I keep my snake_case field names in the JSON output?

Only by declaring an explicit name in the proto: the spec sets the JSON name to the lowerCamelCase form unless the field carries a json_name option, which overrides it. Add json_name = "order_id" to the field and the JSON key becomes order_id. Without that option, no conforming tool keeps the underscore form.

References and verification

The example and behavioral notes were checked against the browser implementation. Standards and primary references below define the relevant format, formula, or platform behavior.

Related Tools