objecthub/swift-yamlkit
YamlKit is a pure Swift implementation of YAML 1.2.2 for
Installation
Add YamlKit to the dependencies of your Package.swift:
dependencies: [
.package(url: "https://github.com/objecthub/swift-yamlkit.git", from: "1.0.0")
],
targets: [
.target(name: "MyTarget", dependencies: [
.product(name: "YamlKit", package: "swift-yamlkit")
])
]Usage
The examples below give a quick overview. USAGE.md explains the main use cases in more depth: decoding and encoding strategies, error handling, working with node trees, custom schemas, and streaming with events.
Decoding
import YamlKit
struct Service: Codable {
var image: String
var replicas: Int
var ports: [Int]
var environment: [String: String]
}
let yaml = """
image: nginx:1.27
replicas: 3
ports: [80, 443]
environment:
TZ: Europe/Zurich
"""
let service = try YAMLDecoder().decode(Service.self, from: yaml)Plain scalars are interpreted according to the YAML 1.2 core schema (3 is an integer, true a boolean, ~ is null, "3" is a string). Errors are reported as DecodingError values whose context includes the coding path and the line and column of the problem.
Encoding
let encoder = YAMLEncoder()
encoder.outputFormatting = [.sortedKeys]
print(try encoder.encodeToString(service))environment:
TZ: Europe/Zurich
image: nginx:1.27
ports:
- 80
- 443
replicas: 3Strategies and Options
let decoder = YAMLDecoder()
// runs-on → runsOn
decoder.keyDecodingStrategy = .convertFromKebabCase
// 2001-12-14t21:59:43.10-05:00
decoder.dateDecodingStrategy = .timestamp
// <<: *defaults
decoder.parseOptions.resolvesMergeKeys = true
let encoder = YAMLEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.outputFormatting = [.explicitDocumentStart,
.indentlessSequences]
encoder.indentation = 4Streams with multiple documents are supported via decodeAll(:from:) and encodeAll(:).
Nodes
let root = try YAML.parse("""
name: YamlKit
tags: [swift, yaml]
""")
print(root?["tags"]?[0]?.string ?? "") // swift
let document: YAMLNode = ["name": "YamlKit", "version": 1, "tags": ["swift", "yaml"]]
print(try YAML.serialize(document))Events
var parser = try YAMLParser(string: "[a, b]")
while let event = try parser.next() {
print(event.kind)
}
let text = try YAML.emit(try YAML.parseEvents("{a: 1}"))Architecture
YamlKit implements the processing model of chapter 3 of the specification as separate layers:
parse compose decode
YAML text ──────────▶ events ──────────▶ nodes ──────────▶ Swift values
◀────────── events ◀────────── nodes ◀────────── Swift values
emit serialize encode| Directory | Contents | |----------------------------|---------------------------------------------------------------| | Sources/YamlKit/Reader | Encoding detection and line break normalization | | Sources/YamlKit/Scanner | Tokenizer: indentation, implicit keys, scalars, properties | | Sources/YamlKit/Parser | YAMLParser and YAMLEvent | | Sources/YamlKit/Node | YAMLNode and the composer (tag resolution, aliases) | | Sources/YamlKit/Schema | YAMLSchema with the core, JSON, and failsafe schemas | | Sources/YamlKit/Emitter | YAMLEmitter and the serializer | | Sources/YamlKit/Codable | YAMLDecoder and YAMLEncoder |
Documentation
The DocC documentation contains API reference, a getting started guide, and a description of the architecture. In Xcode, choose Product ▸ Build Documentation.
Without Xcode, use Scripts/build-documentation.sh. It extracts the symbol graph with SwiftPM and runs the docc tool of the Swift toolchain (found on the PATH, or via xcrun on macOS), so the package needs no documentation plugin dependency:
# .build/YamlKit.doccarchive
Scripts/build-documentation.sh archive
# live preview at http://localhost:8080/documentation/yamlkit
Scripts/build-documentation.sh previewTo publish the documentation on a static web server such as GitHub Pages, run:
Scripts/build-documentation.sh site swift-yamlkitThe website is written to .build/docs-site. The second argument is the hosting base path, i.e. the URL path under which the site is served; swift-yamlkit matches https://<user>.github.io/swift-yamlkit/. Omit it if the site is served from the root of a domain. Copy the contents of .build/docs-site to the web server (for GitHub Pages, e.g. to the docs folder of the publishing branch); the documentation is then available at <base URL>/documentation/yamlkit/.
The script performs these steps, which can also be run by hand:
swift package dump-symbol-graph --minimum-access-level public
# prints "Files written to <directory>"; copy <directory>/YamlKit*.symbols.json
# into a separate directory, e.g. .build/symbol-graphs
docc convert Sources/YamlKit/Documentation.docc \
--fallback-display-name YamlKit --fallback-bundle-identifier org.objecthub.YamlKit \
--additional-symbol-graph-dir .build/symbol-graphs \
--transform-for-static-hosting --hosting-base-path swift-yamlkit \
--output-path .build/docs-siteOn macOS, use xcrun docc if docc is not on the PATH.
Development with Xcode
YamlKit is a plain Swift package; there is no separate Xcode project. Open the package directly in Xcode:
xed . # or: open Package.swift, or File ▸ Open… and select the package folderSelect the shared swift-yamlkit scheme (it is versioned in .swiftpm/xcode/xcshareddata/xcschemes) and a destination such as My Mac or an iOS Simulator. Then use Product ▸ Build (⌘B), Product ▸ Test (⌘U), the Test navigator to run individual tests or test-suite cases, and Product ▸ Build Documentation (⌃⇧⌘D). Code coverage for the YamlKit target is enabled in the scheme and shown in the Report navigator.
Changes to targets, platforms, or resources are made in Package.swift; Xcode picks them up automatically. The same scheme works from the command line:
xcodebuild test -scheme swift-yamlkit -destination 'platform=macOS'
xcodebuild test -scheme swift-yamlkit -destination 'platform=iOS Simulator,name=<simulator name>'xcodebuild -scheme swift-yamlkit -showdestinations lists the available simulators.
Testing
swift testThe test suite includes unit tests for every layer, randomized round-trip tests, and conformance tests based on a vendored snapshot of the YAML test suite. For every case of the suite, the tests verify the parsing events, the composed data (against in.json), and that emitting and serializing preserve the content. The snapshot can be updated with Scripts/update-yaml-test-suite.sh.
The tests use DynamicJSON to read the expected JSON data. It is a test-only dependency: packages that depend on YamlKit neither fetch nor link it.
Requirements
The following technologies are needed to build the YamlKit framework. The framework can both be built either using Xcode or the Swift Package Manager.
- Swift 6
- Swift Package Manager
- macOS 13 or later, iOS 16 or later
License
YamlKit is distributed under the Apache License, Version 2.0. See LICENSE. The YAML test suite data is distributed under the MIT license by its authors.
Copyright
Author: Matthias Zenger (<matthias@objecthub.com>) Copyright © 2026 Matthias Zenger. All rights reserved.
Package Metadata
Repository: objecthub/swift-yamlkit
Default branch: main
README: README.md