Lossless, comment-preserving editing and a System.Text.Json-style serializer for YAML 1.2, in one .NET package. Both run on one parser, so a typed read and an edit never disagree about what a file means. Pure C#, correct YAML 1.2 by default; nesting, alias expansion and integer size are bounded unless you lift the limits.
How many times faster oneyaml-csharp is than the strongest other .NET YAML library on each task, on real configuration files (wall-clock time, log scale, higher is better; a task where oneyaml-csharp is slower shows as a slower bar):
Full results, with memory and the method →
Why oneyaml-csharp
- Edits that keep your file.
YamlDocumentchanges only what you touch, in the old value's style; comments and layout elsewhere stay byte for byte. JSON Patch and Merge Patch apply the same way (editing, patches). - A serializer you already know. Options, naming policies, converters, polymorphism and the System.Text.Json attributes, with a source generator in the package for trimmed and native AOT apps (serializer).
- Correct YAML 1.2 by default.
yesis a string and0755the integer 755; YAML 1.1 forms come only fromMergeKeysor the compatibility packages. Checked against the full yaml-test-suite, with every deviation listed (conformance). - Safe on outside input. Depth, alias expansion and integer size
are bounded by default; input size, scalar size and document count
are bounded when you set them, and
YamlLimits.Untrustedsets them (limits). No unsafe code, no dependencies outside .NET, and fuzzed (fuzzing). - Fast, with the losses shown. Ahead of every other .NET YAML library at typed load, generic load, dump, document parse, editing and writing back an unedited file, through reflection and generated metadata alike, and level or lower on memory throughout. Not on every file: writing back some unedited files was slower than SharpYaml's syntax tree in our run, the generated-metadata column was slower on a few tiny files, and a few files are level (every loss).
How oneyaml-csharp compares with YamlDotNet, SharpYaml and VYaml, including when one of them is the better choice.
Install
dotnet add package OneYamlMoving from YamlDotNet or SharpYaml? A compatibility package covers the common serializer and model calls; its guide lists what it leaves out and what differs.
Quick start
Change two values in a file, keeping the comment, the block scalar and every other byte as they were; then bind the original text to a record.
using OneYaml; string src = """ # Build settings script: | make build replicas: 2 # the CI job scales this """; using var doc = YamlDocument.Parse(src); doc.Set("/script", "make build\nmake test\n"); // still a block literal doc.Root["replicas"] = 3; // only the 2 changes Console.WriteLine(doc); // # Build settings // script: | // make build // make test // replicas: 3 # the CI job scales this var cfg = YamlSerializer.Deserialize<Config>(src)!; Console.WriteLine($"{cfg.Replicas} replicas"); // 2 replicas record Config(int Replicas, string Script);
Keys bind in camel case by default. Read what an edit keeps, and what it does not; for native AOT, use generated metadata.
Where to go
- Using it: serializer, editing, patches, limits, reader and emitter. The API reference is the XML documentation your IDE shows.
- Migrating: from YamlDotNet, from SharpYaml.
- Choosing a library: how oneyaml-csharp compares, including where the others win.
- Evidence: benchmark tables (the numbers behind the chart, every loss and the method), yaml-test-suite conformance, fuzzing.
- What changed, and what stays stable: CHANGELOG.md, stability and supported .NET versions.
- Contributing and security: CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md.
- Other languages: oneyaml-go and oneyaml-rust, all measured by oneyaml-kit.
Packages
| Package | What it is |
|---|---|
OneYaml | The library: YamlSerializer, YamlDocument, patches, limits. Start here. |
OneYaml.Compat.YamlDotNet | A subset of YamlDotNet's API on top of OneYaml: the serializer builders and the representation model, tested against YamlDotNet 18.1.0. Not covered: static contexts, type inspectors, node deserializers, the scanner and comment events; what is covered and every difference. |
OneYaml.Compat.SharpYaml | A subset of SharpYaml's API on top of OneYaml: the serializer, its options and attributes, tested against SharpYaml 3.14.0. Not covered: custom converters, polymorphism, generated contexts, the Model and Syntax namespaces; what is covered and every difference. |
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.