Generate Go structs from JSON
Convert a JSON sample into Go structs with correct json tags, Go initialisms (ID, URL, API), int64/float64 inference and omitempty on optional keys.
- Runs in your browser
- Files are never uploaded
- Free, no account
The name given to the outermost type.
Your JSON never leaves this tab — check it yourself—
Starting the network probe…
The counter above wraps fetch, XMLHttpRequest and navigator.sendBeacon in this tab and counts every call. It does not block anything — it just reports.
Two ways to verify independently
- Turn off Wi-Fi or enable airplane mode, then use the tool. It keeps working, because the page is already fully loaded.
- Open your browser devtools, switch to the Network tab, clear it, and run the tool. No new row appears.
Why this matters
In 2025 researchers found that popular online formatters had retained tens of thousands of user-submitted snippets — JSONFormatter.org and CodeBeautify together exposed roughly 80,000 saved documents, many containing live cloud credentials, private keys and internal database connection strings, because “format this” quietly meant “upload this”. A separate incident exposed roughly 3.5 million user PDFs on a document-conversion service. The only structural fix is not sending the data in the first place: this site is served under a Content-Security-Policy whose connect-src contains no third-party origin, so a request off this device cannot be made even by accident.
Go-specific decisions the generator makes
Initialisms
Go’s naming convention capitalises initialisms in full, and both go vet and the
linters that succeeded golint enforce it. user_id becomes UserID, not
UserId; api_url becomes APIURL; html_body
becomes HTMLBody. The recognised set covers ID, URL, URI, API, HTTP, HTTPS, JSON,
XML, HTML, SQL, UUID, IP, TLS, SSH, CPU, RAM, UTC, EOF, DB, OS and TTL.
Numeric types
Whole numbers become int64 rather than int, because int is
32-bit on some platforms and JSON integers routinely exceed that — a millisecond timestamp already
does. Fractional numbers become float64, which is what a JSON number actually is.
Narrow them by hand where you know the range, and use string plus a decimal library
for money.
Pointers
A field that was sometimes null becomes a pointer, so you can distinguish “absent or
null” from the zero value. This matters more in Go than in most languages: without it,
0, "" and false are indistinguishable from a missing field.
Slices and maps are already nilable and are never wrapped.
Struct tags
Every field carries a json:"…" tag with the original key, because Go’s
case-insensitive fallback matching is a trap: it works until two keys differ only in case, and it
makes the wire format invisible in the source.
omitempty, and when to remove it
Fields that were missing from some records get ,omitempty, so marshalling back to
JSON omits them rather than emitting a zero value. Be deliberate about keeping it: omitempty also
drops 0, "", false and empty slices, so a field where zero
is a meaningful value will silently disappear from your output. If you need to send an explicit
zero and omit an absent value, use a pointer and drop omitempty.
Decoding safely
Two habits worth adopting alongside the generated structs:
-
decoder.DisallowUnknownFields()turns an unexpected key into an error instead of a silent drop. That is how you find out the API changed. -
decoder.UseNumber()keeps numbers as strings until you convert them, which avoids the float64 rounding that destroys large integer IDs.
Struct field ordering and memory
Fields are emitted in the order they appeared in your JSON, which keeps the struct readable against the payload. Go pads struct fields for alignment, so on a hot path with millions of instances you can reduce the memory footprint by grouping fields largest-first. That is an optimisation to apply deliberately, not a default — readability is worth more in almost every case.
The output is a package main starter
The file declares package main so it compiles as-is for a quick check. Change it to
your real package name before adding it to a project, and split large outputs into one file per
logical group rather than keeping forty structs in one file.
Questions
Does it follow Go naming conventions?
Yes. Field names are exported PascalCase, and known initialisms are fully capitalised the way `go vet` and golint expect: `user_id` becomes `UserID`, not `UserId`, and `api_url` becomes `APIURL`. The original key is preserved in the json tag, so the wire format is unaffected.
Why int64 rather than int?
Because `int` is 32-bit on some platforms and JSON integers routinely exceed that — a Unix timestamp in milliseconds already does. int64 is the safe default. Change it by hand if you know the range is small.
When do I get a pointer type?
When a value was sometimes null and nullable modelling is on. A `*string` lets you distinguish "absent or null" from "empty string", which a plain `string` cannot. Slices and maps are already nilable, so they are never wrapped in a pointer.
What does omitempty do here?
It is added to keys that were missing from some records, so marshalling the struct back to JSON omits them rather than emitting a zero value. Be careful: omitempty also drops legitimate zeros, empty strings and false, so remove it on fields where those are meaningful.