Paste JSON and get typed models for Go, Python, C#, Java, Kotlin, Rust or Swift. List items are merged and numbers are typed from how they are written. Nothing is uploaded.
Swift decodes JSON with JSONDecoder into types that conform to Codable. This page writes those structs from a sample: each nested object becomes its own struct, a list becomes an array, whole numbers are Int and numbers with a fraction are Double. A key that is missing from some items, or null in some, becomes an Optional, which the synthesized decoder reads with decodeIfPresent. Names are converted to camelCase, and when any name differs from its key the struct gets a CodingKeys enum that maps each property to the original key. A key that is a Swift keyword, such as default or class, is written between backticks. Timestamps become Date and the file reminds you to set dateDecodingStrategy to .iso8601, which does not accept fractional seconds, so those need a custom strategy. Integers beyond the Int range become Decimal. Values with no single type become a small JSONValue enum that is added at the end of the file, because Codable has no built-in any type.
To turn JSON into typed code, paste an object or a list of objects, choose Go, Python, C#, Java, Kotlin, Rust or Swift, and copy the generated structs, models or classes. Every nested object becomes its own type, named from its key in PascalCase, so the key orders gives a type Order when it holds a list. The sample opens as Go: id becomes ID int64 with the tag json:"id", user_name becomes UserName, and the ISO timestamp created becomes time.Time. Go gets json tags, Python gets Pydantic v2 BaseModel classes or dataclasses, C# gets records or classes with System.Text.Json attributes, Java gets records or plain classes with optional Jackson @JsonProperty annotations, Kotlin gets data classes with optional kotlinx.serialization annotations, Rust gets serde structs with Serialize and Deserialize derives, and Swift gets Codable structs with CodingKeys where a name differs from the key.
The tool reads every item of a list and merges their shapes, because one sample item rarely shows the whole truth. A key that is missing from some items is optional: a Go pointer (a slice stays a nil-able slice) with omitempty, a Python Optional with a None default, a C# or Kotlin nullable type, a Rust Option with serde default. A key whose value is null in some items is nullable but still required. If one field holds a number in one item and text in another, no single type fits, so it falls back to the language's any type with a comment saying the types were mixed. An empty list has no items to read, so its element type is also the any type. Numbers are typed from how they are written, not from their value: 7 is an integer, while 1.0 and 1e3 are floats, because a strict integer decoder rejects them. An integer outside the signed 64-bit range, such as 18446744073709551615, gets the language's big type (Go *big.Int, C# and Java BigInteger, Swift Decimal, Rust serde_json::Number) instead of being rounded through a double. A field that mixes such an integer with decimals gets a lossless decimal type (json.Number, BigDecimal, Decimal, JsonElement), never a double, and a Swift integer of more than 38 digits is typed String because Decimal would round it.
Field names follow each language's style: PascalCase in Go and C#, camelCase in Java, Kotlin and Swift, snake_case in Python and Rust. Go uses its initialisms, so id becomes ID and url becomes URL. A key that is a keyword in the language gets a safe name and the original key is kept: a trailing underscore for Rust (including gen, reserved since the 2024 edition), Python and Java, backticks for Kotlin and Swift. Go struct tags cannot name every legal JSON key: a key of - is written as the tag "-,", while a key with a comma, a quote or nothing at all cannot be a tag name, so that field is marked with a comment. Generated type names avoid the names the output depends on, such as None in Python or List in Java. Two keys that give the same name get a number, and a key that starts with a digit gets a prefix. With Detect timestamps on, only full RFC 3339 timestamps such as 2024-05-01T10:30:00Z (a real calendar day, seconds, and a Z or offset) become time types. Date-only values stay strings. Rust keeps String so you do not need a date crate.
The sample decides everything: a field that is always present in your sample is required in the output, so check optional fields against your real data or an API specification. The tool does not know enums, string formats other than RFC 3339 timestamps, or value ranges. It accepts up to 500,000 characters of strict JSON and nested data up to 60 levels, and pastes over 20,000 characters are converted in a background worker so the page stays responsive. The output targets Go 1.18 or newer (for any), Pydantic v2, C# 9 records, Java 16 records with Jackson 2.12 or newer, kotlinx.serialization, serde 1 and Swift 5 Codable. The work happens in your browser and the JSON is not uploaded or stored; only your option choices are remembered. For TypeScript use the JSON to TypeScript tool.
Only when a property name differs from its key, for example userName for user_name. If every key is already a valid camelCase name, the synthesized keys are enough and the enum is left out.
A field with mixed types, only null, or an empty list has no single Swift type. JSONValue decodes any JSON value and is generated only when needed.
Not with .iso8601. 2024-05-01T10:30:00Z works, but 2024-05-01T10:30:00.5Z needs a custom decoding strategy or ISO8601DateFormatter with fractional seconds.
Paste the JSON, leave the language on Go and copy the result. A key id with a number becomes ID int64 with the tag json:"id", and a key missing from some list items becomes a pointer with omitempty (a list stays a slice, which is nil when the key is absent).
A key is optional when it is missing from at least one object in a list, for example coupon in 1 of 2 orders. Keys that are present in every object, or in a single object sample, are required, even when the value is null in some.
From the written form. 7 is an integer (int64, long, i64), while 1.0 and 1e3 are floats, and one float in a list makes the whole field a float. An integer beyond 9,223,372,036,854,775,807 gets a big type such as BigInteger.
Yes. Choose Python and then Pydantic v2 or dataclass. Pydantic uses BaseModel and Field(alias=...) for keys like user-name, and a dataclass puts fields with defaults last because Python requires it.
A field that is only null in the sample, an empty list, or a field that holds a number in one item and text in another gives no single type, so it becomes the any type (any, Any, object, JsonElement, serde_json::Value) with a comment. Add a sample item with a real value to fix it.
No. The code is generated in your browser, in this tab, and no server receives the JSON. Your option choices are saved in this browser; the JSON is not.