How to turn a JSON sample into Go types

Paste a JSON sample and the tool writes the Go type declarations that fit it: structs, slices, scalar fields and the json tags that tie every field back to its key. Names follow Go conventions, nested objects can stay inline or become named types, and identical shapes are declared once.

The conversion runs in this browser tab. Nothing is uploaded and no request is made, so the page keeps working offline and can be used with payloads you are not allowed to send to a third party.

  1. Paste or type the JSON you want to model. The result updates as you edit, so trim the payload until the generated types look right.
  2. Leave Inline nested types checked for anonymous structs inside the parent, or uncheck it to get separate named types after the main declaration.
  3. If the JSON is malformed, the message names the position and the offending character is marked; fix the input and the types return.
  4. Press Copy Go struct to take the code and Clear to reset both panes. Add the import block yourself: the output is only the type declarations.

How the types are inferred, and what the output leaves out

How types are inferred from one sample

Whole numbers become int when they fit in 32 bits and int64 when they do not; decimals become float64. A number written as 1.0 stays float64 even though it looks whole, and an array that mixes whole and decimal numbers becomes []float64. An array that mixes values which cannot share a type — a number and a string, an object and a number — falls back to []interface{}.

An array of objects is merged into one struct with the union of its keys, and a key missing from some items is tagged with omitempty. A field that is an object in one item and a scalar in another becomes interface{}. Strings shaped like an RFC 3339 timestamp (2024-05-06T07:08:09Z) become time.Time, which needs the time import added by hand.

Names, tags and optional fields

Field names are exported Go names: user-id becomes UserID, and common initialisms such as ID, URL, API and HTTP keep their capitals. The original key is preserved in the struct tag, so the generated code still matches the payload you pasted.

Two keys that reduce to the same Go name get a numeric suffix (UserID and UserID2), and keys made only of symbols become Field, Field2 and so on. Quotes and backslashes inside a key are escaped in the tag, so the emitted code stays valid.

What the output is not

These are declarations only: no package clause, no imports, no methods, and nothing is compiled here. The types describe the sample you pasted, not a schema — a field that is null or absent in that sample is typed from what you provided, so check nullability and numeric widths against a larger payload.

Large documents are still parsed in the browser and limited by the memory of your device. Treat the result as a reviewed starting point: rename the types, add what the sample could not show, and run the file through your compiler after pasting.

Recent tools: