★ Go struct · from JSON
JSON to Go struct Converter
Go structs with the tags already written. Field names follow Go conventions (UserID, not UserId), optional keys get omitempty, nullable ones become pointers, and timestamps become time.Time.
- Runs in your browser
- No signup
Convert to
Strictness
Your JSON
Go struct
3 types · 16 fieldsimport "time"
type Root struct {
ID int64 `json:"id"`
Email string `json:"email"`
DisplayName string `json:"display-name"`
CreatedAt time.Time `json:"createdAt"`
Plan any `json:"plan"`
Tags []string `json:"tags"`
Team Team `json:"team"`
Invoices []Invoice `json:"invoices"`
}
type Invoice struct {
Number string `json:"number"`
Amount float64 `json:"amount"`
Paid bool `json:"paid"`
PaidAt *time.Time `json:"paidAt"`
Note string `json:"note,omitempty"`
}
type Team struct {
ID string `json:"id"`
Name string `json:"name"`
Website string `json:"website"`
}
Typing APIs by hand?
I set up end-to-end type safety (DB → API → UI) so this never happens again.
How the Go struct mapping works
Each JSON value is read, merged with every other sample of the same key, and then mapped to the closest Go struct type:
| In your JSON | Go struct |
|---|---|
| string | string |
| ISO timestamp | time.Time |
| integer / decimal | int64 / float64 |
| true / false | bool |
| null alongside a value | *T (pointer) |
| key missing in some samples | `json:"key,omitempty"` |
| array | []T |
| mixed values or always null | any |
| nested object | its own named struct |
Worked example
A user record with a nested team, a list of invoices (one missing a note, one with a null payment date) and an awkward display-name key:
{
"id": 1042,
"email": "ada@example.com",
"display-name": "Ada",
"createdAt": "2026-11-07T09:30:00Z",
"plan": null,
"tags": ["beta", "founder"],
"team": {
"id": "7f3c9a2e-1b4d-4c8e-9f2a-6d5e4c3b2a19",
"name": "Analytical Engines",
"website": "https://example.com"
},
"invoices": [
{ "number": "INV-001", "amount": 49.5, "paid": true, "paidAt": "2026-10-01T00:00:00Z" },
{ "number": "INV-002", "amount": 49, "paid": false, "paidAt": null, "note": "Card declined" }
]
}Becomes this Go struct, generated by the same engine that runs the converter above (3 types, 16 fields):
import "time"
type Root struct {
ID int64 `json:"id"`
Email string `json:"email"`
DisplayName string `json:"display-name"`
CreatedAt time.Time `json:"createdAt"`
Plan any `json:"plan"`
Tags []string `json:"tags"`
Team Team `json:"team"`
Invoices []Invoice `json:"invoices"`
}
type Invoice struct {
Number string `json:"number"`
Amount float64 `json:"amount"`
Paid bool `json:"paid"`
PaidAt *time.Time `json:"paidAt"`
Note string `json:"note,omitempty"`
}
type Team struct {
ID string `json:"id"`
Name string `json:"name"`
Website string `json:"website"`
}
Go struct gotchas
Zero values hide missing keys
Without a pointer, a missing int decodes as 0 and you can't tell it from a real 0. Make a field a pointer when absent and zero mean different things.
omitempty only affects encoding
It drops zero values when marshalling. It doesn't make decoding stricter or tell you a key was missing.
int64 for every integer
JSON numbers have no size. int64 is the safe default; narrow to int32 or uint only when you know the range.
Questions developers actually ask
Why are IDs named ID, not Id?
Do I need the import for time?
How do I reject unknown fields?
Is my JSON sent to a server?
How does it know a field is optional?
Other languages
More from the workbench
Fine print
Tools: on the house.
Engineer: by the hour.
A codebase that doesn't need this tool is the upgrade. I set up end-to-end type safety so your API, database and UI agree by construction.
I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.
