jpsim
Yams
Swift

A Sweet and Swifty YAML parser.

Last updated Jul 6, 2026
1.3k
Stars
168
Forks
26
Issues
+1
Stars/day
Attention Score
90
Language breakdown
Swift 53.0%
C 45.6%
CMake 1.0%
Starlark 0.4%
Objective-C 0.1%
Ruby 0.0%
โ–ธ Files click to expand
README

Yams

Yams

A sweet and swifty YAML parser built on LibYAML.

SwiftPM xcodebuild Nightly codecov

Installation

Building Yams requires Xcode 14.0+ or a Swift 5.7+ toolchain with the Swift Package Manager or CMake and Ninja.

CMake

CMake 3.17.2 or newer is required, along with Ninja 1.9.0 or newer.

When building for non-Apple platforms:

cmake -B /path/to/build -G Ninja -S /path/to/yams -DCMAKEBUILDTYPE=Release -DFoundation_DIR=/path/to/foundation/build/cmake/modules
cmake --build /path/to/build

To build for Apple platforms (macOS, iOS, tvOS, watchOS), there is no need to separately build Foundation because it is included as part of the SDK:

cmake -B /path/to/build -G Ninja -S /path/to/yams -DCMAKEBUILDTYPE=Release
cmake --build /path/to/build

Swift Package Manager

Add .package(url: "https://github.com/jpsim/Yams.git", from: "6.2.2") to your Package.swift file's dependencies.

Bazel

In your WORKSPACE file

YAMSGITSHA = "SOME_SHA"
http_archive(
    name = "comgithubjpsim_yams",
    urls = [
        "https://github.com/jpsim/Yams/archive/%s.zip" % YAMSGITSHA,
    ],
    stripprefix = "Yams-%s" % YAMSGIT_SHA,
)

Usage

Yams has three groups of conversion APIs: one for use with Codable types, another for Swift Standard Library types, and a third one for a Yams-native representation.

Codable types

  • Codable is an [encoding & decoding strategy introduced in Swift 4][Codable]
enabling easy conversion between YAML and other Encoders like [JSONEncoder][JSONEncoder] and [PropertyListEncoder][PropertyListEncoder].
  • Lowest computational overhead, equivalent to Yams.Node.
  • Encoding: YAMLEncoder.encode(_:)
Produces a YAML String from an instance of type conforming to Encodable.
  • Decoding: YAMLDecoder.decode(_:from:)
Decodes an instance of type conforming to Decodable from YAML String or Data.
import Foundation
import Yams

struct S: Codable { var p: String }

let s = S(p: "test") let encoder = YAMLEncoder() let encodedYAML = try encoder.encode(s) encodedYAML == """ p: test

""" let decoder = YAMLDecoder() let decoded = try decoder.decode(S.self, from: encodedYAML) s.p == decoded.p

Swift Standard Library types

  • The type of Swift Standard Library is inferred from the contents of the
internal Yams.Node representation by matching regular expressions.
  • This method has the largest computational overhead When decoding YAML, because
the type inference of all objects is done up-front.
  • It may be easier to use in such a way as to handle objects created from
JSONSerialization or if the input is already standard library types (Any, Dictionary, Array, etc.).
  • Encoding: Yams.dump(object:)
Produces a YAML String from an instance of Swift Standard Library types.
  • Decoding: Yams.load(yaml:)
Produces an instance of Swift Standard Library types as Any from YAML String.
// [String: Any]
let dictionary: [String: Any] = ["key": "value"]
let mapYAML: String = try Yams.dump(object: dictionary)
mapYAML == """
key: value

""" let loadedDictionary = try Yams.load(yaml: mapYAML) as? [String: Any]

// [Any] let array: [Int] = [1, 2, 3] let sequenceYAML: String = try Yams.dump(object: array) sequenceYAML == """

  • 1
  • 2
  • 3
""" let loadedArray: [Int]? = try Yams.load(yaml: sequenceYAML) as? [Int]

// Any let string = "string" let scalarYAML: String = try Yams.dump(object: string) scalarYAML == """ string

""" let loadedString: String? = try Yams.load(yaml: scalarYAML) as? String

Yams.Node

  • Yams' native model representing [Nodes of YAML][Nodes Spec] which provides all
functions such as detection and customization of the YAML format.
  • Depending on how it is used, computational overhead can be minimized.
  • Encoding: Yams.serialize(node:)
Produces a YAML String from an instance of Node.
  • Decoding Yams.compose(yaml:)
Produces an instance of Node from YAML String.
var map: Yams.Node = [
    "array": [
        1, 2, 3
    ]
]
map.mapping?.style = .flow
map["array"]?.sequence?.style = .flow
let yaml = try Yams.serialize(node: map)
yaml == """
{array: [1, 2, 3]}

""" let node = try Yams.compose(yaml: yaml) map == node

NSMutable* compatibility

Yams also supports deep conversion of YAML into NSMutableDictionary and NSMutableArray, which is useful when working with mutable Cocoa-style collections, such as NSMutableDictionary and NSMutableArray.

To produce NSMutable* results, use a custom constructor:

let yaml = """
names:
  - Alice
  - Bob
"""

let constructor = Constructor(Constructor.defaultScalarMap, Constructor.nsMutableMappingMap, Constructor.nsMutableSequenceMap)

let result = try Yams.load(yaml: yaml, .default, constructor) as? NSMutableDictionary let names = result?["names"] as? NSMutableArray print(names ?? "No data") // -> (Alice, Bob)

Integrating with Combine

When Apple's Combine framework is available, YAMLDecoder conforms to the TopLevelDecoder protocol, which allows it to be used with the decode(type:decoder:) operator:

import Combine
import Foundation
import Yams

func fetchBook(from url: URL) -> AnyPublisher<Book, Error> { URLSession.shared.dataTaskPublisher(for: url) .map(\.data) .decode(type: Book.self, decoder: YAMLDecoder()) .eraseToAnyPublisher() }

License

Both Yams and libYAML are MIT licensed.

[Codable]: https://developer.apple.com/documentation/foundation/archivesandserialization/encodinganddecodingcustomtypes [JSONEncoder]: https://developer.apple.com/documentation/foundation/jsonencoder [PropertyListEncoder]: https://developer.apple.com/documentation/foundation/propertylistencoder [Nodes Spec]: http://www.yaml.org/spec/1.2/spec.html#id2764044

ยฉ 2026 GitRepoTrend ยท jpsim/Yams ยท Updated daily from GitHub