GO

JSON to Go Struct

Infer nested Go structs, JSON tags, slices, pointers, and optional fields from samples

JSON & Data
πŸ”’ 100% client-side β€” your data never leaves this page
Maintained by Evanβ€’Updated: September 30, 2026
JSON β†’ Go structs

Inferred from samples, not a complete API contract. Missing fields and explicit null are inferred separately but can share an output type; null array elements remain nullable. Duplicate keys and numbers that would change value are rejected.

Limits: 1 MiB, 64 levels, 20,000 values, 200 models and 2,000 model fields. Use strings for exact large IDs or monetary decimals.

Target: Go 1.18+ with encoding/json. JSON keys that Go tags cannot represent are rejected explicitly. Mixed values use any.

Go structs

After generation, compile in your target project and verify deserialization with representative responses.

About this tool

JSON to Go Struct starts from an object or a non-empty array of object samples and emits named structs for Go 1.18+ with encoding/json tags. The generator distinguishes missing fields from explicit null while inferring the schema. Nullable scalar and object values, including elements inside slices, use pointers; the missing-field pointer option controls absence observed across samples. Mixed values use any, so they still need an application contract. Normalized field names and model names receive unique suffixes. Not every JSON key can be encoded in a Go tag: empty keys, a single hyphen, commas, quotes, backslashes, backticks, control characters and unsupported symbols are rejected instead of silently reading another field. Turn on omitempty only when dropping nil or empty values is intended. Input is processed locally with limits of 1 MiB, 64 nesting levels, 20,000 values, 200 models and 2,000 model fields. Duplicate keys, unpaired Unicode surrogates, negative zero, unsafe integers and decimal tokens that would change value are rejected. Use strings for exact IDs or money, then compile and test representative responses in the target module.

Scenario Recipes

01

Verify a nullable score list

Goal: A slice whose null element remains distinct from a zero score.

  1. Paste {"values":[1,null,2]} and leave omitempty off.
  2. Generate Go structs and confirm Values uses []*int64.
  3. Unmarshal the same sample with encoding/json, marshal it again and verify the middle element remains null.

Result: A slice whose null element remains distinct from a zero score.

Failure Clinic (Common Pitfalls)

A field is missing after unmarshaling

Cause: A compilable Go tag is not proof that encoding/json accepts its name.

Fix: Check the rejected key and implement a custom mapping for unsupported names. Do not delete punctuation from source keys.

A field disappears after marshaling

Cause: omitempty changes presence semantics for nil and empty values.

Fix: Compare output JSON with a sample containing both null and an empty slice before enabling this option.

Production Snippets

Null elements need their own pointer type

go

// Input: {"values":[1,null,2]}
type ApiResponse struct {
    Values []*int64 `json:"values"`
}
// A nil element remains JSON null; it is not int64(0).

Frequently Asked Questions

Why does [1, null, 2] become []*int64?

The null is an array element, not a missing field. An integer pointer can represent either its value or nil without replacing null with zero.

Why is a valid JSON key rejected?

encoding/json has its own tag-name grammar. Keys outside that grammar need a custom UnmarshalJSON implementation, which this tool does not generate.

Will omitempty preserve explicit null and empty slices?

Not necessarily. For inferred missing fields, the enabled option can omit nil or empty values when marshaling. Keep it off when those values must appear.

Does int64 mean every 64-bit JSON integer is accepted?

No. This browser inference checks the original numeric token and accepts only safe integers. Encode a larger identifier as a string before generating a model.

Keep browsing