Skip to content

[API Spec] XamlOptionalChanges: opt-in API for breaking perf changes - #11110

Merged
Sundaram Ramaswamy (sundaramramaswamy) merged 6 commits into
microsoft:mainfrom
sundaramramaswamy:user/suramaswamy/optional-changes-api-spec
Jun 15, 2026
Merged

Sundaram Ramaswamy (sundaramramaswamy) merged 6 commits into
microsoft:mainfrom
sundaramramaswamy:user/suramaswamy/optional-changes-api-spec

Conversation

@sundaramramaswamy

@sundaramramaswamy Sundaram Ramaswamy (sundaramramaswamy) commented May 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds the API spec for XamlOptionalChanges, a mechanism for apps to opt into breaking changes (e.g. performance improvements that alter layout trees) before XAML initialization.

Summary

  • XamlOptionalChanges - static class with EnableChange(), DisableChange(), IsChangeEnabled(), Lock()
  • XamlChangeId - enum identifying individual breaking changes
  • Changes must be configured before Application.Start() or WindowsXamlManager.InitializeForCurrentThread()
  • State auto-locks at XAML initialization; early manual lock via Lock()

Spec file: specs/XamlOptionalChanges/XamlOptionalChanges-Spec.md

Adds the API spec for XamlOptionalChanges, a mechanism for apps to
opt into breaking changes (e.g. performance improvements that alter
layout trees) before XAML initialization.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the needs-triage Issue needs to be triaged by the area owners label May 19, 2026
@Jay-o-Way

Copy link
Copy Markdown
Contributor

Sundaram Ramaswamy (@sundaramramaswamy) Where and when is this spec discussed? I am really interested in the different opinions, pro and con. Let's be transparent.

Having that said, I would like to share what are my first, quick thoughts are...

  • In general, Microsoft is already known to be heavily backwards compatible. This adds even more... complications.
  • It blurs the lines between version numbers. If you can opt-in or opt-out of specific things, you are less confidant about the production you're actually using. It can mean that, when a certain new function is added to a specific new version, but opted-out, it can frustrate people as to "Why is this specific thing not working?!"
  • Compare Windows xxH2 versions. They are yearly mileposts, but many, many features that are supposed to "belong" to that version, may only be turned on long after the installation. And this testing is not even in the user's control. For example, I am using 25H2 and long after that installation I saw that new Start Menu. But after about a week or so, it was reverted!

As you can see, the entire idea of selective features in a certain release is a no-go for me in the first place. But that's my opinion...

@sundaramramaswamy

Sundaram Ramaswamy (sundaramramaswamy) commented May 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Sundaram Ramaswamy (@sundaramramaswamy) Where and when is this spec discussed? I am really interested in the different opinions, pro and con. Let's be transparent.

Having that said, I would like to share what are my first, quick thoughts are...

  • In general, Microsoft is already known to be heavily backwards compatible. This adds even more... complications.
  • It blurs the lines between version numbers. If you can opt-in or opt-out of specific things, you are less confidant about the production you're actually using. It can mean that, when a certain new function is added to a specific new version, but opted-out, it can frustrate people as to "Why is this specific thing not working?!"
  • Compare Windows xxH2 versions. They are yearly mileposts, but many, many features that are supposed to "belong" to that version, may only be turned on long after the installation. And this testing is not even in the user's control. For example, I am using 25H2 and long after that installation I saw that new Start Menu. But after about a week or so, it was reverted!

As you can see, the entire idea of selective features in a certain release is a no-go for me in the first place. But that's my opinion...

Jay (@Jay-o-Way) This PR is where and when — the spec is being drafted and discussed right here, right now. Your feedback and everyone else's shapes the design.

As for the broader concern: this isn't feature-flighting like Windows xxH2 rollouts. These are developer-controlled, deterministic settings — the app author explicitly opts in, not a server-side toggle. No surprises, no silent rollbacks.

