100% local — your data never leaves your browser

JSON to Swift — Codable With CodingKeys Written

Turn a JSON sample into Swift structs conforming to Codable. Keys that cannot be property names come back through CodingKeys, spelled out for you.

Instant Private Zero cookies

JSON input

Swift output

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.

Frequently asked questions

When do I get a `CodingKeys` enum?
As soon as one property name differs from its key. `content-type` cannot be a property name, so it becomes `contentType` and the enum maps it back: `case contentType = "content-type"`. Where every name already matches its key, the enum would be noise and is left out — Swift synthesises it.
What is this `JSONValue` enum at the bottom?
A small Codable type for the values the sample could not pin down: `null`, an empty array, a heterogeneous array. Swift has no "any Codable" that round-trips, so the enum enumerates what JSON can hold. It is emitted once, only when something needs it, and you can delete it if you replace those fields with real types.
Should the properties be `let` or `var`?
`let` by default, because a decoded payload is a value. The toggle switches the whole struct to `var` when you are building the object rather than reading it. Mixing the two is a decision per field, and one worth making by hand once the model settles.

Related converters