JSON to Go struct — paste JSON, get typed structs with json tags, exported fields, nested sub-structs, pointers for nullable, int64 and omitempty options.
- Runs locally
- Category Developer & DevOps
- Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
How types, tags & pointers are inferred
Each JSON object becomes a named struct with exported (capitalised) fields, each carrying a `json:"key"` tag so encoding/json round-trips your exact key. Integer numbers infer int (or int64); fractional numbers infer float64; if a number is sometimes whole and sometimes fractional, the field widens to float64. Arrays of objects fold into ONE struct — keys missing from some elements become nullable (a pointer when "Pointers" is on). A value that is only ever null types as interface{}. Toggle ,omitempty so empty/zero fields are dropped from the marshalled JSON.
What this tool does
Paste any JSON payload — a GitHub API response, a Stripe webhook, a Kubernetes manifest, a config file — and get back a set of Go `struct` declarations with `json:"field"` tags ready to drop into a `.go` file. Every field is exported (leading capital) so `encoding/json` can reach it, snake_case keys are converted to idiomatic CamelCase, and known initialisms like `ID`, `URL`, `HTTP` and `API` stay all-caps the way golint and staticcheck want them. Numbers are split, not flattened: an integer sample infers `int` (or `int64` if you flip that switch), a fractional sample infers `float64`, and a field that is sometimes whole and sometimes fractional widens to `float64` so it never panics on unmarshal. Arrays of objects fold into ONE struct, so `[{"a":1},{"a":1,"b":2}]` gives you a single type with both fields — not two near-duplicate structs. Keys missing from some array elements (or seen as `null`) are treated as nullable: turn on pointers and they become `*T`; leave it off and the Go zero value stands in. Add `,omitempty` to every tag with one toggle when you marshal back out. Rename the root struct, share the exact input and options as a link, copy or download the `.go` file. Everything runs in your browser — the JSON never touches a server.
Tool details
- Input
- Text + Numbers + Structured content
- The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
- Output
- Live result + Copy + Download
- The result area focuses on usable output, with copy, download, or preview actions when supported.
- Privacy
- Browser-side processing
- The main tool logic does not call an external API, so inputs normally stay in the current tab.
- Save / share
- Shareable URL state
- Key settings are encoded in the URL so another person can reopen the same setup.
- Performance budget
- Initial JS <= 25 KB
- No WASM budget is declared, keeping the tool quick to open on mobile.
- Best fit
- Developer & DevOps · Developer
- Category and role tags drive related tools, internal links, and quick fit checks.
How to use
-
1. Input
Paste or drop your content into the tool panel.
-
2. Process
Click the button. All processing is local in your browser.
-
3. Copy / Download
Copy the result or download to disk in one click.
How JSON to Go Struct fits into your work
Use it in the small gaps between coding, reviewing, debugging, and shipping.
Developer jobs
- Formatting, validating, shrinking, or inspecting code-adjacent text.
- Preparing snippets for documentation, tickets, commits, or handoff.
- Checking a small payload quickly without switching tools.
Developer checks
- Run irreversible transforms like minify or obfuscate on a copy.
- Keep secrets out of pasted snippets unless the tool explicitly stays local.
- Use your normal tests or linter before shipping transformed code.
Good next steps
These links move the current task into a more complete workflow.
- 1 JSON to TypeScript Interface JSON to TypeScript interface — paste JSON, get clean interfaces with union types from arrays, optional vs required detection, root name customizable. Open
- 2 TypeScript to Zod Schema TypeScript to Zod schema converter — paste interface/type, get z.object() schema, supports unions/optionals/nested/generics/enum/Record/Map/Set. Open
- 3 JSON to Python Dataclass JSON to Python — paste JSON, get @dataclass or Pydantic v2 models with type hints, Optional inference, nested classes, snake_case fields and aliases. Open
Real-world use cases
Type a third-party API response without hand-writing structs
You're integrating the GitHub API and the user object has 30+ fields. Curl the endpoint once, paste the JSON here, set the root name to `GitHubUser`, copy the output into `internal/github/types.go`. The nested `plan` object lifts out as `GitHubUserPlan` automatically, and `html_url` becomes `HTMLURL` with the right tag. Now `json.Unmarshal(body, &u)` fills a fully-typed struct instead of a `map[string]interface{}` you have to type-assert all over.
Generate request/response DTOs for a new endpoint
A teammate sends you a sample JSON body for the `/orders` POST they're building. Paste it, name the root `CreateOrderRequest`, turn on `,omitempty` so optional fields don't bloat the marshalled payload. Paste the response sample too as `CreateOrderResponse`. Two structs, fully tagged, committed to `api/dto.go` before either of you writes the handler.
Decide pointers vs values for a nullable webhook payload
A vendor's webhook sometimes includes `cancelled_at` and sometimes omits it. Log the first few payloads, paste them as a JSON array, and the optional-field detection flags `cancelled_at`. Turn on Pointers and it becomes `*string`, so in your handler `if e.CancelledAt != nil` cleanly distinguishes "cancelled" from "still active" — instead of guessing whether an empty string means absent.
Migrate a map[string]interface{} blob to a real type
Old code does `var data map[string]interface{}` and reaches in with `data["user"].(map[string]interface{})["id"].(float64)`. Capture one representative response, paste it, generate the struct, replace the map. The `.(float64)` casts that bit you (JSON numbers decode as float64 into `interface{}`) disappear — `int` and `float64` are now inferred at the field level.
Build fixtures and config types for a Go service
Your service reads a `config.json`. Paste it, name the root `Config`, get `Config`, `ConfigServer`, `ConfigServerTLS` nested structs with `int` ports and `bool` flags. Drop them in `config.go`, write `json.NewDecoder(f).Decode(&cfg)`, and your config is type-checked at compile time instead of failing at runtime on a typo'd key.
Common pitfalls
Pasting a single object and expecting some fields to be optional. A single object has no missing-key signal, so every field is required. Optional/pointer inference only kicks in across an array of objects where some elements carry a key and others don't. To explore optionality from one sample, wrap it as `[{...}]`.
Turning on ,omitempty for a field where 0 / false / empty is a real value. With omitempty, a `Count int` that you set to 0 simply won't appear in the marshalled JSON — the receiver can't tell "count is zero" from "count was never sent". Use a pointer (`*int`) plus omitempty when you genuinely need that distinction.
Assuming int64 is always correct for IDs. If your IDs arrive as JSON *strings* (Stripe `cus_123`, many UUID APIs), they infer as `string`, not int64 — and that's correct. int64 only applies to numeric JSON values. Don't manually retype a string ID to int64; you'll break unmarshalling.
Treating a field that's only ever null as a typed field. `{"meta": null}` gives `Meta interface{}` because null carries no type information. If you know the real shape, feed a non-null sample (`{"meta": {"k": 1}}`) so the tool can infer a proper struct.
Pasting JSON5 / JSON-with-comments / trailing commas. We use strict `JSON.parse`, so comments, unquoted keys, and trailing commas all error out. Strip them first, or pipe through a JSON formatter as a pre-step.
Privacy
Your JSON never leaves this browser tab. Parsing and type inference use the browser's built-in `JSON.parse`; there is no network call and no analytics on the textarea content. The Share link encodes your input and option choices into the URL so a result is reproducible — that means YOU decide when to share. If the payload is sensitive (internal IDs, customer data, prod responses), copy the generated Go instead of sharing the link. Only your option booleans (pointers / omitempty / int64) are stored in localStorage so your preferred style persists across visits.
FAQ
Tool combos
Folks in your role tend to reach for these alongside this tool.
- 555 Timer Calculator Astable f = 1.44/((R1+2R2)C) + monostable t = 1.1RC — pick R1, R2, C in Ω/kΩ and µF/nF, read frequency, duty cycle and pulse width — browser-only
- Add Line Numbers Number every line of pasted text — set start, step and separator, zero-pad to align, skip blanks, or strip numbers back off — browser-only
- AES Text Encryptor Encrypt & decrypt text with a password — AES-256-GCM + PBKDF2 via WebCrypto — 100% in your browser, nothing uploaded
- Affine Cipher Encoder & Decoder Encrypt and decrypt the ax+b affine cipher with live modular-inverse check, browser-only