# YamlDotNet: YAML parsing and serialization for .NET, from token stream to typed object

> YamlDotNet is an MIT-licensed C# library that covers low-level YAML parsing and emitting, a document object model, and object serialization. It targets netstandard 2.0 and 2.1, .NET 8.0, .NET 10.0 and .NET Framework 4.7, and installs as the YamlDotNet NuGet package.

**aaubry/YamlDotNet** — YamlDotNet is a .NET library for YAML

- Repository: https://github.com/aaubry/YamlDotNet
- Stars: 2,865 · Forks: 528
- Language: C#
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/aaubry-yamldotnet

## What YamlDotNet solves, and who ends up using it

YAML shows up in .NET projects through files the runtime does not parse for you: CI pipelines, Kubernetes manifests, game data, application settings that outgrew appsettings.json. YamlDotNet exists to read and write those files from C#. The README describes three layers rather than one API. There is low-level parsing and emitting of YAML tokens, a high-level object model the README compares to XmlDocument, and a serialization layer that maps YAML streams onto your own classes. You pick the layer that matches the problem. A tool that lints or reformats YAML wants the token and document layer. An application loading a config file into a typed object wants the serializer.

The audience is narrower than a general-purpose library. The README states the package is compatible with netstandard 2.0 and 2.1, .NET 8.0, .NET 10.0 and .NET Framework 4.7. That range covers modern ASP.NET services, older desktop and enterprise code still on the framework, and Unity projects, which the README lists as a separate distribution on the Unity Asset Store. If you are shipping to one of those runtimes and need YAML, this is the library the ecosystem points at. The repository also carries YamlDotNet.Samples.Fsharp and an F# test project, so F# consumers are not an afterthought.

## How the parser, the document model and the serializer fit together

The pipeline runs in one direction: text in, tokens, then a document tree, then your objects. The parser produces the token stream and the emitter writes one back out. Above that sits the object model, which the README likens to XmlDocument, so you can walk a YAML document without declaring a class for it. The serialization layer sits on top and does the mapping between YAML nodes and .NET types.

Configuration happens through builders. SerializerBuilder and DeserializerBuilder collect the choices, and Build() produces the instance that does the work. Naming conventions are one such choice. The README's serializer example calls .WithNamingConvention(CamelCaseNamingConvention.Instance), and the output shows C# properties like HeightInInches arriving as heightInInches. The deserializer example uses UnderscoredNamingConvention.Instance instead, and the README comments that this is what turns height_in_inches in the YAML into the matching property. That is the whole design: one builder per direction, conventions and options attached before the object is built.

The repository layout hints at two more concerns the README does not explain. There is a YamlDotNet.Analyzers.StaticGenerator project and a YamlDotNet.Core7AoTCompileTest project, which suggests ahead-of-time compilation is treated as a supported scenario rather than an afterthought. The README itself says nothing about AOT, so treat the source tree as the evidence and check the wiki before relying on it.

## Installing YamlDotNet and serializing your first object

The README gives one installation route: the YamlDotNet NuGet package. From the Visual Studio package manager console the command is the one the README prints, and the equivalent dotnet CLI command is the same package name.

```bash
dotnet add package YamlDotNet
```

After restore, the package is referenced by your project and the YamlDotNet.Serialization namespace becomes available. The README also points at a binaries download hosted on AppVeyor for people who do not want to use NuGet, and at the Unity Asset Store listing for Unity users.

The first real use is serializing an object to a string. The README builds a SerializerBuilder, attaches CamelCaseNamingConvention.Instance, calls Build(), and passes the object to Serialize. The output it shows begins with name: Abe Lincoln and age: 25, with nested addresses indented underneath. Note what the README's own output reveals: the float property HeightInInches prints as 6.3333334922790527 rather than a rounded 6.3333. The serializer writes the value it is given, so if you need tidy numbers you round them before serializing.

```csharp
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

var serializer = new SerializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();
var yaml = serializer.Serialize(person);
System.Console.WriteLine(yaml);
```

Reading is the mirror image. The README's deserialization sample declares a YAML string with underscored keys, builds a DeserializerBuilder with UnderscoredNamingConvention.Instance, and calls Deserialize<Person>(yml). The comment shows the resulting object printing George Washington is 89 years old and lives at 400 Mockingbird Lane in Louaryland, Hawidaho. The naming convention is what makes height_in_inches land on the property; without it, the keys and the property names would not line up.

## Emitter conformance stops at YAML 1.1, and the README says so

