How to use the JSON to Go
- Paste the JSON you want to decode, such as an API response.
- Set the name of the top-level struct.
- Check the nested types: every nested object becomes its own named struct, named after its key.
- Copy the code and decode with json.Unmarshal(data, &v) or json.NewDecoder(r).Decode(&v).
Worked example
A user profile with a nested address
Input
{"id":1001,"userName":"ada","score":98.5,"tags":["a"],"address":{"city":"London"}}Go
package main
type Root struct {
ID int64 `json:"id"`
UserName string `json:"userName"`
Score float64 `json:"score"`
Tags []string `json:"tags"`
Address Address `json:"address"`
}
type Address struct {
City string `json:"city"`
}Field names are exported (capitalized) because encoding/json ignores unexported fields. id becomes ID following Go's initialism convention.
JSON to Go type mapping
| JSON | Go type | Why |
|---|---|---|
| string | string | |
| whole number | int64 | Safe for IDs; use int if you prefer |
| decimal number | float64 | What encoding/json uses for interface{} numbers |
| true / false | bool | |
| integer beyond int64 | json.Number | Keeps every digit |
| null or mixed | any (interface{}) | No single concrete type fits |
| array | []T | nil slice if the key is missing |
| object | named struct | Or map[string]T for dynamic keys |
omitempty, pointers and missing fields
When decoding, a key missing from the JSON leaves the field at its zero value: 0, "", false or nil. You cannot tell "absent" from "zero" unless the field is a pointer (*int64) – a nil pointer means the key was missing or null.
Adding ,omitempty to a tag only affects encoding: zero values are left out of the output. It does nothing when decoding.
Large integers and dynamic keys
Decoding into a typed int64 field keeps every digit. Decoding into any turns numbers into float64 and loses precision above 2^53; call decoder.UseNumber() if you must decode into maps. When object keys are data, such as {"2024-01": 5, "2024-02": 7}, replace the generated struct with map[string]int.
JSON to Go FAQ
Why are my Go struct fields empty after json.Unmarshal?
The fields are probably unexported (lowercase) or the tags do not match the JSON keys. encoding/json only sets exported fields; it matches keys to field names or tags case-insensitively, so a typo in the tag is the usual culprit.
What does omitempty do in a Go JSON tag?
When marshaling, it skips the field if it holds the zero value for its type. It has no effect on unmarshaling.
Should I use int or int64 for JSON numbers in Go?
int is 64 bits on all mainstream 64-bit platforms, so either works there. int64 makes the size explicit and is portable to 32-bit builds.
How do I handle a field that is sometimes a string and sometimes a number?
Use json.RawMessage or any for that field and inspect it after decoding, or write a custom UnmarshalJSON method on a small wrapper type.
Does Go reject unknown JSON fields?
Not by default; they are ignored. Call decoder.DisallowUnknownFields() on a json.Decoder to make unknown keys an error.

