JSON to Go Struct
Generate Go structs with json tags from JSON instantly. Handles nested objects, arrays, nullable pointers, and omitempty tags. Free, runs in your browser.
- Runs in your browser
- Your data never leaves your browser
- Free · No Sign-Up
Scan with WeChat to share this tool
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.
Type Mapping
null→interface{}- string →
string - number without
.or exponent →int - number with
.or exponent (19.0,1e3) →float64 - boolean →
bool - array →
[]T - nullable/optional → pointer (
*T) - nested object → separate named
struct
Example
Given this JSON:
{"name": "Alice", "age": 30, "address": {"city": "London"}}
The tool generates:
type RootObject struct {
Name string `json:"name"`
Age int `json:"age"`
Address Address `json:"address"`
}
type Address struct {
City string `json:"city"`
}
Example: An API Response
{
"user": {
"id": 42,
"name": "Alice",
"email": "alice@example.com",
"is_active": true,
"roles": ["admin", "editor"],
"address": { "city": "New York", "country": "US", "zip_code": "10001" },
"last_login": null
}
}
generates
type RootObject struct {
User User `json:"user"`
}
type User struct {
Id int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
IsActive bool `json:"is_active"`
Roles []string `json:"roles"`
Address Address `json:"address"`
LastLogin interface{} `json:"last_login"`
}
type Address struct {
City string `json:"city"`
Country string `json:"country"`
ZipCode string `json:"zip_code"`
}
snake_case keys become CamelCase field names, and the json tag keeps the original key, so encoding/json maps them both ways. The fields are not aligned; run gofmt (or save in an editor that runs it) to line up the tags. Decode with the standard library:
var root RootObject
if err := json.Unmarshal(data, &root); err != nil {
log.Fatal(err)
}
fmt.Println(root.User.Name) // Alice
Example: A Top-Level Array
[{"sku": "A1", "qty": 2}, {"sku": "B2", "note": "gift"}]
generates
type RootObject struct {
Sku string `json:"sku"`
Qty *int `json:"qty,omitempty"`
Note *string `json:"note,omitempty"`
}
For a top-level array, the struct describes one element; decode into []RootObject. Keys missing from some elements become pointers with omitempty.
Example: Same Key Twice, Decimals, and a Key Starting With a Digit
{
"order": { "id": "A-1001", "total": 19.0, "meta": { "createdBy": "alice", "source": "web" } },
"payment": { "status": "paid", "meta": { "provider": "stripe", "fee": 0.3 } },
"2fa": true
}
generates
type RootObject struct {
Order Order `json:"order"`
Payment Payment `json:"payment"`
X2fa bool `json:"2fa"`
}
type Order struct {
Id string `json:"id"`
Total float64 `json:"total"`
Meta Meta `json:"meta"`
}
type Meta struct {
CreatedBy string `json:"createdBy"`
Source string `json:"source"`
}
type Payment struct {
Status string `json:"status"`
Meta PaymentMeta `json:"meta"`
}
type PaymentMeta struct {
Provider string `json:"provider"`
Fee float64 `json:"fee"`
}
payment.meta has different fields from order.meta, so it gets its own struct named with its parent in front, PaymentMeta; with the same fields, both would share Meta. 19.0 is written with a decimal point, so total is float64: encoding/json refuses to decode 19.0 into an int field. The tool reads the number as written through the browser’s JSON source text access (Chrome 114+, Firefox 135+, Safari 18.4+); browsers without it see 19 and fall back to int. The key 2fa cannot start an exported Go name, so the field is X2fa and the tag keeps 2fa.
What to Fix After Generating
nullbecomesinterface{}. Change it to a pointer of the real type, such as*stringor*time.Time, after checking the API docs.- A number written without
.or an exponent becomesint, and19.0or1e3becomesfloat64; integers and decimals mixed in one array or key givefloat64. A sample that happens to hold only whole numbers still givesint, so check fields such as prices.intis 64 bits on 64-bit platforms. []and arrays with other mixed element types become[]interface{}.- Field names are not adjusted to Go initialisms:
idbecomesIdandurlbecomesUrl, while Go Code Review Comments recommendsIDandURL. Thejsontag keeps decoding correct either way. - A key whose field name would not start with an upper-case letter (
2fa,名前) gets anXprefix (X2fa), and two keys that give the same name (user_id,userId) get a number (UserId2). An empty key and keys with characters a struct tag cannot hold (such as"or,) are listed in a comment instead of a field, becauseencoding/jsoncannot map them by tag. - Generated names such as
PaymentMetaorMeta2come from the JSON keys; rename them to match your domain. - Only
jsontags are written. Addgorm,bson, orvalidatetags yourself.
Limits
- The input must be valid JSON; the error message gives the position, for example
Expected double-quoted property name in JSON at position 8for a trailing comma. - Types come only from the sample you paste.
FAQ
What does this tool generate?
It generates Go struct type declarations with json struct tags. Each nested JSON object becomes its own named struct. Array fields become slices ([]T).
How are nullable fields handled?
A key whose only value in the sample is null becomes interface{}, because the sample does not show its type. In an array of objects, a key that is null in some items and has a value in others becomes a pointer to that type (for example *string), and a key that is missing from some items becomes a pointer (a slice stays a slice) with ,omitempty in its json tag.
Why are pointer types used?
In Go, pointers are the idiomatic way to represent optional or nullable values. A *string can be nil (absent/null) whereas a string cannot.
What json tags are generated?
Every field gets a json tag with the original JSON key, so snake_case and camelCase keys still map after the field gets an exported Go name. Keys that are missing from some items of an array also get ,omitempty. An empty key and keys that contain characters a struct tag cannot hold, such as a double quote or a comma, are written as comments instead of fields. Only json tags are generated.
Is my data sent to a server?
No. The structs are generated in your browser tab, and the JSON and the root struct name are not sent to a server or saved in browser storage. When you finish editing the input, click Generate Go Struct or load the example, the page's analytics records one usage event with the tool name and the action (generate), not the JSON or the code.