Skip to main content
SnipKit

JSON to Go Struct Converter

Generate idiomatic Go struct definitions from JSON — with json/bson/yaml/xml/db tags, time.Time inference, and pointer-based nullables.

Processed locally in your browser

Paste any JSON object or array and copy the generated Go types — fields are PascalCased, nested objects become their own structs, and arrays become slices.

Struct tags
Type inference
JSON
Go

Unlock the full toolkit

Batch processing, no ads, higher limits, and API access.

Go Premium

How to Use

Paste any JSON object or array and copy the generated Go types — fields are PascalCased, nested objects become their own structs, and arrays become slices.

  1. Paste your JSON in the left panel (or click **Load sample** for a quick example). Conversion runs automatically as you type.
  2. Set the **Root struct name** — the top-level struct or type alias. Falls back to <code>AutoGenerated</code> when invalid.
  3. Toggle the **struct tags** you need: <code>json</code> is on by default; enable <code>bson</code> for MongoDB drivers, <code>yaml</code> for go-yaml, <code>xml</code> for encoding/xml, or <code>db</code> for sqlx.
  4. Tick **ISO 8601 strings as time.Time** to auto-detect dates like <code>2024-01-15T10:30:00Z</code> and add <code>import "time"</code>.
  5. Tick **,omitempty** to add the omitempty option to every tag — useful for optional fields and partial responses.
  6. Tick **Use pointer types for null** to render nulls as <code>*interface{}</code> instead of <code>interface{}</code>.
  7. Click **Copy** or **Download** to save the file as <code>.go</code>. Everything happens client-side — your JSON never leaves your browser.

Pair this with the JSON Formatter to clean up input, JSON Validator to spot errors, JSON to YAML, or JSON to XML.

Features

  • Generates one struct per nested object — flattened across the file
  • 5 tag systems: json, bson, yaml, xml, db (mix freely)
  • PascalCase field names with idiomatic initialisms (ID, URL, HTTP, JSON, UUID…)
  • ISO 8601 detection → time.Time + auto-import
  • Pointer types for nullable fields (configurable)
  • Per-tag ,omitempty toggle
  • Reserved Go keyword escape (type, func, range…)
  • Merges objects across array elements for a clean superset struct
  • 100% client-side — your JSON never leaves your browser

Frequently Asked Questions

Why convert JSON to a Go struct?
Go is a statically typed language, so deserialising JSON with <code>encoding/json</code> requires you to declare the receiving type up front. Hand-writing structs for nested API responses is tedious and error-prone — one missing tag silently turns into a zero value at runtime. Generating the struct from a real sample of the data guarantees the field set matches and saves a few minutes per endpoint.
How does the tool handle nested objects?
Each nested object becomes its own named struct, derived from the JSON key (PascalCased). Arrays of objects are merged into a single element struct so you get one clean type even if elements vary slightly. The root struct comes first in the output, then nested types follow in dependency order.
When does it pick int vs float64?
JSON has no integer type — every number is a 64-bit float. The tool inspects the actual value: integers (<code>42</code>, <code>0</code>, <code>-1</code>) become Go <code>int</code>, decimals (<code>3.14</code>, <code>1.0e2</code>) become <code>float64</code>. If you have an array containing both <code>1</code> and <code>1.5</code>, it falls back to <code>[]float64</code> via type unification.
How are nulls represented?
By default, JSON <code>null</code> becomes <code>interface{}</code> — the safe Go fallback that accepts any JSON value. If you tick <strong>Use pointer types for null</strong>, the tool emits <code>*interface{}</code> instead, which lets you distinguish between "field missing", "field null", and "field present" at the cost of slightly more verbose code. For known shapes, edit the result manually to use <code>*string</code>, <code>*int</code>, etc.
What is omitempty and when should I use it?
The <code>,omitempty</code> tag option tells <code>encoding/json</code> to skip the field during marshaling when the value is the zero value (empty string, 0, nil pointer, empty slice). Use it for optional API request fields where you do not want to send <code>"name": ""</code> when the value is unset. Avoid it for response structs where you actually want to see <code>"count": 0</code>.
How are dates and timestamps detected?
Strings matching ISO 8601 patterns — <code>2024-01-15</code>, <code>2024-01-15T10:30:00Z</code>, <code>2024-01-15T10:30:00.123+02:00</code> — are recognised as <code>time.Time</code> when the toggle is on, and <code>import "time"</code> is added automatically. Custom formats (RFC 822, Unix epoch, locale-specific) stay as <code>string</code>; parse them yourself with <code>time.Parse</code>.
What about Go reserved keywords as JSON keys?
Go keywords like <code>type</code>, <code>func</code>, <code>range</code>, <code>chan</code>, <code>select</code> get an underscore suffix when they would collide as a field name. The original key is preserved verbatim in the <code>json</code> tag, so marshalling still produces the correct output. The same logic applies to keys starting with a digit — they get an underscore prefix.
Can I use this with MongoDB / GORM / sqlx?
Yes — toggle the relevant tag block: <code>bson</code> for the official MongoDB driver, <code>db</code> for sqlx (Go SQL toolkit), <code>yaml</code> for go-yaml configurations, <code>xml</code> for encoding/xml. Tags compose freely, so you can have <code>`json:"name" bson:"name" db:"name"`</code> if a single struct serves multiple drivers. GORM uses field name conventions plus its own <code>gorm:"..."</code> tag — you would add that manually.
How does it pick struct names for nested fields?
The JSON key is converted to PascalCase, with common initialisms preserved (<code>user_id</code> → <code>UserID</code>, not <code>UserId</code>). For arrays, the singular form is used (<code>posts</code> → <code>Post</code>). If two distinct nested objects share a key (e.g. <code>user.address</code> and <code>company.address</code>) the second registration gets a numeric suffix (<code>Address2</code>) so the file stays compilable.