JSON to Go Struct Converter

Generate Go structs with json tags from JSON

What is a JSON to Go Struct Converter?

A JSON to Go struct converter turns a raw JSON sample into a ready-to-use Go struct definition, complete with json:"..." field tags. Instead of hand-writing a struct for every API response, config file, or database row, you paste the JSON and get accurate, compile-ready Go in a fraction of a second — entirely in your browser.

Go’s encoding/json package maps JSON into structs by matching struct tags to keys, but you still have to write the struct. For anything beyond a trivial payload, transcribing nested objects, slices, and the right numeric types by hand is tedious and easy to get wrong. This tool automates the boring part: it walks the JSON structure, infers a Go type for every value, exports and renames fields to satisfy Go’s visibility rules, attaches the correct tags, and emits clean code you can drop straight into your package.

Everything happens client-side. Your JSON never leaves the page, which matters when you’re pasting an internal API response that contains real user data or private field names. This is the Go counterpart to our JSON to TypeScript converter — same idea, idiomatic Go output.

How to Convert JSON to Go

  1. Paste your JSON into the input area above. Both a single object and an array of objects are supported as the top-level value.
  2. Click Convert (or press Ctrl+Enter) to generate the Go struct.
  3. Adjust the settings if needed: rename the root struct, switch between inline and named nested structs, add omitempty, or turn on pointers for nullable and optional fields.
  4. Copy the result with the Copy button or Ctrl+Shift+C and paste it into your .go file.
  5. Clear the workspace with Ctrl+L when you’re done.

For the most accurate results, paste an array of several records rather than a single object. With multiple samples the converter can tell which keys are always present and which are optional, and it merges every field it sees into one struct so nothing is missed.

int vs int64 vs float64: How Numbers Are Inferred

JSON has exactly one number type, but Go has many, so the converter has to make a sensible choice:

  • Whole numbers become int — the idiomatic default for counts, IDs, and sizes.
  • Large whole numbers beyond the signed 32-bit range (roughly ±2.1 billion, e.g. a Unix-nanosecond timestamp or a Twitter/X snowflake ID) become int64 so they never overflow on a 32-bit platform.
  • Numbers with a decimal point become float64, Go’s default floating-point type.
  • Mixed samples — a field that is 5 in one record and 5.5 in another — widen to float64 so both fit.

This matters because encoding/json decodes every JSON number into float64 when you unmarshal into an interface{}. Generating a concrete struct with real integer types is the whole reason to define one: you get int64 IDs instead of lossy float64 values, and the compiler catches type mistakes for you.

Inline vs Named Nested Structs

When your JSON contains nested objects, there are two idiomatic ways to model them in Go, and this tool supports both:

  • Inline (default) embeds each nested object as an anonymous struct { ... } directly on the field. Everything stays in a single declaration, which is compact and matches the widely used json-to-go convention most Go developers recognize.
  • Named pulls every nested object into its own top-level type — type Address struct { ... } — and references it by name. Choose this when a nested shape is reused across fields, when you want to attach methods to it, or when deeply nested JSON would otherwise produce an unreadable wall of indentation.

Both compile to the same wire format. Pick inline for a quick paste-and-go struct, named when the nested types deserve their own identity in your codebase.

Optional Fields, null, omitempty, and Pointers

Two of the most common sources of runtime bugs are missing fields and null fields, and Go models them differently from a language with built-in optionals:

  • A missing key (present in some records of an array, absent in others) is detected as optional. Enable omitempty and it gets json:"avatar,omitempty", so the field is omitted from the JSON output when it holds a zero value.
  • A null value can’t be represented by a plain value type — 0, "", and false are indistinguishable from a real zero. Enable Pointers for nullable/optional and those fields become pointer types like *string or *int, where nil means “absent or null” and a non-nil pointer means “present.”

Both options are off by default so the baseline output matches the familiar json-to-go format. Turn them on when you need to round-trip data faithfully — for example, distinguishing “the user did not send an age” from “the user’s age is 0.”

Common Errors and Edge Cases

  • Invalid JSON. The most frequent issue is a trailing comma, single quotes, or an unquoted key — none of which are legal JSON. The tool reports the exact parse error. Run your text through a JSON formatter or JSON validator first if you’re unsure.
  • A single sample object. With only one record, every key looks required. If your production data has optional fields, paste a representative array so optionality is detected correctly.
  • Empty arrays. [] gives the converter nothing to infer from, so it produces []interface{}. Replace it with a populated sample if you need a real element type.
  • Heterogeneous arrays. Go has no union types, so an array like [1, "a", true] becomes []interface{}. Keep arrays homogeneous where you can, or handle the mixed values after unmarshaling.
  • Numbers that are really enums or flags. "status": 1 becomes int, not a named constant. Define your own typed constants if the field is an enum.
  • Timestamps as strings. ISO-8601 strings arrive as string. Go can’t know they’re times — change the field to time.Time yourself and they’ll parse automatically via encoding/json.

