Skip to content

JSON to Go Structs

Generates Go structs with json tags from a JSON sample, including nested and repeated types.

Generates Go structs with `json:` tags from a sample document, so a response body becomes something `encoding/json` can unmarshal into. Field names are exported and camel-cased, and the original key is kept in the tag, which is the part people get wrong by hand.

🔒 Runs entirely in your browsergojsoncodegenstruct
Emit

Sample JSON

Drop a .json file

Read in this tab. Nothing is uploaded.

Give it every element you have. Every extra record narrows the guess — a field missing from one of them is what makes it optional.

TypeScript

How to use it

  1. Paste as many records as you have

    Every element of every array is read and merged, not just the first. Three records tell it far more than one, because a field missing from one of them is exactly what makes that field optional.

  2. Name the root type

    Nested objects are named after the key that holds them, singularised for arrays, so `users` yields a `User`. Only the root needs a name from you.

  3. Read the counts under the output

    Types, optional fields, unions and how many records were merged. A union count above zero means a field held two different kinds of value across your sample — worth looking at before you paste the result into a codebase.

  4. Paste the structs into a package

    Fields that were missing from some records get `,omitempty` in their tag so a marshal round-trip does not invent them. No package clause is emitted — you know where it is going.

Common questions

Why is every number `float64`?

Only when the sample had a fractional value. If every number in the document was whole, the field is emitted as an integer type. There is no way to tell a JSON `1` that is an id from a JSON `1` that is a rounded price, so the sample is all the evidence there is.

What about a field that is null in some records?

It becomes a pointer type, which is how Go distinguishes "absent or null" from "zero". That means dereferencing it needs a nil check — annoying, and the reason the alternative (a plain value that silently reads as 0 or "") is worse.

Does it handle a key that is not a valid Go identifier?

The field name is cleaned up — separators dropped, each part capitalised — and the raw key stays in the `json:` tag, which is what actually does the matching. A key of `user-id` becomes `UserID`-ish with `json:"user-id"` beside it.

Are `time.Time` fields produced?

No. A timestamp in JSON is a string, and turning it into `time.Time` would change what unmarshalling accepts. If you want that, change the field type by hand — `encoding/json` parses RFC 3339 into `time.Time` on its own.

Feed it from

Next

These accept what this tool produces, so the result can go straight in.