100% local — your data never leaves your browser

JSON to Go — Structs That Drop Into Your File

Turn a JSON sample into Go structs with json tags. Columns come out aligned the way gofmt would leave them, so the paste needs no cleanup.

Instant Private Zero cookies

JSON input

Go output

What this tool does

A JSON sample becomes Go structs, one per object.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
type Root struct {
	Id        int     `json:"id"`
	FirstName string  `json:"firstName"`
	Address   Address `json:"address"`
}

type Address struct {
	City string `json:"city"`
}

Columns are aligned the way gofmt aligns them — name, type, tag. Nobody reads unformatted Go, and pasting this into a file then running gofmt should change nothing.

That alignment is recent: fields used to come out separated by single spaces. It was a small thing, and it was still the output not looking like the language it claims to be.

Names are exported, keys live in the tag

encoding/json ignores unexported fields entirely: a lowercase field decodes nothing and encodes nothing, without a word. So every field is exported — PascalCase, with an F in front when the key starts with a digit (2fa gives F2fa) — and the tag carries the original key unchanged.

Two keys that produce the same Go name — user-name and userName — are kept apart by a numbered suffix. The tags stay distinct, so both fields still map to their own key.

omitempty omits more than you might think

The option adds ,omitempty to every tag. It applies when encoding only, and it cannot distinguish “absent” from “zero”: 0, "", false, an empty slice and a nil map all vanish from the output.

That is fine for an optional filter, and wrong for a score that can legitimately be zero. Where the difference matters, the usual answer is a pointer — *int — which encodes null for nil and a real 0 otherwise.

Types, and what a sample cannot say

  • Integers become int, not int64. On every 64-bit platform that is the same thing; a value beyond it fails loudly at decode rather than silently truncating.
  • null and unknown values become any. An empty array becomes []any, a mixed array too, except when it mixes integers and floats — []float64 covers both.
  • No field is a pointer and none is optional, because a sample cannot show that. A key that is sometimes missing is a *T you add yourself, and it is the first thing worth checking against a second payload.

Private by design

Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.

Frequently asked questions

Why are the field names capitalised?
Because `encoding/json` only sees exported fields. A lowercase `id` would be skipped in both directions, silently — the struct would compile, decode nothing into that field and encode nothing out of it. The tag keeps the original key, so `Id int `json:"id"`` reads and writes exactly what your document has.
What does the omitempty option actually do?
It adds `,omitempty` to every tag, which means a zero value is left out when **encoding**. It changes nothing when decoding, and it cannot tell an absent key from a zero: `0`, `""`, `false` and an empty slice all disappear from the output. If a real zero matters, a pointer field is the usual answer.
Should my field be `Id` or `ID`?
Go\u2019s style guide says `ID`, and linters will say so too. This tool writes `Id`, derived mechanically from the key, because renaming initialisms means keeping a list of them — `ID`, `URL`, `API`, `HTTP` — and applying it to keys it has never seen. The tag makes the rename harmless, so it is a safe edit to make yourself.

Related converters