swift-json-schema

0.14.0

Generate, parse, and validate JSON Schema in Swift
ajevans99/swift-json-schema

What's New

v0.14.0

2026-09-13T05:19:08Z

Adds lossless JSON numbers and exact Decimal support, including automatic @Schemable support. Also introduces typed schema projections and improves reference handling, concurrent validation, and parser reliability.

What's Changed

  • Refresh README and linked DocC guides by @ajevans99 in #174
  • Remove scratch JSONSchemaClient executable by @ajevans99 in #175
  • ci: run the full test suite on Linux by @ajevans99 in #176
  • test: fail loudly when conformance fixtures cannot load by @ajevans99 in #180
  • Fix numeric object-key lookup through JSON Pointer by @ajevans99 in #178
  • Fix RFC 3339 date-time format validation by @ajevans99 in #181
  • Fix compressed and IPv4-embedded IPv6 format validation by @ajevans99 in #177
  • fix(ci): fail incomplete API compatibility scans without hiding intentional breaks by @ajevans99 in #179
  • Fix main CI failures from outdated fixture-loader calls by @ajevans99 in #183
  • Add explicit typed schema projections and codegen runtime fixes by @ajevans99 in #184
  • Refactor macro expansion into parse, plan, and emit stages by @ajevans99 in #182
  • fix: exclude test targets from Codecov coverage by @ajevans99 in #188
  • fix: make JSON container parsing stack-safe at depth 256 by @ajevans99 in #197
  • fix: preserve reference and meta-schema initialization when decoding Schema by @ajevans99 in #196
  • Add reproducible benchmark baselines and CI checks by @ajevans99 in #172
  • fix: select compatible @Schemable initializer overloads by @ajevans99 in #194
  • fix: isolate state when reusing Schema concurrently by @ajevans99 in #195
  • Expand OrderedJSON throughput and Foundation round-trip benchmarks by @ajevans99 in #185
  • test: cover validation result serialization fidelity by @ajevans99 in #189
  • Expand JSONSchema benchmarks with pinned real-world corpora by @ajevans99 in #186
  • feat!: preserve JSON number literals and support exact Decimal parsing by @ajevans99 in #198
  • docs: clarify count constraint error bound payloads by @ajevans99 in #200

Breaking Changes

  • Numeric representation: Replace .integer and .number enum pattern matches with .numberLiteral. Both names remain available as construction helpers. Numeric comparison error payloads now use JSONNumberLiteral; count/length error payloads remain Int.
  • Non-finite numbers: Removed the non-conforming-float serialization strategy and associated error API. .number(Double) requires a finite value; use throwing JSONNumberLiteral construction for untrusted inputs.
  • Default parsing: Schema and builder string-parsing APIs now use OrderedJSON. Existing calls without decoder: remain source-compatible; explicit JSONDecoder overloads are deprecated. Foundation interoperability does not guarantee original numeric precision or spelling.
  • Stricter diagnostics: Invalid typed additional-property values now fail parsing instead of being silently dropped. Unsupported macro inputs that were previously ignored or defaulted now produce diagnostics.

See the numeric migration guide for accessor changes, conversion behavior, and migration examples.

Full Changelog: v0.13.2...v0.14.0

Swift JSON Schema

CI Latest release SPI Versions SPI Platforms Supported Dialects Draft 2020-12 codecov

Generate JSON Schema from Swift types, validate JSON against Draft 2020-12 schemas, and parse validated input into typed Swift values.

Use the @Schemable macro or a composable result-builder DSL to define your schemas, or load existing schema documents with the standalone validator. The package also provides structured validation diagnostics, Foundation type conversions, and deterministic JSON serialization.

Try the live playground · Documentation · Latest release

Quick start

Define a model once, then use its schema to generate JSON Schema, parse valid input, and reject invalid data:

import JSONSchemaBuilder

@Schemable
struct Person {
  @StringOptions(.minLength(1))
  let name: String

  @NumberOptions(.minimum(0))
  let age: Int
}

let schema = Person.schema.definition()
print(try schema.jsonValue.serialized(options: .pretty))

let person: Person = try Person.schema.parseAndValidate(
  instance: #"{"name": "Ada", "age": 37}"#
)
print(person.name) // Ada

let result = schema.validate(["name": "Ada", "age": -1])
print(result.isValid) // false

parseAndValidate checks the schema's constraints and returns your Swift type, or throws with parsing and validation details. Use schema.validate when you only need a validation result, without constructing a model. Learn about parsing and validation.

Build schemas directly

Result builders infer their output types from the properties you declare:

let personSchema = JSONObject {
  JSONProperty(key: "name") {
    JSONString().minLength(1)
  }
  .required()

  JSONProperty(key: "age") {
    JSONInteger().minimum(0)
  }
  .required()
}

