> For the complete documentation index, see [llms.txt](https://docs.flatredball.com/gum/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flatredball.com/gum/code/performance-and-optimization/native-aot-and-trimming.md).

# Native AOT and Trimming

Gum supports publishing with `PublishTrimmed` and `PublishAot`. Two things are required:

1. Convert your Gum project to the JSON file format.
2. Avoid the string-based binding overloads in code that must survive trimming.

Everything else works without extra configuration. You do not need `TrimmerRootAssembly` entries for Gum or for your own generated runtime types.

## Convert your project to JSON

`XmlSerializer` relies on runtime code generation, which Native AOT does not allow, so an XML project (`.gumx`) crashes while loading. The JSON format exists for this reason, and conversion is explicit and non-destructive, leaving your XML files untouched.

From the command line:

```
gumcli convert-to-json MyProject.gumj
```

Or in the Gum tool, use **Content** and then **Convert to JSON**.

This writes a `.gumj` project plus a JSON sibling for every screen, component, standard element, behavior, and animation file the project references. Point your game at the new extension:

```csharp
// Initialize
GumUI.Initialize(this, "GumProject/MyProject.gumj");
```

See [Project Files](/gum/gum-tool/project-files.md) for the full list of JSON extensions.

## Publish settings

A typical Native AOT game project needs only the standard .NET properties:

```xml
<PropertyGroup>
  <PublishAot>true</PublishAot>
  <SelfContained>true</SelfContained>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
```

Publish with `dotnet publish -c Release -r win-x64 --self-contained`.

{% hint style="info" %}
The Native AOT link step shells out to `vswhere.exe` to find the MSVC linker. If publishing fails with `link.exe exited with code 123`, add the Visual Studio Installer folder to your `PATH`, or publish from a Developer Command Prompt.
{% endhint %}

## Bindings and trimming

Trimming removes members nothing references. A binding that names its view model property with a string is resolved by reflection at runtime, so the trimmer cannot see the reference and may remove the property. The binding then silently stops updating rather than throwing.

Use the lambda overloads instead, which give the compiler a direct reference to the property:

```csharp
// Initialize
textBox.SetBinding<MyViewModel>(
    nameof(TextBox.Text),
    vm => vm.PlayerName);
```

The string overloads still compile and still work in a non-trimmed build, but each one produces an `IL2026` warning on publish naming the exact call site. Treat those warnings as a to-do list. See [Lambda Binding](/gum/code/binding-viewmodels/advanced-binding-options.md) for the full comparison.

## Other reflection-based APIs

A few APIs beyond binding also resolve a member by name at runtime. Each produces an `IL2026` warning at your call site, and each has a reflection-free alternative:

| API                                                        | Alternative                                                           |
| ---------------------------------------------------------- | --------------------------------------------------------------------- |
| `ListBox.DisplayMemberPath`, `ComboBox.DisplayMemberPath`  | Assign a `VisualTemplate` whose content reads the property directly.  |
| `FrameworkElement.RegisterRuntimeProperty(object, string)` | Use the `GraphicalUiElement` overload, or the getter/setter overload. |

Gum's own runtime types, generated runtime types, and view models are annotated so the trimmer keeps the members Gum resolves by name, so you do not have to root them yourself.

## Fonts

Use text-format `.fnt` files. Bitmap fonts generated by the Gum tool are already in this format, so this only matters if you supply a font file produced elsewhere. The XML `.fnt` variant goes through `XmlSerializer` and fails the same way an XML project does. Binary `.fnt` files are not supported in any configuration.

## Generic components

A generic Gum component needs its closed type built at runtime, which Native AOT can only supply when that exact instantiation is already reachable from your code. If Gum cannot construct one, it throws an error naming the type. Replace the generic component with a concrete one.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.flatredball.com/gum/code/performance-and-optimization/native-aot-and-trimming.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
