Maui.Markup: building .NET MAUI interfaces in C# without XAML
The .NET MAUI Markup Community Toolkit is a community-created library that contains Fluent C# Extension Methods to easily create your User Interface in C#
At a glance
- What is it?
- The .NET MAUI Markup Community Toolkit is a set of fluent C# extension methods that let you construct MAUI views in code while keeping MVVM, bindings and resource dictionaries intact. It suits teams that want a single language for their .NET MAUI app, and it comes with a documented path for community features to be promoted into the official library.
- Who is it for?
- Maui.Markup is a good fit for a .NET MAUI team that already writes C# and wants the UI tree, the view model and the bindings in one language, especially where designers are not driving the markup. It is a poor fit for a team that relies on XAML designer tooling, on XAML hot reload, or on shared XAML resources that would have to be rewritten, and it is a poor fit for a project that cannot accept a community package with its own version cadence.
- 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 2 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
A second way to describe a .NET MAUI view tree
The .NET MAUI Markup Community Toolkit is a collection of fluent C# extension methods for building user interfaces in C#. The stated goal is that developers can keep architecting their apps with MVVM, bindings, resource dictionaries and the rest of the MAUI model, without needing XAML.
That framing matters. The toolkit is not a replacement for the MAUI layout system, and it does not change how bindings work. It replaces the file format in which the view is written. A `Label` is still a `Label`, `Bind` still targets a `BindableProperty`, and the compiled bindings and resource dictionaries you already use still apply. What changes is that the declaration is a C# expression instead of a markup document.
The package is published on NuGet as CommunityToolkit.Maui.Markup, the source is C# with a `src/` directory, and the samples live in `samples/CommunityToolkit.Maui.Markup.Sample/`. The documentation is not in the repository. The README points to Microsoft Learn for everything, with the toolkit pages hosted under the .NET community toolkit documentation set. Licence is MIT.
The audience is a .NET MAUI team that wants one language in the project, or a team that has decided the XAML tooling is not earning its keep. It is also a proving ground: the README states that features added to the toolkit may one day be included in the official .NET MAUI library, because the Community Toolkits are used to debut new features and the maintainers work with the MAUI engineering team to nominate features for promotion.
Turning the toolkit on in MauiProgram.cs
There is one required step before any extension method works, and it lives in the app's `MauiProgram.cs`.
using CommunityToolkit.Maui.Markup;
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
// Initialise the toolkit
builder.UseMauiApp<App>().UseMauiCommunityToolkitMarkup();
// the rest of your logic...
}The call is `UseMauiCommunityToolkitMarkup`, chained onto the existing `UseMauiApp<App>()` builder call, and the namespace `CommunityToolkit.Maui.Markup` has to be imported. The README notes the pattern explicitly, that the extension method is called in `MauiProgram.cs`.
This is worth reading as a design decision rather than a formality. The toolkit is not a static helper class that you call into anywhere. It registers itself with the MAUI builder, which is the same mechanism the MAUI controls use to reach application services. That is consistent with a library that intends to be promotable into the official package: it is shaped like an in-box feature rather than like a third party add-on.
The practical advice for a team evaluating it is to make this the first commit of a trial branch. It is one line, it is reversible, and it tells you immediately whether the rest of the tooling, including the build and the analyzer settings in `Directory.Build.props` and `.runsettings`, copes with the package being present.
Bindings and sizing as chained extension methods
The two smallest examples in the README show the style the whole toolkit follows.
new Entry()
.Bind(Entry.TextProperty, static (ViewModel vm) => vm.RegistrationCode);new Entry().Size(200, 40);The `Bind` method takes the bindable property and a lambda that selects the source value, and the `static` modifier on the lambda avoids capturing anything. The `Size` method takes a width and a height. In both cases the point is the same: the object is created, and then a chain of calls configures it, so the declaration reads top to bottom like a sentence about the view.
The README's framing is that markup allows the binding to be defined fluently and therefore chain multiple methods together to reduce the verbosity of the code. That is a fair characterisation of the ergonomics, and it is also the whole value proposition: XAML is a separate declarative language with its own file per view, its own partial class wiring, and its own tooling story, and this removes the second language from the project.
The cost is equally clear. The extension method set is not infinite, so a property without an extension method falls back to an object initialiser, which is exactly the mixture you get in practice, and XAML tooling such as the designer or hot reload does not apply to code. The README also points to separate documentation pages for the `BindableObject` extensions and the `VisualElement` extensions, which is where the full list of available calls lives.
The grid example: naming rows and columns with enums
The in-depth example in the README is the one to read, because it shows how the toolkit handles the part of XAML that people miss most, the grid row and column definitions.
The page builds a `Grid` with named rows and columns, where the names come from enums rather than from magic numbers, and the extension methods then set a child's row and column.
new Entry
{
Keyboard = Keyboard.Numeric,
BackgroundColor = Colors.AliceBlue,
}.Row(Row.TextEntry).Column(Column.Input)
.FontSize(15)
.Placeholder("Enter number")
.TextColor(Colors.Black)
.Height(44)
.Margin(5, 5)
.Bind(Entry.TextProperty, static (ViewModel vm) vm => vm.RegistrationCode)The enums themselves are declared at the bottom of the class.
enum Row { TextEntry }
enum Column { Description, Input }The `Rows.Define` and `Columns.Define` calls build the grid definitions from those enum members, and `Stars(2)` sets a proportional column width. Because the names are compile time constants, a typo in a row name is a compile error, which is a real improvement over the numeric indices XAML tends to accumulate.
Note also the mixture in the snippet. `Keyboard` and `BackgroundColor` are set in an object initialiser, because they are plain properties, while the sizing, margin, placeholder, colour and binding all go through extension methods. The toolkit does not remove the initialiser syntax; it adds a fluent path for the operations that are common enough to be worth a helper.
The contribution path runs through discussion before any code
The feature workflow is documented in more detail than the rest of the README, and it is worth reading as a statement about how this project is governed.
The first step is a discussion. Feature suggestions, design notes and proposals are supposed to be raised as GitHub Discussions before any issue is opened. The README gives specific guidance: discussions that are short and stay on topic are much more likely to be read, a comment thread of fifty entries means only a few people will read it, discussions that are not relevant to the toolkit will be closed, and a comment that could be expressed with an emoji reaction to an existing comment should be.
The second step is a proposal issue. Once a proposal is fully fleshed out and describes the feature in syntactic and semantic detail, it is opened as an issue and labelled as a Proposal, with the issue comment thread used to hash out remaining details.
The third step, a pull request, follows from that. The workflow is summarised in a sketch file in the `build/` directory, and the repository also has a `CONTRIBUTING.md` for the mechanics.
The reason this matters for an adopter is the promotion path. The toolkit exists partly as a staging area for features that the maintainers then nominate for the official .NET MAUI library, which means the review of a new extension method is not only about the code but about whether it belongs in the shared library at all. A contributor should expect a longer path than a normal library issue, and a consumer should expect the API surface to stay conservative.
Version cadence, dependency bumps and what the releases say
The release history is a useful signal about the maintenance state, and it is not perfectly smooth. Version 8.0.0, published on 2026-07-24, is titled with compiled bindings, improved complex nested bindings, and.NET 11 compatibility. Version 7.0.1 on 2026-02-25 is a single-purpose release that increases the `Microsoft.Maui.Controls` dependency, and version 7.0.0 on 2025-11-12 added.NET 10 support.
That middle release is the important one for anyone upgrading. A patch release that exists to raise a dependency on `Microsoft.Maui.Controls` is the toolkit telling you that the MAUI version your app resolves matters, and that you may need to align the two. A MAUI app that is behind on the framework will not necessarily break, but the toolkit's behaviour against a newer control library is the thing to check when something renders differently than expected.
The last push to the repository was on 2026-10-21, and the project is not archived, so work is landing on it. The repository also carries a `global.json`, a `Directory.Build.props`, an `.editorconfig` and a `.runsettings` file, which are the usual pieces of a build that pins its toolchain and enforces style rules across contributors.
The licence is MIT, which is permissive and lets a company adopt the package without the copyleft obligations that a community toolkit with a different licence would impose. The README also notes that the project is under the.NET Foundation banner, with a build workflow badge and the NuGet package listing, which matters for a dependency you would ship inside a commercial application.
The real alternative is XAML, and the trade is tooling against language unity
The genuine alternative to this toolkit is plain XAML in the official MAUI package, and comparing the two is more useful than listing features.
XAML keeps the view definition in a markup language with its own file type, its own visual designer, hot reload during development, and a resource dictionary system for shared styles. The C# markup approach removes the second language and gives you compile time checking of every property name and row identifier, at the cost of the designer and of hot reload, since the view is now compiled code rather than a document a tool can patch live.
The other alternative is to mix the two, which is what a partial adoption looks like. The `SampleContentPage` in the README already shows a mixture of object initialisers and extension methods, and a larger app will have views written in one form and views written in the other, with shared resources still in XAML dictionaries. That is a workable outcome, but it means the toolkit reduces rather than removes the language split.
There is also the question of who can edit the UI. A team with designers or with people who read XAML comfortably may find the fluent API harder to scan than a markup file, particularly for larger trees, because a C# expression with a dozen chained calls is denser than the equivalent markup block. A team of C# developers with no design tooling will find the opposite.
The honest summary is that Maui.Markup is a bet that a MAUI team's binding and layout work is better expressed in the language they already write. That bet has been made by a community toolkit with an active release line and a documented route into the official library, which is a reasonable amount of evidence in its favour.
Editorial conclusion
Maui.Markup is a good fit for a .NET MAUI team that already writes C# and wants the UI tree, the view model and the bindings in one language, especially where designers are not driving the markup. It is a poor fit for a team that relies on XAML designer tooling, on XAML hot reload, or on shared XAML resources that would have to be rewritten, and it is a poor fit for a project that cannot accept a community package with its own version cadence. Verify first that the release you install matches the Microsoft.Maui.Controls version your app targets, since a recent release explicitly raised that dependency, and read the Microsoft Learn pages for the toolkit before you rely on an extension method that has no example in the README.
Frequently asked questions
What is the .NET MAUI Markup Community Toolkit?
It is a collection of fluent C# extension methods that let you build .NET MAUI user interfaces in C# rather than XAML, while keeping MVVM, bindings and resource dictionaries. It is published on NuGet as CommunityToolkit.Maui.Markup and is MIT licensed.
How do I enable Maui.Markup in my MAUI app?
Import the CommunityToolkit.Maui.Markup namespace and call `builder.UseMauiApp<App>().UseMauiCommunityToolkitMarkup()` in your MauiProgram.cs, as the README's getting started snippet shows.
How do I set a binding with C# Markup?
Use the Bind extension method with the bindable property and a lambda, for example `new Entry().Bind(Entry.TextProperty, static (ViewModel vm) => vm.RegistrationCode)`. The README links to the BindableObject extensions documentation for the full set of options.
Can I still use object initialisers and XAML resources with Maui.Markup?
Yes. The README's own grid example sets plain properties such as Keyboard and BackgroundColor in an object initialiser and uses extension methods for sizing, margin, placeholder and binding, and the toolkit's stated goal is to keep resource dictionaries and MVVM intact.
How do I propose a new feature to the Maui.Markup project?
The workflow starts with a GitHub Discussion, where the feature is discussed and design notes are exchanged, and only once a proposal is fleshed out in syntactic and semantic detail is an issue opened and labelled as a Proposal, with implementation following in a pull request.
What is the latest release of Maui.Markup and what does it change?
Version 8.0.0, published on 2026-07-24, brings compiled bindings, improved complex nested bindings and .NET 11 compatibility. The preceding 7.0.1 release, dated 2026-02-25, exists to increase the Microsoft.Maui.Controls dependency.
Official sources
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.
[](https://hysenlabs.com/projects/communitytoolkit-maui-markup)Was this useful?