Recursive AI

Choosing a C# YAML library

C# YAML parser libraries compared: YamlDotNet, SharpYaml, VYaml and OneYaml by license, targets, YAML version and API, with the same file read by each.

The C# YAML parser most .NET code uses is YamlDotNet, with more than 600 million NuGet downloads and targets from .NET Framework 4.7 to .NET 10. Its README lists YAML 1.2 for the parser but only YAML 1.1 for the emitter, and its typed deserializer reads yes as true. SharpYaml 3 has a System.Text.Json-style API and reads the YAML 1.2 Core schema. VYaml is built for speed and Unity. OneYaml pairs a System.Text.Json-style serializer with a YamlDocument that edits a file and keeps its comments, on .NET 8 and .NET 10. All four are permissively licensed.

Package facts are from each NuGet listing and README, read on 26 October 2026. Behavior was measured by running each package, and the program is below.

.NET YAML libraries at a glance

Package, version (date)LicenseTargetsAPIYAML version, per its docs
YamlDotNet 18.1.0 (Jun 2026)MIT.NET Standard 2.0 and 2.1, .NET Framework 4.7, .NET 8, .NET 10DeserializerBuilder/SerializerBuilder, a YamlStream object model, low-level parser and emitterParser 1.1 and 1.2, emitter 1.1 (README)
SharpYaml 3.16.0 (Oct 2026)MIT.NET Standard 2.0, .NET 8, .NET 10System.Text.Json style: YamlSerializer, YamlSerializerOptions; scanner, parser, emitter and syntax tree“YAML 1.2 Core Schema”, with Failsafe, JSON and Extended selectable (README)
VYaml 1.5.0 (Oct 2026)MIT.NET Standard 2.0 and 2.1, .NET 6, 8, 9; Unity[YamlObject] partial types, source-generated; a UTF-8 parser and emitter“YAML 1.2 mostly supported” (README)
OneYaml 1.2.1 (Oct 2026)MIT OR Apache-2.0.NET 8, .NET 10System.Text.Json style YamlSerializer, plus a lossless YamlDocument with JSON Pointer edits and patches1.2, Core schema

For native AOT, SharpYaml and OneYaml ship a source generator inside the main package, and VYaml generates code for [YamlObject] types. YamlDotNet’s generator is a separate package, Vecc.YamlDotNet.Analyzers.StaticGenerator.

The same file, read by three C# YAML libraries

YAML 1.1 read yes as a boolean and a leading zero as octal. YAML 1.2 has only true and false as booleans, and 0755 is the decimal 755. This program binds both forms to a typed class with each library:

Program.cs.NET 10
using System.Text.Json;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
 
var readers = new (string Name, Func<string, Settings> Read)[]
{
    ("YamlDotNet 18.1.0", yaml => new DeserializerBuilder()
        .WithNamingConvention(CamelCaseNamingConvention.Instance)
        .Build()
        .Deserialize<Settings>(yaml)),
    ("SharpYaml 3.16.0", yaml => SharpYaml.YamlSerializer.Deserialize<Settings>(yaml,
        new SharpYaml.YamlSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })!),
    ("OneYaml 1.2.1", yaml => OneYaml.YamlSerializer.Deserialize<Settings>(yaml)!),
};
 
foreach (var (name, read) in readers)
{
    Console.WriteLine($"{name}: {Show(() => read("enabled: yes").Enabled)}, {Show(() => read("mode: 0755").Mode)}");
}
 
static string Show<T>(Func<T> get)
{
    try { return $"{get()}"; }
    catch (Exception e) { return e.GetType().Name; }
}
 
class Settings
{
    public bool Enabled { get; set; }
    public int Mode { get; set; }
}
Output
YamlDotNet 18.1.0: True, 493
SharpYaml 3.16.0: YamlException, 755
OneYaml 1.2.1: YamlException, 755

YamlDotNet reads the file as YAML 1.1: yes becomes true and 0755 becomes 493. SharpYaml and OneYaml read it as YAML 1.2: yes is refused as a boolean, and 0755 is 755. Neither answer is wrong for every project, but you should know which one you get. OneYaml’s error names the line, the column and the JSON Pointer of the value: The value 'yes' cannot be read as a boolean. (line 1, column 10, path /enabled). VYaml isn’t in the run: its typed serializer works through source-generated [YamlObject] partial types, which needs a different program.

