Microsoft.UI.Reactor: o que é e como usar no WinUI

O Microsoft.UI.Reactor é um framework experimental em C# que traz o padrão MVU para apps desktop com WinUI.
Na prática, você descreve a interface com funções C# comuns, sem arquivos XAML, sem code behind e sem ViewModels.
A Microsoft mostrou o projeto na Build 2026 e, em 21 de outubro de 2026, publicou um tour completo no blog ifdef Windows. Este artigo explica o que é o Reactor, como ele funciona, como ele se compara ao XAML com MVVM e como começar a usar hoje.
O que é o Microsoft.UI.Reactor
Antes de tudo, o Microsoft.UI.Reactor não é uma nova plataforma de UI. Ele não tem um renderizador próprio e também não é um fork do WinUI.
Quando você escreve Button, TextBox, NavigationView ou TreeView, recebe o controle real do WinUI. Esse controle usa os mesmos painéis de layout, os mesmos recursos de tema e as mesmas ferramentas de inspeção de um app XAML.
Por outro lado, algumas peças pertencem ao projeto, como o painel de layout flex. Mesmo assim, essas peças usam as mesmas primitivas que um app XAML já usa.
Em outras palavras, o que muda no Microsoft.UI.Reactor é a forma de descrever a interface, não a interface em si.
Assim, em vez de escrever marcação que vira uma árvore de controles, você escreve uma função C# que retorna uma descrição imutável da tela. Em seguida, o framework compara essa descrição com a anterior e altera apenas o que mudou nos controles reais.
Um projeto experimental de propósito
O próprio time deixa dois avisos claros logo no início do anúncio.
Primeiro, o Microsoft.UI.Reactor é experimental: não há política de suporte nem garantia de API. A Microsoft publicou o projeto cedo de propósito, porque prefere ouvir agora que errou no design.
Segundo, o Reactor não substitui o XAML nem o MVVM. Por isso, o rótulo experimental continua nos próximos meses, e a sintaxe da DSL ainda pode mudar.
MVVM e MVU: dois padrões diferentes
Apps XAML costumam seguir o MVVM, sigla para Model-View-ViewModel. Nesse modelo, o estado mora em um ViewModel, que anuncia cada mudança.
Então, os bindings puxam os novos valores para os controles da tela.
Já o Microsoft.UI.Reactor usa o MVU, sigla para Model-View-Update. Nesse caso, o estado fica em um único lugar, e uma função de atualização devolve o próximo estado.
Além disso, a view passa a ser apenas uma função desse estado. O Elm popularizou essa ideia, e React, SwiftUI e Jetpack Compose seguem variações dela.
Contudo, nenhum dos dois padrões é uma versão mais nova do outro. De fato, são dois padrões consolidados, com vantagens e custos diferentes, e agora o WinUI roda ambos.
Por que a Microsoft criou o Microsoft.UI.Reactor
O primeiro objetivo é descobrir até onde o MVU consegue ir no WinUI.
Hoje, quem vem de React, SwiftUI ou Jetpack Compose precisa aprender XAML e um motor de binding antes de começar. Assim, o time quer saber se o Microsoft.UI.Reactor consegue remover essa etapa.
Além disso, interfaces escritas em C# puro se mostraram fáceis de ler, escrever e verificar por agentes de código. Por isso, o projeto agora considera agentes de IA, e não apenas pessoas, no design da API.
Por fim, o Reactor funciona como um laboratório para o WinUI. Controles e padrões novos aparecem nele primeiro, e os que se provarem úteis podem chegar ao próprio WinUI, inclusive para apps XAML.
Um app completo com Microsoft.UI.Reactor em um arquivo
O exemplo oficial é um contador, e ele cabe inteiro em um único arquivo. Isso inclui a referência ao pacote e as configurações de build.
#:package Microsoft.UI.Reactor@0.1.0-preview.16
#:property OutputType=WinExe
#:property TargetFramework=net10.0-windows10.0.22621.0
#:property UseWinUI=true
using Microsoft.UI.Reactor;
using Microsoft.UI.Reactor.Core;
using static Microsoft.UI.Reactor.Factories;
// Abre a janela com título e tamanho iniciais
ReactorApp.Run<MyApp>("Hello Reactor", width: 340, height: 200);
class MyApp : Component
{
public override Element Render()
{
// Estado local do componente: valor atual e função para alterá-lo
var (count, setCount) = UseState(0);
return VStack(
TitleBar("Hello Reactor"),
VStack(12,
Heading($"Count: {count}"),
HStack(8,
Button("-", () => setCount(count - 1)),
Button("+", () => setCount(count + 1))
.AccentButton()
)
).Padding(24)
).Backdrop(BackdropKind.Mica);
}
}
As linhas que começam com #: vêm dos apps baseados em arquivo do .NET 10. Elas colocam referências de pacotes e propriedades de build no mesmo arquivo do código.
Para executar, basta salvar o conteúdo como counter.cs e rodar o comando abaixo.
winapp run counter.cs
Logo depois, uma janela WinUI real abre, com uma TitleBar, um TextBlock e dois Button, e o contador funciona.
Como ler o método Render
A classe MyApp herda de Component e sobrescreve o método Render.
Dentro dele, o hook UseState cria o estado count e a função setCount, que o atualiza. Depois, o método monta a tela com VStack, HStack, Heading e Button, todos vindos de Factories.
Cada botão recebe uma lambda que chama setCount com o novo valor. Quando o estado muda, o Microsoft.UI.Reactor chama Render de novo e aplica só a diferença nos controles.
Modificadores encadeados, como .Padding(24), .AccentButton() e .Backdrop(BackdropKind.Mica), ajustam espaçamento, estilo e fundo.
Para apps maiores, você usa um projeto normal criado por template. Mesmo nesse caso, o código do Reactor continua igual.
O papel do winapp CLI
O winapp é a CLI da Microsoft para desenvolvimento de apps Windows. Ela cuida de scaffolding, identidade de pacote, empacotamento MSIX e assinatura.
Além disso, ela funciona com qualquer framework que tenha o Windows como alvo, não só com o Reactor. A versão 0.7.0 trouxe a execução direta de arquivos .cs, recurso que o exemplo acima usa.
Segundo a documentação de uso do winapp CLI no Microsoft Learn, o modo de arquivo único gera um manifesto a partir das diretivas #:property. Em seguida, a CLI abre o app com identidade de pacote.
Também dá para ficar só no dotnet run, com algumas flags a mais.
dotnet run counter.cs -a x64 -p:WindowsAppSDKSelfContained=true
Nesse caso, o app roda sem pacote, porque a identidade e o MSIX são justamente o que o winapp acrescenta.
O mesmo contador com XAML e MVVM
Para comparar de forma justa, o time escreveu a versão XAML como um bom desenvolvedor faria em 2026. Ou seja, com x:Bind e com os source generators do MVVM Toolkit fazendo o trabalho pesado.
Essa versão exige ao menos cinco arquivos e um projeto: a janela, o code behind, o ViewModel, o App.xaml, o App.xaml.cs e o .csproj. Abaixo estão os três arquivos que concentram o contador.
<!-- MainWindow.xaml -->
<Window x:Class="CounterApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hello XAML">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
<StackPanel>
<TitleBar x:Name="AppTitleBar" Title="Hello XAML" />
<StackPanel Spacing="12" Padding="24">
<TextBlock Text="{x:Bind ViewModel.CountText, Mode=OneWay}"
Style="{StaticResource TitleTextBlockStyle}" />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="-" Command="{x:Bind ViewModel.DecrementCommand}" />
<Button Content="+" Command="{x:Bind ViewModel.IncrementCommand}"
Style="{StaticResource AccentButtonStyle}" />
</StackPanel>
</StackPanel>
</StackPanel>
</Window>
// MainWindow.xaml.cs
public sealed partial class MainWindow : Window
{
public CounterViewModel ViewModel { get; } = new();
public MainWindow()
{
InitializeComponent();
// Estende o conteúdo para a barra de título
ExtendsContentIntoTitleBar = true;
SetTitleBar(AppTitleBar);
}
}
// CounterViewModel.cs
public partial class CounterViewModel : ObservableObject
{
// O source generator cria a propriedade e a notificação de mudança
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(CountText))]
public partial int Count { get; set; }
public string CountText => $"Count: {Count}";
[RelayCommand] private void Increment() => Count++;
[RelayCommand] private void Decrement() => Count--;
}
O que essa comparação revela
Esse XAML é bom, e os geradores eliminam quase todo o boilerplate que deixou o MVVM famoso. No entanto, alguns pontos continuam verdadeiros, mesmo com o melhor código possível.
- O valor passa por três arquivos e duas linguagens antes de chegar à tela.
- A expressão
{x:Bind ViewModel.CountText}é uma string que o compilador XAML precisa interpretar. - Se você renomear
CountTextno C#, depende das ferramentas para atualizar o XAML. - O estado vive em uma classe que existe apenas para que a tela a observe.
- Para saber como a tela fica quando
Countvale 5, você lê três arquivos e simula o binding de cabeça.
No Microsoft.UI.Reactor, essa última pergunta tem uma resposta simples: basta ler o Render. Afinal, ele é uma função que recebe um contador e devolve uma interface.
Segundo o time, quase todas as vantagens do Reactor nascem dessa ideia. Mesmo assim, a própria Microsoft lembra que ficar com XAML em uma tela específica continua uma resposta válida.
O que o Microsoft.UI.Reactor oferece além de menos arquivos
A vantagem principal não está nos arquivos a menos, e sim na verificação em tempo de compilação. Assim, não existem falhas de binding aparecendo na janela de saída durante a execução.
Da mesma forma, renomear uma propriedade atualiza todos os usos, porque todos os usos estão em C#. O estado fica ao lado da interface que o usa, sem classe de ViewModel e sem a infraestrutura de PropertyChanged.
Além disso, o Microsoft.UI.Reactor já traz vários recursos prontos para uso.
- Layout flexbox com uma portabilidade fiel, em C#, do motor Yoga da Meta.
- Commanding e navegação entre telas.
- Tokens de tema e localização.
- Um DataGrid e um sistema de docking de painéis.
Analisadores Roslyn no Microsoft.UI.Reactor
Como a interface é C# comum, toda a cadeia de ferramentas do Roslyn atua sobre ela. Por isso, o projeto entrega mais de 60 analisadores específicos do Microsoft.UI.Reactor.
Eles cobrem hooks, acessibilidade, temas, commanding e desempenho. Na prática, eles detectam problemas que a marcação esconde.
- Item de lista sem chave.
- Hook chamado dentro de um
if. - Pincel fixo que não sobrevive ao modo escuro.
- Botão só com ícone, que o leitor de tela anuncia apenas como botão.
Dessa forma, você descobre o erro segundos depois de digitar, e não semanas antes da entrega.
Onde o XAML continua se encaixando
A Microsoft foi direta nesse ponto: o WinUI é a base, e o XAML continua como uma forma de primeira classe de usá-lo. O XAML segue recebendo investimento ativo, e a empresa não vai descontinuá-lo.
O modelo XAML com MVVM atende boa parte dos usuários do WinUI. Também por isso, o designer, os templates, a documentação e o ecossistema de controles de terceiros continuam no lugar.
Assim, os dois modelos convivem de propósito. Se você já entrega com XAML e MVVM, a recomendação oficial é continuar entregando.
Por outro lado, se você quer MVU sem XAML, o Microsoft.UI.Reactor oferece esse caminho no mesmo runtime e com os mesmos controles. E, se quiser os dois, eles interoperam nos dois sentidos, no mesmo processo e na mesma árvore visual.
Faltou algum controle? Qualquer outro controle WinUI, de terceiros ou seu, pode virar um elemento do Reactor e funcionar como os nativos.
Se você vem do mundo mobile, o comparativo entre .NET MAUI e Flutter no blog do balta.io ajuda a contextualizar essa discussão entre XAML e UI declarativa. Já para ver o MVVM aplicado em outro framework, vale também a live sobre Blazor com MVVM.
Como começar com o Microsoft.UI.Reactor
Para começar com o Microsoft.UI.Reactor, você precisa de dois itens: o SDK do .NET 10 e o winapp CLI na versão 0.7 ou superior. Para instalar a CLI, use o winget.
winget install Microsoft.WinAppCli
Depois disso, o caminho mais rápido é o próprio contador: salve o arquivo e rode winapp run counter.cs. O comando compila o arquivo, gera um manifesto de pacote e abre o app com identidade de pacote real.
Se preferir o dotnet run, adicione a linha #:package Microsoft.Windows.SDK.BuildTools.WinApp@* ao arquivo. Com isso, o dotnet run faz o mesmo lançamento empacotado, que é exatamente o que o winapp faz por baixo dos panos.
Templates do Microsoft.UI.Reactor
Quando você quiser um projeto de verdade, e não um arquivo de rascunho, use os comandos abaixo.
winapp new -t reactor -n MyApp
cd MyApp
winapp run
Assim, a CLI cria um app empacotado com Package.appxmanifest, assets e perfis de publicação. Se o pacote de templates do WinUI faltar na máquina, ela instala tudo automaticamente.
Além disso, builds de debug já incluem as devtools do Reactor. A tabela abaixo resume os quatro templates disponíveis.
| Template | O que entrega |
|---|---|
reactor |
App em branco, só com C# |
reactor-mvu |
Estado, ações e um reducer já conectados |
reactor-navview |
App inicial com NavigationView |
reactor-tabview |
App inicial com TabView |
Todos os quatro templates continuam experimentais. Para ver a lista completa, incluindo os templates XAML, rode winapp new --list.
Código aberto, Rust e uso em produção
Todo o Microsoft.UI.Reactor está no GitHub sob a licença MIT, no repositório microsoft/microsoft-ui-reactor.
O repositório inclui o framework, as especificações de design, apps de exemplo, a suíte de testes, a CLI, os analisadores e a extensão para VS Code.
Esse movimento acompanha o próprio WinUI, que também leva o desenvolvimento do dia a dia para o repositório microsoft/microsoft-ui-xaml. Segundo a Microsoft, o Reactor nasceu público desde o primeiro commit, sem um branch interno onde o trabalho real acontece.
Além disso, o projeto já roda fora dos exemplos oficiais. O app companheiro do OpenClaw para Windows usa o Reactor em produção no chat, ativado por padrão.
Como esse app também tem código aberto, dá para ler como uma aplicação real usa o framework.
windows-reactor para quem prefere Rust
A ideia também não depende do C#. No projeto windows-rs, o time conduz o mesmo experimento em Rust com o windows-reactor.
Trata-se de uma biblioteca declarativa de WinUI em que os componentes guardam o próprio estado. Nela, os controles enviam mensagens tipadas de volta, e apenas os controles alterados recebem atualização.
O windows-reactor também está no início e já aparece no crates.io.
Quando faz sentido testar o Microsoft.UI.Reactor
Como não há política de suporte, apostar no Microsoft.UI.Reactor em um app crítico exige cautela. Por outro lado, este é o momento em que o feedback ainda muda o design, antes que vire quebra de compatibilidade.
A Microsoft listou quatro perguntas que quer ver respondidas pela comunidade.
- A DSL continua legível em uma tela de 400 linhas, e não só em exemplos de 12?
- Em qual controle, layout ou cenário o Reactor falha e obriga a voltar ao XAML?
- A interoperabilidade permite adotar o framework aos poucos dentro de um app existente?
- O WinUI realmente precisa disso, ou a ideia não faz sentido?
Para quem vem de React, SwiftUI ou Compose, o modelo deve parecer familiar logo de cara. Já para quem domina XAML, vale testar em uma tela pequena e comparar o resultado.
Os canais de feedback incluem os comentários do post, as issues do GitHub e o guia oficial do Reactor.
No próximo mês, o time promete um tour pelos cerca de vinte apps do repositório, como um editor de registro, um cliente de chat e uma IDE com painéis destacáveis. Também promete construir um campo minado completo e responder onde o estado fica quando não existe ViewModel.
Conclusão
O Microsoft.UI.Reactor propõe outra forma de descrever interfaces WinUI, com MVU, C# puro e os mesmos controles nativos. Ele não substitui o XAML nem o MVVM, e os dois modelos interoperam no mesmo app.
Na prática, o ganho está na verificação em tempo de compilação, no estado ao lado da interface e nos analisadores Roslyn. Contudo, o rótulo experimental pede cautela, porque a sintaxe pode mudar e não há garantia de API.
Portanto, o melhor uso hoje do Microsoft.UI.Reactor é experimentar em telas pequenas e enviar feedback enquanto o design ainda está aberto.
FAQ
O Microsoft.UI.Reactor substitui o XAML?
Não. A Microsoft afirma que o XAML continua uma forma de primeira classe de usar o WinUI e segue recebendo investimento.
O Reactor usa controles próprios ou controles do WinUI?
Ele renderiza os controles reais do WinUI. Apenas algumas peças, como o painel de layout flex, pertencem ao projeto, e elas usam as mesmas primitivas do WinUI.
Preciso do winapp CLI para rodar um app Reactor?
Não. O dotnet run também funciona, mas o winapp acrescenta a identidade de pacote e o empacotamento MSIX.
Posso misturar Reactor e XAML no mesmo app?
Sim. Os dois modelos interoperam nos dois sentidos, no mesmo processo e na mesma árvore visual.
O Microsoft.UI.Reactor está pronto para produção?
Ele ainda carrega o rótulo experimental, sem política de suporte nem garantia de API. Mesmo assim, o app do OpenClaw para Windows já usa o framework em produção.