JSON to Go Struct
Convert a JSON sample into a ready-to-use Go struct with json tags. Handles nested structs, slices, unions, and null fields. Runs entirely in your browser.
Input JSON
How it works
- Paste any valid JSON — the struct definition is inferred from the values: numbers, strings, booleans, arrays, and nested objects.
- Whole numbers become
int64, decimals becomefloat64, andnullbecomesinterface. - Arrays of objects become
[]Typeslices; arrays of mixed values become[]interface. - Every field gets a Go field name and a
json:"..."tag matching the original key.
Type mapping rules
| JSON value | Go type |
|---|---|
42 | int64 |
3.14 | float64 |
"hello" | string |
true / false | bool |
null | interface |
[1, 2, 3] | []int64 |
[{...}, {...}] | []Type |
{"a": 1} | struct |
About JSON to Go Struct
Go’s encoding/json needs explicit struct types, and writing them by hand for a large API payload is slow and error-prone. This tool infers the struct skeleton from a representative JSON sample and emits idiomatic fields with json tags, so the decoder maps keys correctly even when Go field names differ. Nested objects become nested structs and arrays of objects become slices of structs.
Inferred output reflects only the sample: fields that are absent from the sample will be missing from the struct, and optional fields that happen to hold null become interface. After generating, review the result, add omitempty where you want zero values skipped, and consider json.RawMessage for polymorphic fields. The tool runs fully locally — paste production payloads safely.
Struct generation and type selection
Whole numbers land on `int64` and fractional ones on `float64`. `int64` is the right default for identifiers and covers the full signed 64-bit range, but Go will refuse a fractional value on the wire for that field, so a number that is sometimes `1` and sometimes `1.5` wants `float64` — or `json.Number` where the exact decimal matters.
`null` maps to `interface{}`, which accepts anything and asserts nothing. That is honest for a genuinely optional field and useless as a default: every read needs a type assertion. Arrays of objects merge their keys into one `KeyItem` struct and produce a slice of it; an array mixing objects and scalars degrades to `[]interface{}`, and an empty array becomes `[]interface{}` because there is nothing to infer from.
Field naming and JSON tags
Field names are PascalCase, built by splitting the key on non-alphanumeric runs and capitalising each part. Every field carries a `json:"..."` tag holding the original key, so `user_id` maps cleanly onto `UserId` — the tag is what makes decoding lossless regardless of the Go-side name, and it also means renaming the field in Go never breaks the wire format.
Nested structs are collected into a definition list during traversal and emitted before their referents, with the `Root` type emitted last. Go does not require declaration order, but the layout keeps a nested type visible above the struct that uses it, which matters when a payload nests more than three levels deep.
Gaps worth closing by hand
A top-level array or scalar is rejected with a clear message, since there is no sensible struct to anchor to. Fields absent from the sample are absent from the struct, so an endpoint that omits a field under some conditions will silently drop it on decode — and because `null` and absent both map to a zero value, the two cases are indistinguishable.
No `omitempty`, no pointers, and no `json.RawMessage` are emitted. Add `omitempty` where zero values should be skipped, switch genuinely optional fields to pointers so absent is distinguishable from zero, and use `json.RawMessage` for polymorphic fields — a discriminated union has no faithful single-type representation here. For optional-aware output, the Pydantic generator produces nullable fields natively.
Frequently Asked Questions
How do I convert JSON to a Go struct?
Are the Go types accurate?
Is my data sent to a server?
Do I need an account or API key?
Can I use these tools offline?
All processing happens in your browser. No uploads, no tracking, no servers. Your API keys, configs, and private payloads stay private — 100% client-side.