Library / SDK
VincentH-Net/CSharpForMarkup avatar
VincentH-Net/CSharpForMarkup

C# Markup 2: declarative .NET UI without XAML

Concise, declarative C# UI markup for .NET browser / native UI frameworks

840 stars46 forksC#MIT

At a glance

What is it?
C# Markup 2 is a next generation approach to building .NET user interfaces entirely in C#, targeting Uno Platform, WinUI 3 and WPF, with more frameworks promised. Its pitch is brevity, with no repeated new keyword, no explicit alignment assignments and no binding boilerplate, and it separates markup namespaces so IntelliSense shows only what belongs in the file you are editing.
Who is it for?
C# Markup 2 is worth evaluating for a .NET team that has grown tired of XAML, especially one already on Uno Platform, since it removes the boilerplate that dominates XAML files and keeps the IntelliSense list short enough to be useful. It is the wrong choice for a WPF codebase that has settled on XAML with a code generator, and the wrong choice if you need Avalonia, MAUI or Blazor support today, since those are listed as coming rather than available.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 147 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The same UI framework, a different authoring language

C# Markup 2 is described as concise, declarative C# UI markup for .NET browser and native UI frameworks, and the README bills it as a Flutter-like UI development experience for .NET.

The setting matters. Uno Platform supports both XAML and C# UI through its own C# Markup, and this library is a second option in the same space, with the README presenting the choice as options rather than as a replacement. The comparison image in the repository puts XAML, C# Markup 2 and Uno C# Markup side by side, and the argument is that developers get the experience they like and the UI framework gains adoption.

So the library is not a new UI framework. It is an authoring layer over frameworks that already exist, and the frameworks it currently supports are Uno Platform, WinUI 3 through the Windows App SDK, and WPF. Avalonia, MAUI and possibly Blazor are listed as coming.

The target list is broader than the desktop: the README says you can target browsers and native desktop and mobile, and the earlier generation of the library carried WPF, Xamarin, Xamarin Forms and WinUI in its topic tags, which tells you where this came from.

The library is MIT licensed, and the repository is small in structure, with a src directory, a global.json pinning the SDK, a NuGet.config and the images used in the README.

The verbosity argument

The core claim is about how much noise a XAML file contains, and the README is specific about the repetitions it removes.

It says C# Markup 2 goes beyond the first generation C# Markup approaches, naming the MAUI community toolkit markup and the Uno C# Markup as the comparison points, to eliminate a lot of verbosity: no more endless repetitions of the new keyword, of setting HorizontalAlignment to HorizontalAlignment.Center, of the lambda arrow, or of the nameof operator.

The last of those is the interesting one for anyone who writes XAML by hand. In XAML, binding a TextBlock to a property means naming it, and the markup has to spell that out for every control, even though the intention is always the same. The README says the point of that change is to stop specifying for each and every TextBlock binding that yes, you want to bind to the Text property.

So the design goal is that the default case is the common case and you only write the exception. That is a small idea with a large effect on the size of a UI file, and it is the reason the library exists rather than the sum of its features.

Two other claims sit alongside it: you can use the library for part or all of your application UI, and it is designed to handle large UI fast, with practically allocation-free operation, no reflection and efficient C#.

Separated namespaces and the IntelliSense argument

The second design idea is about the editing experience, and it is more unusual than the syntax.

The README says separated markup namespaces eliminate IntelliSense pollution, allow quick discovery and encourage a clean separation of markup and logic. The consequence it gives is concrete: you see only the markup API while editing your page file, and you see the UI framework and other APIs while editing the logic file.

The problem being solved is the one every XAML or code behind developer knows. The completion list in a XAML file is a mixture of markup extensions, framework controls, converters and your own types, and finding the three entries you want means scrolling through hundreds. Splitting the file into a markup half and a logic half, and giving each half its own namespace, keeps both lists short.

The README gives the file names as an example, editing a page markup file and the matching page logic file. Whether the tooling enforces the split automatically or expects you to keep to the convention is not something the README spells out, so that is worth checking in the getting started material for the framework you use.

The design also implies that markup and logic live in different files rather than in one. That is a real change in how a team organises a view, and it is the part that can cost more than the syntax saves.

MVVM, other update models and partial adoption

The library does not impose a single update model. The README says you can use the built-in MVVM support, or any other update model that supports your UI framework, naming Uno MVUX and ReactiveUI as examples.

There is a matching set of NuGet packages for those integrations, among them the Uno Toolkit, the Reactive extensions, the Navigation extensions and the Navigation Toolkit extensions, plus first class packages for two charting libraries and for a mapping library.