Read and edit YAML in C# with OneYaml

TerminalNuGet
dotnet new console -o YamlStart
cd YamlStart
dotnet add package OneYaml --version 1.2.1

YamlSerializer.Deserialize<T> binds YAML to classes and records the way JsonSerializer binds JSON, with keys in camel case by default. To change a file that people also edit by hand, parse it into a YamlDocument:

Program.csOneYaml 1.2.1 · .NET 10
using OneYaml;
 
const string Src = """
    # Deploy settings
    name: api
    replicas: 2   # raised by the release job
    ports: [80]
    """;
 
// Typed read, the way System.Text.Json works. Keys bind in camel case.
var cfg = YamlSerializer.Deserialize<Config>(Src)!;
Console.WriteLine($"{cfg.Name}: {cfg.Replicas} replicas on {string.Join(", ", cfg.Ports)}");
 
// Edit the same text: only the values you set change.
using var doc = YamlDocument.Parse(Src);
doc.Set("/replicas", 3);
doc.Add("/ports/-", 443);
Console.WriteLine(doc);
 
record Config(string Name, int Replicas, List<int> Ports);
Output
api: 2 replicas on 80
# Deploy settings
name: api
replicas: 3   # raised by the release job
ports: [80, 443]

The comment after replicas stays, and the new port joins the flow list in its own style. YamlSerializerOptions takes naming policies, ignore conditions, converters and the System.Text.Json attributes (serializer). The getting started guide covers writing YAML and patches, and the classes recipe and reading YAML without a class go further.

What each C# YAML library is for

YamlDotNet

The default choice for years, and the widest reach: .NET Standard 2.0, .NET Framework and current .NET, plus a Unity Asset Store package. It has builders for the serializer, an object model “similar to XmlDocument”, and low-level parsing and emitting. Its node deserializers can be replaced or extended to change how binding works, as its samples show for validation. Choose it for older frameworks, for those extension points, or when the code already works.

SharpYaml

Version 3 is a redesign with a System.Text.Json-style API, YAML 1.2 Core by default with other schemas selectable, System.Text.Json attribute support, a source generator in the package, and public scanner, parser, emitter and syntax tree APIs. Choose it for System.Text.Json-style code that also has to run on .NET Standard 2.0, or when you need a schema other than Core.

VYaml

A low-allocation library that works on UTF-8 bytes directly, built for .NET and Unity, including Unity’s own serialized YAML. Choose it for Unity, or when allocation per read matters most.

OneYaml

The System.Text.Json shape for YAML 1.2, plus edits in place: YamlDocument writes a new value in the old one’s style and keeps every other byte, comments included (edit YAML without losing comments). It applies RFC 6902 JSON Patch and RFC 7396 Merge Patch to the YAML text (JSON Patch for YAML), bounds depth, alias expansion and integer size by default with a YamlLimits.Untrusted preset (untrusted input), and has no dependencies outside .NET. Speed and memory against the other libraries are on the performance page, which lists the files where OneYaml was slower.

When OneYaml is not the right fit

  • .NET Framework, .NET Standard or Unity: OneYaml runs on .NET 8 and .NET 10 only.
  • Comments as data: YamlDocument keeps comments through edits, but it can’t read, add or move them.
  • A public streaming parser: OneYaml exposes its reader only inside a converter. YamlDotNet, SharpYaml and VYaml have public pull parsers.
  • Schemas other than Core: OneYaml reads the Core schema only.
  • A long track record: OneYaml 1.0.0 was released in October 2026.

How to choose a C# YAML library

  • New code on .NET 8 or later that reads configuration, or edits files people maintain: OneYaml.
  • System.Text.Json-style code that must also target .NET Standard 2.0: SharpYaml.
  • Unity: VYaml or YamlDotNet.
  • Existing YamlDotNet code: keep it, or swap to OneYaml.Compat.YamlDotNet, which keeps the builder calls (replacing YamlDotNet).
  • Existing SharpYaml code: keep it, or use OneYaml.Compat.SharpYaml (from SharpYaml).

For a fuller side-by-side, including where the others win, see how OneYaml compares. All three oneyaml languages are on the oneyaml home page.