A JSON to Protocol Buffers generator that turns a representative JSON
sample into a ready-to-use .proto schema. Paste an object or an array and the
tool infers nested messages, repeated fields, scalar types and field
numbers, then lets you copy the result or download it as a .proto file for
protoc, buf, or any gRPC toolchain. It is built for backend and platform
engineers who have a payload but no schema yet, and who want a correct first
draft in seconds instead of hand-writing message definitions.
How it works
The generator parses your JSON, walks the value tree, and builds a set of
Protobuf message definitions. Type inference follows the Protobuf scalar model:
strings become string, booleans become bool, fractional numbers become
double, and whole numbers become int32 — automatically promoted to int64
when a value is too large for 32 bits (think Unix-millisecond timestamps or
snowflake IDs). Every nested object is hoisted into its own named message, and
arrays become repeated fields whose element type is inferred from the array
contents.
Arrays of objects get special treatment: rather than typing only the first
element, the tool merges every element so any key seen across the array
becomes a field. That means optional keys appearing in just one record are not
silently dropped. Mixed scalar arrays are widened to a safe common type
(numeric families collapse to the widest member; genuinely mixed types fall back
to string). Values that cannot be typed from the sample — null and empty
arrays — map to google.protobuf.Any, and the matching import line is added for
you. You control proto3 vs proto2, the package name, the root message name,
snake_case field naming, explicit scalar presence, and sample-value comments.
Your input and options are cached locally so the tool remembers your last
session, and nothing ever leaves the browser.
Example
Given this JSON:
{ "id": 42, "tags": ["dev"], "profile": { "city": "London" } }
the generator emits a Root message with an int32 id, a repeated string tags,
and a nested Profile message referenced as profile. The result is valid,
protoc-ready output you can paste straight into a .proto file:
| JSON value | Inferred Protobuf type |
|---|---|
"London" | string |
true | bool |
199.95 | double |
42 | int32 |
1280034512000 | int64 |
["dev", "math"] | repeated string |
{ "city": "London" } | nested message |
Every field number is assigned in key order starting at 1 — review them before production use, because renumbering a field is a breaking change on the wire.
Notes on correctness
Schema inference from a single sample is a best-effort first draft, not a
substitute for a designed contract. Use the largest, most complete sample you
have so optional fields are captured, replace any google.protobuf.Any
placeholders with concrete types, and confirm field numbers and optional
labels match your compatibility rules before committing the schema to a shared
repository.