JSON to Swift Struct
Generate Swift Codable struct definitions from a JSON sample.
Overview
The JSON-to-Swift converter produces Codable struct definitions from a sample JSON document. Property names are camelCased, types are inferred, and CodingKeys are added when the original JSON keys don't match Swift's naming conventions.
iOS and server-side Swift developers reach for a json to swift converter when consuming a REST API or a third-party SDK that returns JSON. Pasting a real response yields a struct ready to pass to JSONDecoder().decode(_:from:) without further fiddling.
How it works
The generator walks the JSON tree, creates a struct for the root, and recursively creates structs for each nested object. JSON keys are camelCased into idiomatic Swift property names; if any key conflicts with camelCase rules (snake_case keys, leading underscores), a CodingKeys enum is emitted to preserve the original mapping.
Type inference maps JSON to Swift: strings to String, integers to Int, decimals to Double (or Decimal on opt-in), booleans to Bool, arrays to [T]. Optional properties (T?) are used where the sample shows null or where a key is missing in some elements.
Examples
Sample:
{ "id": 1, "first_name": "Alice", "tags": ["admin","ops"], "address": { "city": "Berlin" } }
struct Root: Codable {
let id: Int
let firstName: String
let tags: [String]
let address: Address
enum CodingKeys: String, CodingKey {
case id
case firstName = "first_name"
case tags
case address
}
}
struct Address: Codable {
let city: String
}
FAQ
When do CodingKeys get added?
Only when at least one property name differs from its JSON key — typically when snake_case keys get camelCased, or when a JSON key isn't a valid Swift identifier. If every key already matches, the enum is omitted to keep code clean.
Can I use keyDecodingStrategy = .convertFromSnakeCase instead?
Yes — toggle the option and the generator skips emitting CodingKeys for snake_case keys, expecting your decoder to do the conversion automatically.
Are dates decoded as Date automatically?
ISO 8601 timestamps stay as String by default because Swift's Date decoding requires choosing a strategy (iso8601, secondsSince1970, custom). Configure the option to emit Date if your decoder already has the right strategy.