What this tool does
Generate Go structs with json:"…" tags from a JSON sample. Each object becomes a struct, each key a Go-cased field (created_at → CreatedAt), and the JSON tag preserves the original key. Nullable values get pointer types (*string) so you can distinguish missing from zero-value. Powered by quicktype, runs entirely in your browser.
How to use it
Paste JSON (or load the example) and read the Go struct on the right. Each nested object becomes its own type, with idiomatic Go field names and json: tags so the struct round-trips through encoding/json.
Input: {"id":42,"name":"devsmiths","createdAt":"2024-03-11T08:24:00Z","stars":1280,"public":true,"contributors":[{"login":"ada","commits":51,"admin":true},{"login":"linus","commits":33,"admin":false}],"homepage":null}
Output (Go):
type Root struct {
ID int64 `json:"id"`
Name string `json:"name"`
CreatedAt string `json:"createdAt"`
Stars int64 `json:"stars"`
Public bool `json:"public"`
Contributors []Contributor `json:"contributors"`
Homepage interface{} `json:"homepage"`
}
type Contributor struct {
Login string `json:"login"`
Commits int64 `json:"commits"`
Admin bool `json:"admin"`
}Limits and edge cases
- Field names are PascalCase (Go’s requirement for exported fields), but the
json:"…"tag preserves the original JSON casing — socreated_atin JSON becomesCreatedAt string `json:"created_at"`. - Nullable fields (where the sample has
null) are emitted asinterface, not pointer types. You usually want pointers (*string) to distinguish “missing” from “zero value”; flip nullable as pointer in the options pane if that matches your downstream code. - Whole numbers are typed as
int64regardless of magnitude. If the JSON contains2.0the generator emitsfloat64; if it contains2you getint64.encoding/jsontolerates either at decode time, but tighten by hand for fields you know are always integral. - Date strings (ISO 8601) generate as plain
string, nottime.Time. The generator can’t tell a date from a slug at the JSON layer — change the field type and add aUnmarshalJSONif you want native time values. - No
omitemptytags by default. Add them by hand for fields that should be skipped when serialising back to JSON (or pass all optional to getomitemptyon every field). - The single-sample limitation applies here too — fields not present in the sample need to be added by hand or via all optional.
Frequently asked questions
- Why are field names PascalCase but my JSON uses camelCase?
- Go requires exported (capitalised) field names for the struct fields to be visible to packages outside the declaring one — `encoding/json` lives outside, so unexported fields wouldn't serialize. The `json:"camelCaseKey"` tag preserves the original JSON key for serialization; the Go-side name is PascalCase for the language's convention.
- Should I use *string for nullable fields, or stick with interface{}?
- Pointer types are usually better: `*string` distinguishes 'field missing' (nil pointer) from 'field present and empty' (pointer to empty string). `interface{}` works but loses type safety and requires a type assertion at every read site. Toggle 'nullable as pointer' in the options pane to switch globally.
- How are large numbers handled — do I lose precision?
- Numbers come in via JavaScript first (it's what your browser uses to parse the JSON), so values beyond ±2^53 lose precision before they reach the Go generator. If the JSON has 64-bit IDs (e.g. Twitter/X status IDs), serialize them as strings on the producer side and use `json:",string"` tag on the Go field to round-trip through encoding/json.
- Can I get omitempty on every field automatically?
- Yes — toggle 'all optional' in the options pane. The generator emits `json:"name,omitempty"` on every field, which makes encoding/json skip zero-value fields during marshal. Be careful: `omitempty` treats Go's zero values (0, "", false, nil) as omittable, which can drop legitimate values. Use pointer types if you need to distinguish 'zero' from 'omitted'.
- What about JSON dates — can I get time.Time?
- Not automatically. JSON dates are strings, and the generator doesn't try to recognise ISO 8601 from arbitrary slug-shaped strings. Change the field type from `string` to `time.Time` by hand; encoding/json will then parse with RFC 3339 format. For non-RFC-3339 dates, implement a custom `UnmarshalJSON` method on a wrapper type.
- Does the output work with goimports / gofmt?
- Yes — the output is gofmt-clean (tab indent, aligned struct tags). goimports may add an `encoding/json` import if you serialize the structs in your code, but the generator doesn't include unused imports. Drop the output through `goimports -w` if your editor doesn't run it on save.
Content reviewed by ShiangYu Huang