The list of published packages tells you how the library composes with a real application. Beyond the core, there are packages for WinUI, for WinUI with the Uno Toolkit, for the Uno Reactive extensions, for the Uno Navigation extensions and the navigation toolkit, for LiveChartsCore with a SkiaSharp view, for ScottPlot, for Mapsui, and a separate package for WPF. There is also a templates package, Modern.CSharp.Templates.

So the story is that the markup layer is small, and the ecosystem of adapters around it is where the actual configuration work lives. Each framework and each add on gets its own package, and the README lists them with NuGet badges including prereleases, which is a reminder that some of this surface is still moving.

The claim that you can use the library for part or all of your application UI follows from that packaging. You can adopt it for one page and leave the rest of an existing XAML application alone.

Trying it with dotnet new templates

The quick play around section is a sequence of template installs and a project creation, and it is the fastest way to see whether the syntax appeals to you.

bash
dotnet new install Uno.Templates
dotnet new install Modern.CSharp.Templates

mkdir MyApp && cd MyApp

dotnet new unoapp -presentation mvvm -renderer skia -platforms desktop -preset recommended
dotnet new mcs-uno-markup2 --presentation mvvm --renderer skia --allow-scripts yes

The first two commands install the template packs, the Uno templates and the modern C# templates. Then a project directory is created and two templates are used inside it: the Uno application template and the C# Markup 2 template, which is registered under the name mcs-uno-markup2.

The parameter names are the same on both, and the README says to use the same presentation and renderer values for unoapp and mcs-uno-markup2, because they must match for the generated project to build. The mvvm presentation, the skia renderer and the desktop platform are the choices in the example.

For discovering the parameters, the README points at the help output of the Uno template command and at the online Uno Platform Live Wizard, which is a browser based way to pick the platform, renderer and features before generating the project.

Versions, packages and the state of the project

The release tags show a package-per-framework versioning scheme rather than a single version number. The most recent are csharpmarkup2-winui-4-0-7 from 2026-04-17 and csharpmarkup2-winui-4-0-0 from 2026-03-31, and before them a Mapsui build tagged for WinUI 3.1.2 with a Mapsui 5 beta in July 2025.

That naming tells you two practical things. The framework is baked into the version, so upgrading Uno means moving to a different package line rather than bumping a version. And the presence of a beta in a tag means some packages are published as prereleases, which the NuGet badges in the README reflect by including prereleases.

The news section records the largest recent step. On 31 March 2026 the project released C# Markup 4.0, described as including .NET 10, Uno Platform 6.5 and more, updating all C# Markup 2 libraries to C# 14, .NET 10 and/or .NET 9 and the latest stable technology versions, with the Uno libraries moved to the newest .NET version supported by the corresponding Uno SDK 6.5 libraries.

That is a fast-moving target. The last push was on 2026-05-29, and the README points at a Discord channel on DotNetEvolution as the place to ask questions.

One more feature is worth noting for anyone with an automated workflow. The README carries a tip that agentic engineering support exists for letting agents use this library, through a separate .NET Agentic Engineering repository, which is an unusual thing to see in a UI library and a sign of where the author expects usage to go.

Editorial conclusion

C# Markup 2 is worth evaluating for a .NET team that has grown tired of XAML, especially one already on Uno Platform, since it removes the boilerplate that dominates XAML files and keeps the IntelliSense list short enough to be useful. It is the wrong choice for a WPF codebase that has settled on XAML with a code generator, and the wrong choice if you need Avalonia, MAUI or Blazor support today, since those are listed as coming rather than available. Verify first which of your targets are actually supported by the current package, because the packages are published per framework, and read the release notes for the version you pin, since the line moved to C# 14, .NET 10 and Uno 6.5 in the 4.0 release.

Frequently asked questions

What is C# Markup 2?

It is a next generation approach to writing .NET user interfaces entirely in C#, described as concise and declarative, offering a Flutter-like authoring experience over frameworks such as Uno Platform, WinUI 3 and WPF.

Which UI frameworks does C# Markup 2 support?

Uno Platform, WinUI 3 through the Windows App SDK, and WPF are supported now. Avalonia, MAUI and possibly Blazor are listed as coming.

How do I try C# Markup 2?

Install the Uno.Templates and Modern.CSharp.Templates template packs, then generate an unoapp project and an mcs-uno-markup2 project with matching presentation and renderer values, such as mvvm and skia.

What does the separated markup namespace do?

The README says it eliminates IntelliSense pollution by keeping the markup API visible while editing the markup file and the UI framework APIs visible while editing the logic file, and it encourages a clean separation of markup and logic.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. VincentH-Net/CSharpForMarkup on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vincenth-net-csharpformarkup.svg)](https://hysenlabs.com/projects/vincenth-net-csharpformarkup)

Was this useful?