---
title: "Use YAML in a native AOT app"
url: https://recursiveai.org/oneyaml/csharp/cookbook/native-aot/
description: "Read and write YAML in a trimmed or native AOT .NET app with OneYaml’s source generator, using a YamlSerializerContext instead of reflection."
version: "1.2.1"
---

# Use YAML in a native AOT app

The `YamlSerializer` overloads that take options use reflection, which trimming and native AOT can’t rely on. Declare a `YamlSerializerContext` and pass its generated metadata instead. The generator ships in the `OneYaml` package; there is nothing else to install.

```xml
<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>
```

```csharp
using OneYaml;

// Generated metadata instead of reflection: safe to trim and to publish as native AOT.
string src = """
    retries: 3
    endpoint: https://example.com
    tags: [web, public]
    """;
Settings settings = YamlSerializer.Deserialize(src, AppYamlContext.Default.Settings)!;
Console.WriteLine($"{settings.Retries} retries against {settings.Endpoint.Host}");

Console.Write(YamlSerializer.Serialize(settings with { Retries = 5 }, AppYamlContext.Default.Settings));

// YamlDocument takes generated metadata too.
using var doc = YamlDocument.Parse(src);
doc.Set("/tags", new List<string> { "web", "internal" }, AppYamlContext.Default.ListString);
Console.WriteLine(doc);

record Settings(int Retries, Uri Endpoint, List<string> Tags);

[YamlSerializable(typeof(Settings))]
partial class AppYamlContext : YamlSerializerContext;
```

```text
3 retries against example.com
retries: 5
endpoint: https://example.com
tags:
  - web
  - public
retries: 3
endpoint: https://example.com
tags: [web, internal]
```

That output is from the native executable built by `dotnet publish -c Release`, with warnings treated as errors.

## Good to know

- The generator writes a `YamlTypeInfo<T>` property on the context for each `[YamlSerializable]` type and for every type those reach, such as `ListString` for `List<string>` above.
- Generated and reflection metadata bind the same way: attributes, converters, polymorphism and extension data work with both.
- For options other than the defaults, create the context with them, `new AppYamlContext(new YamlSerializerOptions { ... })`, or set `TypeInfoResolver = AppYamlContext.Default` on options you already pass around.
- With `PublishTrimmed` or `PublishAot`, reflection-based binding is off by default. Set the MSBuild property `YamlSerializerIsReflectionEnabledByDefault` to `true` to keep it.
- Mistakes in a context, such as a context that isn’t `partial`, are build-time diagnostics `OY0001` to `OY0010`.

More in [source generation and native AOT](https://recursiveai.org/oneyaml/csharp/docs/serializer/#source-generation-and-native-aot).

Trim warnings, publish results and YamlDotNet compared: [C# YAML with native AOT](https://recursiveai.org/oneyaml/articles/csharp-yaml-native-aot/).
