Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fc86e0b
Add Reactor (Microsoft.UI.Reactor) dotnet new templates
azchohfi Jul 13, 2026
7079826
Fix Reactor template runtime crash: remove TitleBar icon
azchohfi Jul 13, 2026
572c23a
Bump Reactor templates to preview.12 and restore title-bar icon
azchohfi Jul 15, 2026
e31aed3
Merge branch 'main' into azchohfi-reactor-dotnet-new-templates
azchohfi Jul 15, 2026
cc5a9b1
Merge branch 'main' into azchohfi-reactor-dotnet-new-templates
azchohfi Jul 22, 2026
a6bc434
Provision .NET 10 SDK in dotnet-new templates test stage
azchohfi Jul 23, 2026
5d76a37
Address PR review: trim launchSettings comments, use per-template icons
azchohfi Jul 24, 2026
47bcf4f
Add winui-reactor* short-name aliases to Reactor templates
azchohfi Jul 24, 2026
c15e219
reactor-tabview: integrate tabs into the title bar
azchohfi Jul 24, 2026
94e206a
Make Reactor templates packaged (MSIX) and match the WinUI templates
azchohfi Jul 24, 2026
74f8df0
reactor-mvu: greet 'Hello, Reactor!'; use WinUI type-ramp styles for …
azchohfi Jul 24, 2026
768ac67
reactor-tabview: give tab pages a solid background to match WinUI
azchohfi Jul 24, 2026
cbeb825
reactor-tabview: stretch the tab page surface to fill the content area
azchohfi Jul 24, 2026
bb5bc93
Fill reactor-tabview page surface to window height
azchohfi Jul 24, 2026
cdee0c2
Use Reactor's navigation system in reactor-navview
azchohfi Jul 27, 2026
6b4aebf
Toggle the nav pane on the control instead of mirrored state
azchohfi Jul 27, 2026
2898bec
Match the WinUI page transition in reactor-navview
azchohfi Jul 27, 2026
9dc32b9
Trim the Reactor templates to match the XAML templates' style
azchohfi Jul 27, 2026
d0b3e47
Mark the Reactor templates as experimental
azchohfi Jul 27, 2026
37fe726
Fix Reactor analyzer warnings in the MVU and TabView templates
azchohfi Jul 27, 2026
6ee1260
Use $targetentrypoint$ in the Reactor manifests, like the XAML templates
azchohfi Jul 28, 2026
61fb3c7
Merge branch 'main' into azchohfi-reactor-dotnet-new-templates
azchohfi Jul 30, 2026
8ea4586
Commit the Reactor templates' publish profiles
azchohfi Jul 30, 2026
f818c19
Stop .gitignore from swallowing template publish profiles
azchohfi Jul 30, 2026
f3f78bd
Match the XAML templates' icon font and size
azchohfi Aug 4, 2026
7542f2e
Update Reactor dotnet new templates for 0.1.0-preview.13
azchohfi Jul 30, 2026
e91d7b3
Let the OS size the window, like the XAML templates
azchohfi Aug 4, 2026
a3eedf0
Add the MsixPackage launch profile to the Reactor templates
azchohfi Aug 5, 2026
5c43a94
Float the Windows App SDK version in the Reactor templates
azchohfi Aug 5, 2026
3c8c640
Merge branch 'main' into azchohfi-reactor-dotnet-new-templates
azchohfi Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,6 @@ build/override/
# WindowsAppSDK specific files
Microsoft.WinUI.AppX.targets
!dev/vsix/**/*.pubxml
# Project templates ship publish profiles as template content, so they must be
# committed despite the blanket *.pubxml rule above.
!dev/Templates/**/*.pubxml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ parameters:
- name: dotnetSdkVersion
type: string
default: '8.0.x'
# Reactor project templates target net10.0 and declare a [10.0,) SDK
# constraint, so the test agent also needs the .NET 10 SDK to scaffold and
# build them. Installed alongside dotnetSdkVersion below.
- name: reactorDotnetSdkVersion
type: string
default: '10.0.x'
- name: WindowsAppSdkVersion
type: string
default: '*'
Expand Down Expand Up @@ -68,6 +74,16 @@ stages:
packageType: sdk
version: '${{ parameters.dotnetSdkVersion }}'