The design is a middle ground between progress and backward compat: we want to ship perf improvements without forcing breakage on apps that aren't ready, but we also don't want to carry old behavior forever. The proposed lifecycle gives developers a 2-major-version runway to adapt before a change becomes permanent.

@roxk

roxk commented May 20, 2026 •

Copy link
Copy Markdown

Sundaram Ramaswamy (@sundaramramaswamy) Where and when is this spec discussed? I am really interested in the different opinions, pro and con. Let's be transparent.

Having that said, I would like to share what are my first, quick thoughts are...

  • In general, Microsoft is already known to be heavily backwards compatible. This adds even more... complications.
  • It blurs the lines between version numbers. If you can opt-in or opt-out of specific things, you are less confidant about the production you're actually using. It can mean that, when a certain new function is added to a specific new version, but opted-out, it can frustrate people as to "Why is this specific thing not working?!"
  • Compare Windows xxH2 versions. They are yearly mileposts, but many, many features that are supposed to "belong" to that version, may only be turned on long after the installation. And this testing is not even in the user's control. For example, I am using 25H2 and long after that installation I saw that new Start Menu. But after about a week or so, it was reverted!

As you can see, the entire idea of selective features in a certain release is a no-go for me in the first place. But that's my opinion...

There are prior art to these flags, e.g. react native's turbo module, fabric render engine. Having these flags allow eager developers to test feature early, without requiring hesitant developers to join or wait for the next major version upgrade. I in principle support this feature flag spec.

I only have two concerns:

  1. Technical debt and Maintenance burden - unless the WinUI team suddenly gained lots of resources, given the track record (from 2019 until now...), asking the already under-staffed WinUI team to support multiple behavior across (at a minimum) 3 major versions is asking a lot. I'm not confident about it unless more are disclosed
  2. A manifest/MSBuild-property based approach is a must. Having to "downgrade" to manually writing the main just for enabling a feature is unacceptable developer experience in 2026. Other ecosystems, e.g. react, rely heavily onxxx.config.js and friends, and developers could just configure libraries/tool behavior declaratively in these files. Enabling a feature is as simple as adding isFeatureXEnabled: true. You might want to invent a new options format (.xamlconfig like .editorconfig?) in the long run, but MSBuild property is the bare minimum this should be shipped with IMO.

@Jay-o-Way

Copy link
Copy Markdown
Contributor

Having these flags allow eager developers to test feature early

Isn't that what beta/preview versions are for? 🤓

@riverar

Rafael Rivera (riverar) commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Windows App SDK currently already ships a similar system with RuntimeCompatibilityChange. What does this do that theirs doesn't? Can you maybe leverage their system? https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Compatibility/RuntimeCompatibilityOptions.md

@sundaramramaswamy

Sundaram Ramaswamy (sundaramramaswamy) commented May 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Windows App SDK currently already ships a similar system with RuntimeCompatibilityChange. What does this do that theirs doesn't? Can you maybe leverage their system? https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Compatibility/RuntimeCompatibilityOptions.md

They serve different purposes. Servicing changes are, by definition, fixes — RuntimeCompatibilityOptions lets you opt out temporarily when a fix accidentally regresses your app. Breaking changes are, by definition, guaranteed to break an app making an assumption in the area being changed — XamlOptionalChanges lets you opt in deliberately after validating your app handles the new behavior. Opposite polarity, complementary systems.

@sundaramramaswamy

Sundaram Ramaswamy (sundaramramaswamy) commented May 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Having these flags allow eager developers to test feature early

Isn't that what beta/preview versions are for? 🤓

Preview versions help with testing but don't solve the problem: when a breaking change ships in stable, it's on for everyone with no escape hatch. This API lets individual apps adopt breaking changes on their own schedule in stable, not just preview.

@sundaramramaswamy

Sundaram Ramaswamy (sundaramramaswamy) commented May 26, 2026 •

Copy link
Copy Markdown
Contributor Author

I only have two concerns:

  1. Technical debt and Maintenance burden [...]
  2. A manifest/MSBuild-property based approach is a must.