JSON to Go Use Cases

Go developers reach for a JSON-to-struct converter constantly:

  • Typing API responses. Paste a sample response from a REST or GraphQL endpoint and get a struct to json.Unmarshal into, with real integer and boolean types instead of map[string]interface{}.
  • Config and manifest files. Generate structs for YAML/JSON config so your service fails fast on a malformed field instead of silently reading a zero value.
  • Third-party webhooks. Turn a sample webhook body into a struct so you can handle Stripe, GitHub, or Slack events with autocomplete and compiler checks.
  • Bootstrapping clients. When wrapping an external API, converting its JSON responses is the fastest way to scaffold your client’s data models.

JSON to Go vs map[string]interface

You can unmarshal any JSON into map[string]interface{} and skip the struct entirely — but you pay for it. Every access needs a type assertion, every number comes back as float64, typos in key names fail silently at runtime, and there’s no autocomplete. A generated struct gives you compile-time safety, correct numeric types, IDE support, and self-documenting field names — for the cost of one paste. For quick throwaway scripts a map is fine; for anything you maintain, generate the struct. Paste, convert, copy, done.

Frequently Asked Questions

How do I convert JSON to a Go struct?

Paste your JSON into the input box and click Convert (or press Ctrl+Enter). The tool parses the JSON, infers a Go type for every value, and outputs a struct with correct json tags mapping each field back to its original key. Nested objects become nested structs (inline by default, or separate named types if you switch the option), and the top-level struct is named AutoGenerated. You can rename the struct, choose inline vs named structs, add omitempty, and use pointers for nullable fields in the settings panel.

Does this tool send my JSON to a server?

No. The entire conversion runs in your browser using JavaScript. Your JSON is parsed and turned into Go locally — nothing is uploaded, logged, or stored. You can confirm this by opening your browser's network tab: there are no requests while you convert. That makes it safe for API responses that contain internal fields or real user data.

How does it choose between int, int64, and float64?

JSON has a single number type, so the converter inspects each value. A whole number becomes int, unless its magnitude exceeds the 32-bit range (about 2.1 billion), in which case it becomes int64 to avoid overflow on 32-bit builds. Any number with a decimal point becomes float64. If the same field is sometimes an integer and sometimes a float across your samples, it is widened to float64. Note that Go's encoding/json actually decodes all JSON numbers into float64 unless a concrete numeric type is specified — which is exactly why generating an explicit struct is useful.

What is the difference between inline and named nested structs?

Inline (the default) embeds nested objects as anonymous struct literals directly inside the parent field, which keeps everything in one block and matches the popular json-to-go convention. Named structs pull each nested object out into its own top-level type (Address, User, and so on) and reference it by name. Inline is compact and self-contained; named is better when you want to reuse a nested type elsewhere, add methods to it, or keep deeply nested JSON readable. Switch between them in the settings.

How are optional and null fields handled?

If you paste an array of objects and a key appears in some elements but not others, it is treated as optional. With 'omitempty' enabled, optional fields get a json:"key,omitempty" tag so they are dropped from output when empty. With 'Pointers for nullable/optional' enabled, those fields (and fields that contain null) become pointer types like *string, letting you distinguish an absent or null value from a zero value such as 0 or an empty string. Both options are off by default to match standard json-to-go output.

Why are my field names capitalized, and how do the json tags work?

Go only marshals and unmarshals exported (capitalized) struct fields, so the converter turns user_id into UserID and content-type into ContentType. To preserve the original JSON key, each field gets a struct tag like `json:"user_id"`. Common initialisms (ID, URL, API, HTTP, JSON) are upper-cased to follow Go naming conventions. Your data is never changed — only the generated Go is adjusted so it compiles and round-trips correctly.

Is the generated Go ready to use?

Yes. The output is valid, compile-ready Go you can paste into a .go file and use with encoding/json's Marshal and Unmarshal. It is gofmt-compatible — run gofmt or goimports if you want columns aligned exactly to your editor's tab stops. Because types are inferred from a sample, review the result against your real API: a field that is always a whole number in your sample might be a float or nullable in production. Paste a representative array and use the pointer option to tighten the struct before shipping.