What this tool does
A JSON sample becomes Swift structs conforming to Codable.
{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
struct Root: Codable {
let id: Int
let firstName: String
let address: Address
}
struct Address: Codable {
let city: String
}
JSONDecoder reads that directly. Nested objects get their own struct; an array of objects at the root gets a typealias, so the list has a name too.
CodingKeys where the name had to change
A property name cannot contain a dash, cannot start with a digit, and a keyword needs backticks. When a key cannot be a name as it stands, the mapping is written out:
struct Root: Codable {
let contentType: String
let `class`: Int
let f2fa: Bool
enum CodingKeys: String, CodingKey {
case contentType = "content-type"
case `class`
case f2fa = "2fa"
}
}
Note `class` keeps its key without a mapping: backticks change how Swift reads the name, not what it is. The enum lists every case once it exists, because a partial CodingKeys would silently drop the properties it omits.
JSONValue, and why it is there
A null, an empty array or a mixed array leaves nothing to infer. Swift has no ready-made “any JSON value” that both decodes and encodes, so a small enum is emitted once, at the end:
let nickname: JSONValue?
let tags: [JSONValue]
It handles the six things JSON can hold and nothing else. If you later know the field is a nullable string, String? replaces it and the enum can go.
What a sample cannot say
Only a null produces an optional. Everything else is non-optional, because the document had a value — and a ? you add later is one character, while a wrong one hides a missing field until it matters.
Int and Double come from how the number was written, not from its value: 3 gives Int, 3.0 gives Double. That distinction matters in Swift, where decoding 3.5 into an Int throws rather than rounding.
Private by design
Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.