Skip to content

JSON to Swift

Generate Swift Codable structs from a JSON sample.

Input

What this tool does

Generate Swift Codable structs from a JSON sample. Properties are emitted as let with Swift-idiomatic types; fields containing null in the sample become Optionals. JSON keys that collide with Swift reserved words (public, class, …) are escaped with backticks. Powered by quicktype, runs entirely in your browser.

How to use it

Paste JSON (or load the example) and read the Swift structs on the right. Each nested object becomes its own Codable struct; the output works with Foundation’s JSONDecoder without further annotation when JSON keys match Swift property names.

Input: {"id":42,"name":"devsmiths","createdAt":"2024-03-11T08:24:00Z","stars":1280,"public":true,"contributors":[{"login":"ada","commits":51,"admin":true},{"login":"linus","commits":33,"admin":false}],"homepage":null}

Output (Swift):

import Foundation

struct Root: Codable {
    let id: Int
    let name: String
    let createdAt: String
    let stars: Int
    let `public`: Bool
    let contributors: [Contributor]
    let homepage: String?
}

struct Contributor: Codable {
    let login: String
    let commits: Int
    let admin: Bool
}

Limits and edge cases

  • Output uses struct with Codable conformance, not class. Structs are Swift’s value type — they suit JSON DTOs perfectly. If you need reference semantics (e.g. for SwiftUI @ObservableObject), wrap the struct in a class by hand.
  • Properties are let (immutable). Mutate via var copy = original and rebuild, or change to var by hand for fields you genuinely mutate.
  • JSON keys that are Swift reserved words (public, class, default) are wrapped in backticks in the Swift source (let `public`: Bool); JSONDecoder sees the bare key.
  • camelCase / snake_case mismatch: by default the generator emits no CodingKeys enum, which means JSON keys must match Swift property names character-for-character. For snake_case JSON, set decoder.keyDecodingStrategy = .convertFromSnakeCase instead of generating an explicit CodingKeys per struct.
  • Date strings stay as String. Set decoder.dateDecodingStrategy = .iso8601 and change the property type to Date by hand — there’s no per-field date strategy in JSONDecoder.
  • Single-sample inference: keys absent in the sample don’t become Optional automatically. Toggle all optional for every field to use Optional semantics.

Frequently asked questions

Why struct + Codable, not class?
Structs are Swift's value type and work perfectly as JSON DTOs — copy semantics, no reference cycles, thread-safe by construction. Codable is the stdlib protocol (Encodable + Decodable) that JSONDecoder / JSONEncoder operate on. For reference semantics (SwiftUI @ObservedObject, persistence), wrap the struct in a class by hand or use @Observable on a wrapper.
How do I handle camelCase JSON vs snake_case JSON keys?
JSONDecoder has `keyDecodingStrategy`. For snake_case JSON: `decoder.keyDecodingStrategy = .convertFromSnakeCase`. The generated structs use camelCase property names (Swift convention); the strategy bridges automatically. For mixed cases or keys that don't follow either convention, generate a `CodingKeys` enum explicitly per struct — the generator doesn't do this by default because the global strategy is usually all you need.
What about Date fields — can I get Date instead of String?
Yes, with two steps. Change the property type from String to Date in the generated struct, and set `decoder.dateDecodingStrategy = .iso8601` (or `.formatted(...)` for non-ISO formats). The dateDecodingStrategy is global per decoder — every Date property gets the same treatment. For per-field control, write a custom `init(from:)` that handles each Date field individually.
Why is my JSON key public wrapped in backticks?
Because `public` is a Swift access modifier. Backticks let you use reserved words as identifiers (`let `public`: Bool`) without renaming the property. JSONDecoder sees the bare key (`public`) and binds it to the backtick-quoted Swift property. If you'd rather rename, add a `CodingKeys` enum: `case isPublic = "public"` and use `isPublic` as the Swift name.
How do I handle JSON keys that aren't valid Swift identifiers at all?
Keys with hyphens or leading digits (`2024-tax-year`) can't be Swift property names even with backticks. Use an explicit `CodingKeys` enum: `case taxYear = "2024-tax-year"`, with `taxYear` as the Swift-side name. The generator detects this and emits the CodingKeys enum automatically when a JSON key isn't a valid Swift identifier under any escaping.
Can I use the generated structs with SwiftData / Core Data?
Not directly — both frameworks need `@Model` (SwiftData) or `NSManagedObject` (Core Data) base classes, which are reference types with persistence machinery. The generated structs are pure value types. Use them as the DTO layer (parse JSON → struct → pass to a mapping function → write to SwiftData model). One-way mapping keeps the parse layer fast and the persistence layer obvious.

Content reviewed by