let parsed: (String, Int) = try personSchema.parseAndValidate(
  instance: #"{"name": "Ada", "age": 37}"#
)

The output is a tuple in property declaration order. parseAndValidate returns it directly; parse returns Parsed<(String, Int), ParseIssue>. Add .map(Person.init) to the builder to construct a Person instead.

Builders also support arrays, schema compositions, references, and conditional rules. Explore the DSL.

Validate an existing schema

No Swift model or macro is required when your schema already exists:

import JSONSchema

let externalSchema = try Schema(
  instance: #"{"type": "string", "minLength": 3}"#
)
let validation = try externalSchema.validate(instance: #""hi""#)
print(validation.isValid) // false

let diagnostics = try validation.renderedOutput(level: .basic)
print(try diagnostics.serialized(options: .pretty))

The diagnostics identify the failing keyword and input location. Learn about validation output.

Installation

Add the package in Xcode with File > Add Package Dependencies, or add it to Package.swift:

dependencies: [
  .package(url: "https://github.com/ajevans99/swift-json-schema", from: "0.13.2")
]

from: sets a minimum version and allows compatible updates; it does not pin an exact release. See the latest release for the current version.

Choose the products your target uses. For the quick start:

targets: [
  .target(
    name: "YourTarget",
    dependencies: [
      .product(name: "JSONSchemaBuilder", package: "swift-json-schema")
    ]
  )
]
Library Use it for
JSONSchema Loading and validating existing JSON Schema documents, references, formats, and diagnostics. Re-exports OrderedJSON.
JSONSchemaBuilder Generating schemas and parsing typed values with result builders and @Schemable. Builds on JSONSchema.
JSONSchemaConversion Converting schema-defined strings into UUID, URL, and Date values. Builds on JSONSchemaBuilder.
OrderedJSON Order-preserving JSON parsing and serialization, independently of schema validation.

Requirements: Swift 6.1 or later. Package deployment minimums are macOS 13, iOS 16, Mac Catalyst 16, watchOS 9, tvOS 16, and visionOS 1. Generated schemas and variadic object builders require macOS 14, iOS 17, Mac Catalyst 17, watchOS 10, or tvOS 17 on those platforms. The package also builds on Linux.

Schema-first code generation

Starting with JSON Schema rather than Swift? The companion swift-json-schema-codegen package generates typed builder components from schema documents, completing the other direction: JSON Schema to Swift.

With its separate JSONSchemaCodegen product installed, an inline schema becomes a typed parser:

import JSONSchemaCodegen

@Schema("""
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name", "age"]
}
""")
enum PersonSchema {}

let person = try PersonSchema.schema.parseAndValidate(
  instance: #"{"name": "Ada", "age": 37}"#
)
print(person.name) // Ada

The output fields are inferred from the schema; you do not repeat their Swift types. A CLI and SwiftPM build-tool plugin also generate components from schema files, useful for shared API contracts, configuration formats, and design tokens. See the codegen guide for installation, supported schemas, and file-based workflows.

Explore the capabilities

The guides on Swift Package Index cover the details without requiring you to read generated macro code:

Guide What you can do
Generate schemas from Swift types Model nested and recursive data, enums, collections, custom coding keys, and nullable properties.
Build schemas manually Compose reusable schemas with result builders, references, and dynamic object properties.
Model conditional rules Express property dependencies and if/then/else validation.
Parse into Swift values Combine parsing and validation, map outputs, and select composition branches.
Validate existing schemas Load schema documents, resolve references, and enable built-in or custom formats.
Inspect validation output Choose flag, basic, detailed, or verbose diagnostics.
Convert Foundation types Parse UUIDs, URLs, and dates using custom property schemas.
Emit deterministic JSON Produce reproducible schemas and validation results, and understand the serialization guarantees.

Ecosystem and integrations

  • swift-json-schema-playground (live demo) - an in-browser validation playground running the package as WebAssembly via SwiftWasm.
  • swift-mcp-toolkit - strongly typed tools built on the official Model Context Protocol Swift SDK.
  • SwiftFunctionToolsExperiment - type-safe OpenAI API function tool calls using schemas built with this library.
  • Bowtie - cross-language JSON Schema conformance reports, with a dedicated Swift harness.
  • A2UI - agent-generated user interfaces, with Swift core and component-catalog libraries that use this package.

Have a project to share? Open a PR to add it here.

License

Released under the MIT license. See LICENSE for details.

Description

  • Swift Tools 6.1.0
View More Packages from this Author

Dependencies

Last updated: Sun Sep 13 2026 14:52:53 GMT-0900 (Hawaii-Aleutian Daylight Time)