(1) The strict semver lifecycle keeps maintenance bounded — changes are default-off within a major, default-on at the next, removed at the one after. No indefinite dual code paths. (2) Agreed — an MSBuild property is planned (see the thread on line 62). No one will need DISABLE_XAML_GENERATED_MAIN for this.

@neerajmsgithub

neerajmsgithub commented May 27, 2026 •

Copy link
Copy Markdown
Contributor

DISCUSSION: Xaml island scenario where different islands want to use different Xaml options is problematic. WASDK versions have similar problem. So this is not new problem.

@tusharsnx

Tushar Singh (tusharsnx) commented May 28, 2026 •

Copy link
Copy Markdown
  1. It's also important to discuss (and could be enforced through the API design) whether XamlOptionalChanges aims to give developers a long-term or short-term escape hatch.

  2. Manifest based opt-in should be the primary way for opting in, while keeping programmatic enablement as an advance scenario. Also, when changes are programmatic enabled, it should merge with the changes coming from the manifest instead of overriding the whole set. Conflicting configs should throw errors instead of silently doing some magic.

@dotMorten

Copy link
Copy Markdown
Contributor

My initial feedback on this is the opt-in for performance: Performance should be the default. I understand there might be behavioral changes, but you need to move this platform forward and create an SDK people are happy to use by default.

Compare to .NET's feature switches, which is always opting-out of new features: https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/appcontextswitchoverrides-element

It would also be nice for .NET developers to be able to use the well-known approach of using appcontext switches to control features, rather than having to use a different way when developing for WinUI.

@mominshaikhdev

Copy link
Copy Markdown

My initial feedback on this is the opt-in for performance: Performance should be the default.

exactly. performance should always be the default in a native framework that is designed to be consumed by languages projections.

@ghost1372

Copy link
Copy Markdown
Contributor

Interesting... API Now Exist!
cc64a0b

@riverar

Rafael Rivera (riverar) commented May 29, 2026 •

Copy link
Copy Markdown
Contributor

So what's the point of this PR if you already wrote the code and merged it in? cc64a0b

EDIT: I don't know what pre-seed means in this context, that's not community or common terminology.

I feel like you wasted my time with fake community engagement.

@evelynwu-msft

Copy link
Copy Markdown
Member

So what's the point of this PR if you already wrote the code and merged it in? cc64a0b

EDIT: I don't know what pre-seed means in this context, that's not community or common terminology.

I feel like you wasted my time with fake community engagement.

In this case, we chose to implement the feature in parallel with the spec review as we did not expect major divergence as an outcome of the review. The commit you saw is simply our initial implementation and it is fully our intention to revise it based on the feedback from this review.

@riverar

Copy link
Copy Markdown
Contributor

Sounds good, thanks Evelyn Wu (@evelynwu-msft)!

@sundaramramaswamy

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback, Tushar Singh (@tusharsnx).

  1. Short-term vs long-term: The API is designed as a short-term bridge. A change is introduced as opt-in, may become the default in a subsequent major version, and eventually becomes permanent — at which point the enum value stays in ABI but becomes a no-op. The updated spec captures this lifecycle in the XamlChangeId remarks.

  2. Manifest / MSBuild as primary path: Agreed — a declarative MSBuild property will be the primary configuration path, with the programmatic API available for advanced scenarios. On merge semantics: programmatic calls will layer on top of the declaratively configured set (additive merge, not override). Conflicting configs (e.g. manifest enables, code disables the same change) will throw. Good callouts — these align with where the design is headed.

@tusharsnx Tushar Singh (tusharsnx) left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnableChange and DisableChange sound too generic IMO. I'd prefer EnableXamlChange and DisableXamlChange with XamlChangeId.

Nvm, the method names are fine.

Remove 'eventually removed' wording from rationale
sections. The spec commits to [deprecated] attributes
on graduated enum values, not physical removal, which
is consistent with WinRT's additive-only type system.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-triage Issue needs to be triaged by the area owners

Projects

None yet

Development

Successfully merging this pull request may close these issues.