Shell | Getting Started
Make .NET MAUI Shell shinier with viewmodel lifecycle management, navigation, and source generation to remove boilerplate, reduce errors, and make your app testable.
Inspired by Prism Library by Dan Siegel and Brian Lagunas.
Frameworks
.NET MAUI
Features
Section titled “Features”- Navigation service — route-based and ViewModel-based navigation with
INavigator - Shell switching — swap the entire Shell at runtime with
SwitchShell(instance or DI-resolved) - Dialog service — alert, confirm, prompt, and action sheet dialogs with
IDialogs - Navigation events —
NavigatingandNavigatedevents with source/destination ViewModel instances - ViewModel lifecycle — appearing/disappearing, navigation confirmation, navigation awareness, and disposal
- Auto BindingContext — ViewModels automatically attached to page binding contexts
- Source generation — eliminates route registration boilerplate, generates strongly-typed navigation extensions and DI registration
- ShinyShell base class — one base class change for deterministic BindingContext assignment on the initial page
- Testable —
INavigatorandIDialogsare injectable and mockable for unit testing
-
Install the NuGet package
Terminal window dotnet add package Shiny.Maui.Shell -
Configure
UseShinyShellin yourMauiProgram.cspublic static class MauiProgram{public static MauiApp CreateMauiApp(){var builder = MauiApp.CreateBuilder();builder.UseMauiApp<App>().UseShinyShell(x => x.Add<MainPage, MainViewModel>(registerRoute: false).Add<AnotherPage, AnotherViewModel>("another")).ConfigureFonts(fonts =>{fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");});return builder.Build();}} -
Update your
AppShellto inherit fromShinyShellAppShell.xaml:
<shiny:ShinyShellx:Class="MyApp.AppShell"xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:shiny="clr-namespace:Shiny;assembly=Shiny.Maui.Shell"xmlns:local="clr-namespace:MyApp"Title="MyApp"><ShellContentTitle="Home"ContentTemplate="{DataTemplate local:MainPage}"Route="MainPage" /></shiny:ShinyShell>AppShell.xaml.cs:
using Shiny;namespace MyApp;public partial class AppShell : ShinyShell{public AppShell(){InitializeComponent();}} -
Inject
INavigatorinto your ViewModels and navigateusing Shiny;public class MainViewModel(INavigator navigator){public async Task GoToDetails(){await navigator.NavigateTo("another");}}
Quick Example
Section titled “Quick Example”// Navigate by route with argumentsawait navigator.NavigateTo("details", ("Id", 42));
// Navigate by ViewModel with strongly typed setupawait navigator.NavigateTo<DetailViewModel>(vm => vm.Id = 42);
// Go back with argumentsawait navigator.GoBack(("Result", "saved"));
// Switch to a different Shell at runtimeawait navigator.SwitchShell<AdminShell>();AI Coding Assistant
Section titled “AI Coding Assistant”claude plugin add github:shinyorg/skills/shiny-maui-shell - Open the shiny-maui-shell skill file and copy its contents
- In your repository, create
.github/copilot-instructions.mdif it doesn't exist - Paste the skill content into that file and save
Copilot will automatically pick up the instructions on your next chat or code completion. You can also use path-specific instructions by placing the file in .github/instructions/ with an applyTo frontmatter pattern.
Next Steps
Section titled “Next Steps”- Navigation — Full
INavigatorAPI reference - Dialogs — Alert, confirm, prompt, and action sheet dialogs
- ViewModel Lifecycle — Lifecycle interfaces and events
- Source Generation — Eliminate boilerplate with attributes