Skip to main content
7BBusyBoss

JSON to Go Struct Converter — Free Online

JSON to Go struct generator with exported field names and json tags. Handles nested objects, arrays, and type inference for int vs float64.

No limitsZero data leaksSuper fast

JSON to Go Struct Converter

Files never leave your browser
View:

0 lines · 0 chars · 0 B

0 lines · 0 chars · 0 B

You're on 7BusyBoss — 300+ free tools that run instantly in your browser. No signup, nothing uploaded.

Browse all Code Converters
About this tool

Exported names are mandatory, and the failure is silent

Go's encoding/json package works by reflection, and reflection can only reach exported identifiers — those beginning with a capital letter. A lowercase struct field is simply invisible to the decoder: it is left at its zero value, and no error is returned. You get a struct that looks fine and is quietly empty, which is considerably worse than a crash because nothing points at the cause.

This is why the generator capitalises every field name. userName becomes UserName, user_name becomes UserName, and email_address becomes EmailAddress. If you later "tidy" those back to lowercase to match the JSON, the struct stops unmarshalling and gives you no clue why.

The struct tag is the bridge

Because the Go field is capitalised while the JSON key usually is not, something has to connect the two. That is the backtick-quoted tag:

type Root struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Author Author `json:"author"`
}

Without a tag, Go falls back to matching the field name against the key case-insensitively. That happens to work for simple keys — id finds ID, title finds Title — which is exactly why the tags look optional right up until they are not. A key of user_id will not match a field named UserID, because case-insensitive comparison still leaves the underscore in place and the two strings differ. The same applies to any key containing a hyphen. The tags are load-bearing.

Missing keys leave fields at their zero value

When a key is absent from the JSON, Go assigns the field its zero value and reports nothing: 0 for numbers, "" for strings, false for booleans, nil for slices and maps.

The consequence is that absent and present-but-zero are indistinguishable. A missing count key and an explicit "count": 0 both arrive as Count: 0. Where that distinction carries meaning — a discount that was not supplied versus a discount of zero, a flag that was never set versus one set to false — the fix is a pointer:

Count *int `json:"count"`

Now the field is nil when the key was absent. The cost is a nil check before every use, so apply it to the fields where the difference genuinely matters rather than across the whole struct. The generator does not emit pointer types; this is a change you make by hand.

One JSON number type becomes either int or float64

JSON has a single number type, so the generator has to choose from the sample: a whole number such as 42 produces int, and a decimal such as 3.14 produces float64.

The trap is a value like 2.0 or 100.0. It is mathematically an integer but syntactically a float, so the generator emits float64 — and the reverse also happens, where an API that returns 5 in your sample but 5.5 in production gives you an int field that fails to decode the real response. Neither case is detectable from one sample. Check the API documentation for the intended type and correct it by hand.

What omitempty actually does

This one is widely misunderstood, so it is worth stating precisely. The tag itself affects both directions — it is how keys map on the way in and on the way out. The omitempty option, however, affects encoding only: it tells the encoder to leave zero-valued fields out of the JSON it produces.

It does not make a field optional when decoding. A missing key still leaves the field at its zero value whether omitempty is present or not, because decoding never consults it. The generator emits plain tags without it. Add it yourself only when you control the encoding side and want to slim the output — and note the side effect, that a genuine zero will then be omitted from your JSON too.

The same JSON shape is worth generating types for in whichever language the other end of the wire uses — the JSON to TypeScript converter does the front-end half of exactly this job.

How to use the JSON to Go Struct Converter

Takes about a minute. No signup, no download, your data stays in your browser.

  1. 1
    Open the tool. Scroll up to the JSON to Go Struct Converter above — it loads instantly in your browser, no install needed.
  2. 2
    Enter your values. The fields come pre-filled with realistic defaults so you can see how it works — replace them with your own numbers.
  3. 3
    Read the result. The output updates instantly. Copy or share it — nothing is uploaded to a server, everything stays on your device.

Frequently asked questions

Common questions about the JSON to Go Struct Converter.

Why do my struct fields start with a capital letter when the JSON keys are lowercase?

Because Go's encoding/json uses reflection, which can only reach exported fields — those starting with a capital. A lowercase field is invisible to the decoder, stays at its zero value, and produces no error at all. The json tag bridges the gap by telling the decoder which key maps to the capitalised field.

Can I remove the json tags or reorder the fields?

Reorder freely, since field order does not affect unmarshalling. Do not remove the tags. Without one, Go falls back to a case-insensitive name match, which works for simple keys like id or title but fails on anything containing an underscore or hyphen — user_id will not match a field named UserID, and the failure is silent.

What happens if a JSON field is missing?

The field is set to its zero value with no error: 0 for numbers, empty string for strings, false for booleans, nil for slices. This makes a missing key indistinguishable from an explicitly sent zero. Where that difference matters, change the field to a pointer type such as *int so it is nil when the key was absent, at the cost of a nil check before use.

Why did a value of 2.0 become float64 instead of int?

The generator infers from the sample, and 2.0 has a decimal point, so it reads as float64 even though the value is a whole number. The reverse also happens: a sample containing 5 gives an int field that will fail on a production response of 5.5. One sample cannot settle it — check the API documentation and adjust the type by hand.

What does omitempty do, and why is it not in the generated tags?

It affects encoding only, telling the encoder to leave zero-valued fields out of the JSON it writes. It does not make a field optional when decoding — a missing key still leaves the field at zero regardless. The generator omits it because it has no bearing on unmarshalling. Add it yourself if you control the output and want it slimmer, remembering it will also drop genuine zeros.

Community rating

Discussion (0)

No comments yet. Start the discussion.