# Reactor templates require the .NET 10 SDK (they target net10.0 and set a
# [10.0,) sdk-version constraint). Install it alongside the version above;
# the .NET muxer picks the highest installed SDK, and the WinUI templates
# auto-detect their TFM and build cleanly on .NET 10 as well.
- task: UseDotNet@2
displayName: 'Use .NET SDK ${{ parameters.reactorDotnetSdkVersion }} (for Reactor templates)'
inputs:
packageType: sdk
version: '${{ parameters.reactorDotnetSdkVersion }}'

- task: NuGetAuthenticate@1
displayName: 'Authenticate NuGet feeds'

Expand Down
50 changes: 50 additions & 0 deletions dev/Templates/Dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,40 @@ Get below list via `dotnet new list winui`

Each `winui-*` short name also has a `winui3-*` alias (e.g. `winui3-mvvm`).

### Reactor Templates (Experimental)

> [!IMPORTANT]
> These templates are **experimental**.
> [Microsoft.UI.Reactor](https://github.com/microsoft/microsoft-ui-reactor) is
> prerelease software: its API may change in breaking ways between releases, and
> these templates may change or be removed. They aren't recommended for
> production apps yet.

[Microsoft.UI.Reactor](https://github.com/microsoft/microsoft-ui-reactor) is a
declarative, React-style way to build WinUI 3 apps in **pure C# — no XAML**.
These templates scaffold a runnable, single-project MSIX-packaged Reactor app
whose UI mirrors the matching WinUI 3 XAML templates.

Get the list via `dotnet new list reactor`

| Short Name | Description |
|--------------------|----------------------------------------------------------------------|
| `reactor` | Blank Reactor app (alias `reactor-blank`). Start here if unsure |
| `reactor-mvu` | Reactor app using the Model-View-Update pattern with `UseReducer` |
| `reactor-navview` | Reactor app with a `NavigationView` shell and multiple pages |
| `reactor-tabview` | Reactor app with a `TabView` shell whose tabs live in the title bar |

Each also has a `winui-reactor*` alias (e.g. `winui-reactor`, `winui-reactor-mvu`)
so they show up under `dotnet new list winui` alongside the other WinUI templates.

Reactor apps are packaged (single-project MSIX) and reference the
[`Microsoft.UI.Reactor`](https://www.nuget.org/packages/Microsoft.UI.Reactor)
preview NuGet package. They require .NET 10 or later. Like the WinUI templates,
they reference `Microsoft.Windows.SDK.BuildTools.WinApp` so `dotnet run` launches
the app with full MSIX package identity. Pin a specific Reactor package version
at scaffold time with `--reactor-version`, or the Windows App SDK version with
`--wasdk-version`.

### Item Templates

| Short Name | Description |
Expand Down Expand Up @@ -64,6 +98,22 @@ dotnet run
`dotnet run` registers a loose-layout MSIX, gives the app package identity,
and launches it via AUMID activation — equivalent to F5 in Visual Studio.

### Quickstart a new Reactor app

```powershell
dotnet new reactor -n MyReactorApp
cd MyReactorApp
dotnet run
```

Reactor apps are pure C# (no XAML) and packaged (single-project MSIX), so
`dotnet run` registers a loose-layout package and launches the app with full
MSIX package identity — equivalent to F5 in Visual Studio. See the
[Reactor documentation](https://github.com/microsoft/microsoft-ui-reactor) to
learn the component model, hooks, and layout system. Swap `reactor` for
`reactor-mvu`, `reactor-navview`, or `reactor-tabview` to start from a richer
shell.

### Add items to an existing project

```powershell
Expand Down
9 changes: 8 additions & 1 deletion dev/Templates/Dotnet/Test-DotnetNewTemplates.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,14 @@ try {
# acquires package identity) via UnitTestClient.Run(), not via
# `dotnet test`. Validate it as an App so we still confirm the
# template builds cleanly.
@{ ShortName = 'winui-unittest'; Kind = 'App' }
@{ ShortName = 'winui-unittest'; Kind = 'App' },
# Reactor (Microsoft.UI.Reactor) app templates: pure C#, unpackaged,
# dotnet-new-only. They build with the same App path below
# (-p:WindowsPackageType=None), and their .csproj already sets it.
@{ ShortName = 'reactor'; Kind = 'App' },
@{ ShortName = 'reactor-mvu'; Kind = 'App' },
@{ ShortName = 'reactor-navview'; Kind = 'App' },
@{ ShortName = 'reactor-tabview'; Kind = 'App' }
)

foreach ($template in $projectTemplates) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "https://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"dotnetVersion": {
"longName": "dotnet-version",
"shortName": "tfm",
"description": "Base TFM for the project (Microsoft.UI.Reactor requires net10.0 or later)."
},
"reactorVersion": {
"longName": "reactor-version",
"shortName": "rv",
"description": "Pin to a specific Microsoft.UI.Reactor NuGet version."
},
"windowsAppSdkVersion": {
"longName": "wasdk-version",
"shortName": "wasdkv",
"description": "Pin to a specific Windows App SDK NuGet version."
},
"skipRestore": {
"longName": "no-restore",
"shortName": ""
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"icon": "icon.png",
"requiredComponents": [
{
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"hostId": "vs",
"componentType": "setupComponent"
}
],
"symbolInfo": [
{
"id": "dotnetVersion",
"name": {
"text": "Framework"
},
"isVisible": "true"
},
{
"id": "reactorVersion",
"name": {
"text": "Microsoft.UI.Reactor version"
},
"isVisible": "true"
},
{
"id": "windowsAppSdkVersion",
"name": {
"text": "Windows App SDK version"
},
"isVisible": "true"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"$schema": "https://json.schemastore.org/template",
"author": "Microsoft",
"classifications": [ "Windows", "WinUI", "Desktop", "Reactor", "Experimental" ],
"tags": {
"language": "C#",
"type": "project"
},
"identity": "Microsoft.WindowsAppSDK.Reactor.CSharp.BlankApp",
"groupIdentity": "Microsoft.WindowsAppSDK.Reactor.CSharp.BlankApp",
"name": "Reactor Blank App (Experimental)",
"shortName": [ "reactor", "reactor-blank", "winui-reactor" ],
"sourceName": "ProjectTemplate",
"defaultName": "ReactorApp",
"description": "Experimental. Creates a blank Microsoft.UI.Reactor (WinUI 3) desktop app. Pure C#, no XAML. Start here if unsure. Microsoft.UI.Reactor is prerelease and its API may change.",
"preferNameDirectory": true,
"constraints": {
"windows-only": {
"type": "os",
"args": "Windows"
},
"sdk-version": {
"type": "sdk-version",
"args": [ "[10.0,)" ]
}
},
"symbols": {
"safeProjectName": {
"type": "derived",
"valueSource": "name",
"valueTransform": "safe_name",
"replaces": "$safeprojectname$"
},
"projectName": {
"type": "derived",
"valueSource": "name",
"valueTransform": "identity",
"replaces": "$projectname$"
},
"dotnetVersion": {
"type": "parameter",
"datatype": "choice",
"description": "Base target framework moniker (TFM). Microsoft.UI.Reactor requires .NET 10 or later.",
"choices": [
{ "choice": "net10.0", "description": "Target .NET 10" }
],
"defaultValue": "net10.0",
"replaces": "$DotNetVersion$"
},
"reactorVersion": {
"type": "parameter",
"datatype": "text",
"defaultValue": "0.1.0-preview.13",
"replaces": "$ReactorVersion$",
"description": "Microsoft.UI.Reactor (and Microsoft.UI.Reactor.Devtools) NuGet version to reference."
},
"windowsAppSdkVersion": {
"type": "parameter",
"datatype": "text",
"defaultValue": "*",
"replaces": "$WindowsAppSdkVersion$",
"description": "Microsoft.WindowsAppSDK NuGet version. Requires 2.1.3 or later; use * for the latest stable."
},
"windowsSdkBuildToolsVersion": {
"type": "parameter",
"datatype": "text",
"defaultValue": "*",
"replaces": "$WindowsSdkBuildToolsVersion$",
"description": "Microsoft.Windows.SDK.BuildTools NuGet version. Use * for the latest stable."
},
"windowsSdkBuildToolsWinAppVersion": {
"type": "parameter",
"datatype": "text",
"defaultValue": "*",
"replaces": "$WindowsSdkBuildToolsWinAppVersion$",
"description": "Microsoft.Windows.SDK.BuildTools.WinApp NuGet version. Use * for the latest stable."
},
"publisherDn": {
"type": "parameter",
"datatype": "text",
"replaces": "$XmlEscapedPublisherDistinguishedName$",
"defaultValue": "CN=AppPublisher",
"description": "Publisher distinguished name used inside Package.appxmanifest."
},
"publisherDisplay": {
"type": "parameter",
"datatype": "text",
"replaces": "$XmlEscapedPublisher$",
"defaultValue": "AppPublisher",
"description": "Publisher display name shown in the manifest."
},
"guid9": {
"type": "generated",
"generator": "guid",
"parameters": {
"format": "D"
},
"replaces": "$guid9$"
},
"skipRestore": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "If specified, skips the automatic restore of the project on create."
}
},
"sources": [
{
"modifiers": [
{
"replacements": [
{
"before": "$targetnametoken$",
"after": "{{safeProjectName}}"
}
]
}
],
"rename": {
"gitignore.txt": ".gitignore"
}
}
],
"primaryOutputs": [
{ "path": "ProjectTemplate.csproj" }
],
"forms": {
"safe_name": {
"identifier": "safe_name"
},
"identity": {
"identifier": "identity"
}
},
"postActions": [
{
"id": "restore",
"condition": "(!skipRestore)",
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
"continueOnError": true,
"description": "Restore NuGet packages required by this project.",
"manualInstructions": [ { "text": "Run 'dotnet restore'" } ]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "https://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"dotnetVersion": {
"longName": "dotnet-version",
"shortName": "tfm",
"description": "Base TFM for the project (Microsoft.UI.Reactor requires net10.0 or later)."
},
"reactorVersion": {
"longName": "reactor-version",
"shortName": "rv",
"description": "Pin to a specific Microsoft.UI.Reactor NuGet version."
},
"windowsAppSdkVersion": {
"longName": "wasdk-version",
"shortName": "wasdkv",
"description": "Pin to a specific Windows App SDK NuGet version."
},
"skipRestore": {
"longName": "no-restore",
"shortName": ""
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"icon": "icon.png",
"requiredComponents": [
{
"id": "Microsoft.VisualStudio.Workload.ManagedDesktop",
"hostId": "vs",
"componentType": "setupComponent"
}
],
"symbolInfo": [
{
"id": "dotnetVersion",
"name": {
"text": "Framework"
},
"isVisible": "true"
},
{
"id": "reactorVersion",
"name": {
"text": "Microsoft.UI.Reactor version"
},
"isVisible": "true"
},
{
"id": "windowsAppSdkVersion",
"name": {
"text": "Windows App SDK version"
},
"isVisible": "true"
}
]
}
Loading