The dotnet new templates for Uno Platform: one C# and XAML codebase, running on Android, iOS, WebAssembly, Windows, macOS and Linux. This repo also builds the Uno.Sdk that those templates sit on.
dotnet new install Uno.Templates
dotnet new unoapp -o MyAppThat gives you a blank multi-platform app. Want the full "production-ready" setup (navigation, DI, configuration, localization, HTTP, logging, tests...)? Add -preset recommended.
New to Uno Platform? The Get Started guide walks you through installing everything you need. You can also create projects from the IDE:
- Visual Studio extension
- Visual Studio Code and Rider extensions (see the Get Started guide)
The IDE wizards use the same templates as the command line.
| Short name | Name | What it is |
|---|---|---|
unoapp |
Uno Platform App | The main solution template: a multi-platform app targeting Android, iOS, tvOS, WebAssembly, Skia Desktop (Windows, macOS, Linux) and Windows App SDK. |
unoapp-reactor |
Uno Platform Reactor App | A single-project app built with Reactor: components and hooks in C#, no XAML. Targets Android, iOS, WebAssembly and Skia Desktop (Windows, macOS, Linux). |
unolib |
Uno Platform Class Library | A cross-targeted class library for Uno Platform (WinUI, Android, iOS, WebAssembly and Skia). |
unomauilib |
Uno Platform Maui Embedding Class Library | A library for .NET MAUI controls that you embed inside an Uno Platform app. |
unoapp-uitest |
Uno Platform UI Tests Class Library | A project for UI tests of an Uno Platform app. |
Run dotnet new unoapp --help for the full list. These are the ones you will reach for most:
| Option | Alias | Values | Default |
|---|---|---|---|
--preset |
-preset |
blank, recommended |
blank |
--tfm |
-tfm |
net10.0, net11.0 |
net10.0 |
--platforms |
-platforms |
android, ios, tvos, wasm, desktop, windows (repeatable) |
android, ios, wasm, desktop |
--renderer |
-renderer |
skia, webgpu (repeatable) |
skia |
--presentation |
-presentation |
none, mvvm, mvux |
depends on preset |
--markup |
-markup |
xaml, csharp |
xaml |
--app-theme |
-theme |
material, fluent, cupertino, simple |
depends on preset |
--navigation |
-nav |
regions, blank |
depends on preset |
--authentication |
-auth |
none, custom, msal, oidc, Web |
none |
--use-http |
-http |
none, basic, refit, kiota |
depends on preset |
--logging |
-log |
none, default, serilog |
depends on preset |
--tests |
-tests |
none, unit, ui |
depends on preset |
--server |
-server |
true, false |
false |
--toolkit |
-toolkit |
true, false |
depends on preset |
--dsp |
-dsp |
true, false |
depends on preset |
--continuous-integration |
-ci |
none, azure, github |
none |
--skip-restore |
-skip |
true, false |
false |
There are plenty more (dependency injection, configuration, localization and cultures, theme service, SVG, MAUI embedding, PWA manifest, VS Code and Rider files...). Defaults marked "depends on preset" change when you pick -preset recommended.
The other templates are much smaller. They all take --tfm; unoapp-reactor also takes --platforms and --app-id, unolib takes --global-json, and unomauilib takes --android, --ios and --winappsdk.
# Recommended preset, MVVM instead of MVUX
dotnet new unoapp -o MyApp -preset recommended -presentation mvvm
# C# Markup with the Fluent theme and the Uno Toolkit
dotnet new unoapp -o MyApp -preset recommended -markup csharp -theme fluent -toolkit
# Desktop and WebAssembly only
dotnet new unoapp -o MyApp -platforms desktop wasm
# WebGPU first, with Skia as the fallback (WebGPU is experimental)
dotnet new unoapp -o MyApp --renderer skia webgpu
# The default platforms plus Apple TV
dotnet new unoapp -o MyApp -platforms android ios tvos wasm desktop
# Recommended app with a server, Kiota HTTP client and OIDC auth
dotnet new unoapp -o MyApp -preset recommended -server -http kiota -auth oidc
# A Reactor app for desktop and WebAssembly
dotnet new unoapp-reactor -o MyApp -platforms desktop wasm
# A class library
dotnet new unolib -o MyLibrary| Path | What lives there |
|---|---|
src/Uno.Templates |
The template pack project (Uno.Templates.csproj). The templates themselves are under content/ (unoapp, unoapp-reactor, unolib, unolib-uitest, unomauilib). reinstall.ps1 builds and installs the pack locally. |
src/Uno.Sdk |
The Uno.Sdk MSBuild SDK package, including packages.json, the version manifest. |
src/Uno.Templates.sln |
Solution for the projects above. |
tools/Uno.Sdk.Updater |
The tool that bumps package versions in packages.json and friends. |
tools/TemplateTfmSwitchGenerator |
Generates the per-TFM switch cases used by the template configuration. |
build |
PowerShell scripts for CI checks (stable pins, NuGet.org dependency verification, wizard icons and options, signing, Windows SDK install) and updater config in build/templates. |
specs |
Design specs for template changes. |
.github |
CI workflows and the composite actions they use. |
version.json |
Nerdbank.GitVersioning configuration. |
The templates generate projects that use Uno.Sdk (the "Uno Platform Single Project"), and this repo builds and ships that package too. The SDK takes care of the platform heads and the versions of the commonly used NuGet packages, so your project file stays small.
Package versions come from src/Uno.Sdk/packages.json, a manifest of package groups (Uno core, Extensions, Toolkit, Themes, WASM Bootstrap, SkiaSharp, WinAppSDK, AndroidX, MAUI...). Nobody edits it by hand for routine bumps:
- The Update Uno Sdk workflow (
uno-updater.yml) runs every 6 hours, usestools/Uno.Sdk.Updaterto refresh the manifest formainand the supported release branches, and opens a pull request with auto-merge enabled. uno-updater-pr.ymlruns the same update on PRs that touch the updater itself.- On stable release branches, CI rejects prerelease pins (
build/Verify-StablePins.ps1). A prerelease the release ships on purpose, because no stable version exists yet, is listed with its reason inbuild/Verify-StablePins.AllowedPrereleases.jsonon that branch, and every CI run shows it as a warning.
If you need a different version in your own app, you can override it with an MSBuild property. The Uno.Sdk ReadMe lists every property and its current default.
You need a .NET SDK (CI builds the packages with 9.0.300). To also build the apps the templates generate, follow the Get Started guide.
The quick way, from src/Uno.Templates (PowerShell):
./reinstall.ps1It uninstalls any installed Uno.Templates (and legacy template packs), cleans bin/obj, builds the pack as version 255.255.255.255 and runs dotnet new install on the resulting .nupkg.
Or do it by hand:
dotnet build src/Uno.Templates/Uno.Templates.csproj -c Release -p:PackageVersion=255.255.255.255
dotnet new uninstall Uno.Templates
dotnet new install src/Uno.Templates/bin/Release/Uno.Templates.255.255.255.255.nupkgCI does the same for both packages (dotnet build -c Release -p:PackageVersion=..., see build-packages). Building src/Uno.Sdk/Uno.Sdk.csproj works the same way, but it first downloads the SDK content from Uno's package feed, so it needs network access to it.
dotnet new unoapp -o ../TestApp -preset recommended
cd ../TestApp
dotnet buildPass -skip (--skip-restore) to skip the restore when you only want to look at the generated files.
ci.yml runs on pushes and PRs to main, servicing/* and release/*, plus a nightly canary run:
- Verifies there are no prerelease pins on stable release branches, apart from the allowed ones.
- Builds the
Uno.SdkandUno.Templatespackages. Beside the build, it checks the wizard metadata (the iconsTemplateWizard.jsonnames, its options and values againsttemplate.json, and that each preset meets the requirements of what it turns on) and runs thebuild/*.Tests.ps1script tests: a failure there fails the run, but doesn't hold back the packages. - Signs them, and publishes dev builds from
main(production publishing sits behind approval gates). - Generates a test matrix (
generate-test-matrix): a big list ofdotnet newargument combinations (presets, platforms, markup, MVVM/MVUX, HTTP flavors, auth modes, themes, MAUI embedding, libraries...). - Runs that matrix on Linux, Windows and macOS: install the freshly built templates, create each project, and build it (
run-tests). For-ci, it also checks that the pipeline files it creates are valid YAML.
If you add or change an option, add a matching entry to the matrix. If the wizard shows it, TemplateWizard.json names its icon: add the icon under unoapp/.template.config/Assets in its four theme variants (Assets/, Dark/, Disable/ and DarkDisable/), and remove the icons nothing names anymore, unless they wait for an option on the script's kept list (Test-WizardIcons.ps1 checks both). When you rename or remove an option or one of its values, update TemplateWizard.json too: the wizards silently skip what template.json doesn't define (Test-WizardOptions.ps1 checks it). A preset can't turn on an option its own requirements disable, such as Import Uno DSP without the Material theme: the same script checks that too. The Visual Studio wizard and the Live Wizard take the metadata from the templates package.
The nightly run is this repo's canary, like the canaries of the other Uno Platform repos:
- It starts from
mainand moves the Uno packages to their newest dev builds, with the samesdk-updatestep as the Update Uno Sdk workflow (see Uno.Sdk). Packages that aren't Uno's keep their pins.Uno.UITest.Helpers, the one Uno package outsidepackages.json, moves too. - It builds the packages and runs the whole matrix on them. Nothing is committed or published.
- The run is named Canary: newest Uno dev builds, and its summary lists every version it tried.
A red canary means a newer Uno dev build breaks the templates, or something outside changed, such as a runner image, the .NET SDK or a workload. Start from the versions in the run summary. The nightly runs are listed under Actions.
To try the canary on a branch, run CI manually with canary: true. Unlike the other canaries there is no canaries/dev branch: the scheduled run always uses main's workflow and applies the update in its workspace, so there is no branch to keep in sync.
Contributions are welcome. Please:
- Read the Code of Conduct.
- Report security issues as described in SECURITY.md, not in a public issue.
- Use Conventional Commits for your commits (
feat: ...,fix: ...,docs: ...). The conventional-commits check validates every PR and fails if they do not match.
Licensed under the Apache License 2.0.