The conformance table in the README is the most useful paragraph in the document. The parser is marked as supporting both YAML 1.1 and YAML 1.2. The emitter is marked as supporting 1.1 only, with the 1.2 cell left blank. Anyone generating YAML for a consumer that expects 1.2 semantics should read that as a boundary, not a bug report. The library will parse the newer spec and write the older one.

Two other gaps are worth naming. The README states that more information lives in the project wiki, which means the package's own documentation is deliberately thin and the wiki is where you go for anything beyond the samples. And the README does not document rollback, migration between major versions, or what changed between releases; it only points at the GitHub Releases page. If you are upgrading across a major version, the release notes are the source, and this article cannot tell you what they say.

The library is also the wrong tool for some jobs. If your YAML is a small settings file with a flat shape, .NET's configuration binder already reads it and you avoid a dependency. If your problem is validating YAML against a schema rather than reading it into objects, the README does not describe a schema validation feature, so check the wiki before assuming one exists. And if you need to round-trip a document while preserving comments and formatting exactly, the object model path will not do that for you.

## YamlDotNet against SharpYaml and the built-in configuration binder

SharpYaml is the alternative that comes up in the same searches, and the difference is lineage. SharpYaml descends from an older .NET YAML effort and has historically been used by projects that needed YAML before YamlDotNet's serialization layer matured. YamlDotNet's README makes its own position explicit: the library has been used in multiple projects and is considered fairly stable, and the README publishes a conformance table against the YAML specifications. That table is the concrete thing to compare. Ask the other library what spec versions its parser and emitter claim, and whether it documents them at all.

The second alternative is not a library. For configuration files, Microsoft.Extensions.Configuration reads YAML-shaped settings without a third-party dependency, and for many services that is enough. The trade-off is control. The configuration binder gives you key-value lookup; YamlDotNet gives you the token stream, a document model you can walk, and builders where you set naming conventions and other options before the serializer is constructed. If you only ever read a connection string and a log level, the binder wins on dependency count. If you parse user-supplied YAML, emit YAML from a tool, or need the document model, YamlDotNet is the layer you actually want.

## Licence, release cadence and what an upgrade costs you

YamlDotNet is MIT licensed, and the repository carries both LICENSE.txt and a separate LICENSE-libyaml file. The second file matters: it indicates the project incorporates libyaml-derived code under its own terms. If you redistribute the library, read both files rather than assuming a single licence covers everything. This is not legal advice, and the two files are short enough to read directly.

On cadence, the release list shows v18.1.0 on 2026-06-26, v18.0.0 on 2026-05-21 and v17.1.0 on 2026-04-28, and the last push to the default branch was on 2026-09-15. The project is not archived and the repository is being touched, but the README does not describe a support window for older major versions, so the practical upgrade cost is unknown until you read the release notes for the versions you are crossing. The repository uses GitVersion.yml and Directory.Packages.props, which suggests versioning and package versions are managed centrally; that is a build detail, not a compatibility promise.

One cost you can see in the repository is build weight. The Dockerfile installs mono-complete, adds a Mono apt repository, and pulls an additional SDK, with a comment noting the bullseye image is used even though Mono only ships buster packages. That is the project's own CI image, not something you inherit, but it tells you the test matrix spans runtimes old enough to need Mono.

## Conclusion

Adopt YamlDotNet when you need YAML inside a .NET application and want control over the parsing layer, not just a deserialize call. Skip it if you need YAML 1.2 output, since the README's conformance table marks the emitter as 1.1 only, or if your configuration is simple enough that the built-in configuration binder suffices. Before committing, check that your target framework appears in the compatibility list and decide whether camelCase or underscored naming conventions match the files you already have.

## FAQ

### How do I use YamlDotNet to read and write YAML?

Use the serialization layer. The README builds a SerializerBuilder with a naming convention and calls Serialize on an object, and for reading it builds a DeserializerBuilder and calls Deserialize<Person> on a YAML string.

### What is the alternative to YamlDotNet?

SharpYaml is the other YAML library that appears in the same searches. YamlDotNet's README publishes a conformance table against the YAML 1.1 and 1.2 specifications, which is the concrete claim to compare against.

### What is YAML and why is it used?

The README describes YAML as a human friendly data serialization standard for all programming languages, portable and platform-independent like XML but easier for a person to read or produce.

## Sources

- [aaubry/YamlDotNet on GitHub](https://github.com/aaubry/YamlDotNet)
- [Issues](https://github.com/aaubry/YamlDotNet/issues)
- [License: MIT](https://github.com/aaubry/YamlDotNet/blob/master/LICENSE)
- [README](https://github.com/aaubry/YamlDotNet/blob/master/README.md)
- [Releases](https://github.com/aaubry/YamlDotNet/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aaubry-yamldotnet
