Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit.

MITAuto-check passedDevelopment

Install Mvvm

skills CLI
$ npx skills add managedcode/dotnet-skills --skill mvvm -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install managedcode/dotnet-skills mvvm --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/managedcode/dotnet-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/catalog/Libraries/MVVM-Toolkit/skills/mvvm .claude/skills/mvvm && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
mvvm
GitHub stars
486
Token cost
~2.7k tokens
SKILL.md length
321 words
Files
4 (incl. references)
Skills in repo
81
Repo updated
First seen
Licence
MIT

At a glance

Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit.

  • Works in 5 steps: Keep Views dumb — no business logic in… → Use data binding — connect View to… → Commands for actions — handle user… → …
  • : implementing UI separation with Model-View-ViewModel
  • SKILL.md covers Trigger On, Documentation, References and Core Concepts, plus 13 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Mvvm is an agent skill from managedcode/dotnet-skills. Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit. USE FOR: implementing UI separation with Model-View-ViewModel; using MVVM Toolkit (CommunityToolkit.Mvvm) for ViewModels; designing testable UI architecture. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or…

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `manifest.json`, `references/anti-patterns.md` and `references/patterns.md`). Compatibility notes: Applies to WPF, MAUI, WinUI, Uno Platform, Avalonia, and Blazor projects.

It sits in Development, covering Codebase knowledge for agents. It works with .NET. The repository describes itself as: Installable .NET skill catalog and CLI for Codex, Claude Code, GitHub Copilot, and Gemini. The licence is MIT.

When your agent uses it

  • : implementing UI separation with Model-View-ViewModel
  • Using MVVM Toolkit (CommunityToolkit.Mvvm) for ViewModels
  • Designing testable UI architecture
  • : unrelated stacks

Example prompts

  • “/mvvm”

Requirements

  • Compatibility (from SKILL.md): Applies to WPF, MAUI, WinUI, Uno Platform, Avalonia, and Blazor projects.

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Keep Views dumb — no business logic in code-behind
  2. Use data binding — connect View to ViewModel properties
  3. Commands for actions — handle user interactions via ICommand
  4. Inject dependencies — services go into ViewModel constructors
  5. Test ViewModels — they should be unit testable without UI

What it can do on your machine

Read from SKILL.md and the folder at commit 535dd55. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp and xml).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • learn.microsoft.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Applies to WPF, MAUI, WinUI, Uno Platform, Avalonia, and Blazor projects.

    From compatibility in the SKILL.md frontmatter.

Context cost

Mvvm loads about 2.7k tokens when it runs, and up to ~6.1k if it reads all its reference files. Until then it costs about 141 tokens; SKILL.md has 321 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~141
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~6.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from managedcode/dotnet-skills at commit 535dd55, republished under its MIT licence (© managedcode). 321 words, ~2,738 tokens.

Download SKILL.mdSave it as .claude/skills/mvvm/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
mvvm
description
Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit. USE FOR: implementing UI separation with Model-View-ViewModel; using MVVM Toolkit (CommunityToolkit.Mvvm) for ViewModels; designing testable UI architecture. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.
compatibility
Applies to WPF, MAUI, WinUI, Uno Platform, Avalonia, and Blazor projects.

MVVM Pattern for .NET

Trigger On

  • implementing UI separation with Model-View-ViewModel
  • using MVVM Toolkit (CommunityToolkit.Mvvm) for ViewModels
  • designing testable UI architecture
  • handling commands, property changes, and messaging
  • choosing between MVVM frameworks

Documentation

References

See detailed examples in the references/ folder:

Core Concepts

ComponentResponsibilityExample
ModelBusiness logic and dataProduct, Order, User
ViewUI presentation (XAML/Razor)ProductPage.xaml
ViewModelUI logic and stateProductViewModel

Workflow

  1. Keep Views dumb — no business logic in code-behind
  2. Use data binding — connect View to ViewModel properties
  3. Commands for actions — handle user interactions via ICommand
  4. Inject dependencies — services go into ViewModel constructors
  5. Test ViewModels — they should be unit testable without UI

MVVM Toolkit Setup

xml
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.*" />

ViewModel Patterns

Basic ViewModel with Source Generators
csharp
public partial class ProductViewModel(IProductService productService) : ObservableObject
{
    [ObservableProperty]
    private string _name = string.Empty;

    [ObservableProperty]
    private decimal _price;

    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
    private bool _isValid;

    [RelayCommand(CanExecute = nameof(CanSave))]
    private async Task SaveAsync()
    {
        await productService.SaveAsync(new Product { Name = Name, Price = Price });
    }

    private bool CanSave() => IsValid && !string.IsNullOrEmpty(Name);
}
Property Changed Notifications
csharp
public partial class OrderViewModel : ObservableObject
{
    [ObservableProperty]
    private int _quantity;

    [ObservableProperty]
    private decimal _unitPrice;

    // Computed property - manually notify
    public decimal Total => Quantity * UnitPrice;

    partial void OnQuantityChanged(int value)
    {
        OnPropertyChanged(nameof(Total));
    }

    partial void OnUnitPriceChanged(decimal value)
    {
        OnPropertyChanged(nameof(Total));
    }
}
Collection ViewModel
csharp
public partial class ProductListViewModel(IProductService productService) : ObservableObject
{
    [ObservableProperty]
    private ObservableCollection<ProductViewModel> _products = [];

    [ObservableProperty]
    private ProductViewModel? _selectedProduct;

    [ObservableProperty]
    private bool _isLoading;

    [RelayCommand]
    private async Task LoadProductsAsync()
    {
        IsLoading = true;
        try
        {
            var items = await productService.GetAllAsync();
            Products = new ObservableCollection<ProductViewModel>(
                items.Select(p => new ProductViewModel(productService)
                {
                    Name = p.Name,
                    Price = p.Price
                }));
        }
        finally
        {
            IsLoading = false;
        }
    }

    [RelayCommand]
    private void DeleteProduct(ProductViewModel product)
    {
        Products.Remove(product);
    }
}

Commands

Async Commands with Cancellation
csharp
public partial class SearchViewModel : ObservableObject
{
    [ObservableProperty]
    private string _searchText = string.Empty;

    [RelayCommand(IncludeCancelCommand = true)]
    private async Task SearchAsync(CancellationToken token)
    {
        await Task.Delay(500, token); // Debounce
        // Search logic with cancellation support
    }
}
Command with Parameter
csharp
public partial class NavigationViewModel : ObservableObject
{
    [RelayCommand]
    private void NavigateTo(string page)
    {
        // Navigate to page
    }

    [RelayCommand]
    private async Task OpenItemAsync(int itemId)
    {
        // Load and open item
    }
}

Messenger Pattern

Sending Messages
csharp
// Define message
public record ProductSelectedMessage(Product Product);

// Send from one ViewModel
WeakReferenceMessenger.Default.Send(new ProductSelectedMessage(selectedProduct));
Receiving Messages
csharp
public partial class ProductDetailViewModel : ObservableRecipient
{
    public ProductDetailViewModel()
    {
        IsActive = true; // Enable message reception
    }

    protected override void OnActivated()
    {
        Messenger.Register<ProductDetailViewModel, ProductSelectedMessage>(
            this, (r, m) => r.LoadProduct(m.Product));
    }

    private void LoadProduct(Product product)
    {
        // Update UI with product details
    }
}

Validation

Using ObservableValidator
csharp
public partial class RegistrationViewModel : ObservableValidator
{
    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "Email is required")]
    [EmailAddress(ErrorMessage = "Invalid email format")]
    private string _email = string.Empty;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required]
    [MinLength(8, ErrorMessage = "Password must be at least 8 characters")]
    private string _password = string.Empty;

    [RelayCommand(CanExecute = nameof(CanRegister))]
    private async Task RegisterAsync()
    {
        ValidateAllProperties();
        if (HasErrors) return;

        // Registration logic
    }

    private bool CanRegister() => !HasErrors;
}

Dependency Injection

Registration
csharp
// Services
services.AddSingleton<IProductService, ProductService>();
services.AddSingleton<INavigationService, NavigationService>();

// ViewModels
services.AddTransient<ProductListViewModel>();
services.AddTransient<ProductDetailViewModel>();

// Views (for View-first navigation)
services.AddTransient<ProductListPage>();
services.AddTransient<ProductDetailPage>();
ViewModel Locator Pattern
csharp
public class ViewModelLocator
{
    private static IServiceProvider _provider = null!;

    public static void Initialize(IServiceProvider provider) => _provider = provider;

    public ProductListViewModel ProductList => _provider.GetRequiredService<ProductListViewModel>();
    public ProductDetailViewModel ProductDetail => _provider.GetRequiredService<ProductDetailViewModel>();
}

View Binding

XAML Binding
xml
<Page x:Class="MyApp.Views.ProductListPage"
      xmlns:vm="using:MyApp.ViewModels"
      x:DataType="vm:ProductListViewModel">

    <Grid>
        <ProgressRing IsActive="{x:Bind ViewModel.IsLoading, Mode=OneWay}"
                      Visibility="{x:Bind ViewModel.IsLoading, Mode=OneWay}" />

        <ListView ItemsSource="{x:Bind ViewModel.Products, Mode=OneWay}"
                  SelectedItem="{x:Bind ViewModel.SelectedProduct, Mode=TwoWay}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="vm:ProductViewModel">
                    <StackPanel>
                        <TextBlock Text="{x:Bind Name, Mode=OneWay}" />
                        <TextBlock Text="{x:Bind Price, Mode=OneWay}" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button Content="Load"
                Command="{x:Bind ViewModel.LoadProductsCommand}" />
    </Grid>
</Page>

Anti-Patterns to Avoid

Anti-PatternWhy It's BadBetter Approach
Logic in code-behindNot testableMove to ViewModel
ViewModel knows ViewTight couplingUse interfaces/messaging
Manual INotifyPropertyChangedVerbose, error-proneUse source generators
God ViewModelUnmaintainableSplit responsibilities
Direct service calls in ViewViolates separationGo through ViewModel
Exposing Model directlyLeaks implementationCreate ViewModel properties

Testing ViewModels

csharp
public class ProductViewModelTests
{
    [Fact]
    public async Task LoadProducts_PopulatesCollection()
    {
        // Arrange
        var mockService = new Mock<IProductService>();
        mockService.Setup(s => s.GetAllAsync())
            .ReturnsAsync([new Product { Name = "Test", Price = 10 }]);

        var viewModel = new ProductListViewModel(mockService.Object);

        // Act
        await viewModel.LoadProductsCommand.ExecuteAsync(null);

        // Assert
        Assert.Single(viewModel.Products);
        Assert.Equal("Test", viewModel.Products[0].Name);
    }

    [Fact]
    public void SaveCommand_CannotExecute_WhenInvalid()
    {
        var viewModel = new ProductViewModel(Mock.Of<IProductService>())
        {
            Name = "",
            IsValid = false
        };

        Assert.False(viewModel.SaveCommand.CanExecute(null));
    }
}

Framework Comparison

FeatureMVVM ToolkitPrismMVVMLight
Source generatorsYesNoNo
MaintenanceActiveActiveDeprecated
DI built-inNoYesNo
NavigationNoYesNo
WeightLightHeavyLight

Deliver

  • ViewModels that are fully unit testable
  • Clean separation between UI and business logic
  • Proper use of commands and data binding
  • Messaging for loose coupling between components

Validate

  • No business logic in code-behind files
  • ViewModels don't reference View types
  • Commands are used for all user actions
  • Properties use ObservableProperty or equivalent
  • Dependencies are injected, not created
  • Unit tests cover ViewModel logic

© managedcode, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in catalog/Libraries/MVVM-Toolkit/skills/mvvm of managedcode/dotnet-skills.

  • SKILL.md
  • manifest.json
  • references/anti-patterns.md
  • references/patterns.md

Open the folder on GitHubat commit 535dd55

Compare with similar skills

Mvvm next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Mvvm compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Mvvm this skillmanagedcode/dotnet-skills486—~2.7kAutomated safety check: PassMIT
Repomix Codebase Exploreryamadashy/repomix29k1 repos~2.7kAutomated safety check: PassMIT
Codebase Contexthomarr-labs/homarr5k—~659Automated safety check: PassApache-2.0
tilth Code Reading CLIjahala/tilth352—~1.1kAutomated safety check: PassMIT
Brownfield Repo ScannerQ00/ouroboros6.2k—~2.2kAutomated safety check: PassMIT
Roslynkmrpmorris/Roslynk122—~3kAutomated safety check: PassMIT

Similar skills

  • Repomix Codebase Explorer

    yamadashy/repomix

    Packs a local or remote repository into a single AI-friendly file with the Repomix CLI, then reads and searches that output to explain structure, find patterns or report metrics.

    29k GitHub starsUsed in 1 repo~2.7k tokens
    DevelopmentAuto-check passed
  • Codebase Context

    homarr-labs/homarr

    Navigate Homarr's monorepo architecture and reuse shared packages.

    5k GitHub stars~659 tokensUpdated today
    DevelopmentAuto-check passed
  • Replaces grep, cat, find and ls with the tilth CLI, which returns AST-aware outlines, definitions, usages and callers across many languages in one call.

    352 GitHub stars~1.1k tokensUpdated 10 days ago
    DevelopmentAuto-check passed
  • Scans a directory for existing git repositories and worktrees, then registers and manages which ones serve as default context during interviews.

    6.2k GitHub stars~2.2k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Roslynk

    mrpmorris/Roslynk

    How to use the Roslynk MCP tools (mcproslynk) effectively for .NET work.

    122 GitHub stars~3k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • trace-mcp Code Navigation

    nikolai-vysotskyi/trace-mcp

    Routes code exploration through trace-mcp's indexed dependency graph, using symbol search, outlines, call graphs and change-impact tools instead of Read, Grep and Glob.

    185 GitHub stars~1.6k tokensUpdated yesterday
    DevelopmentAuto-check: notes

More from managedcode/dotnet-skills

All 81 skills in this repo
  • Analyzer Config

    managedcode/dotnet-skills

    Use a repo-root .editorconfig to configure free .NET analyzer and style rules.

    486 GitHub stars~1.3k tokensUpdated today
    Auto-check passed
  • Archunitnet

    managedcode/dotnet-skills

    Use the open-source free ArchUnitNET library for architecture rules in .NET tests.

    486 GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Aspire

    managedcode/dotnet-skills

    Build, upgrade, and operate Aspire 13.5.x C or TypeScript application hosts with the current CLI, AppHost, ServiceDefaults, integrations, dashboard, testing, MCP, and deployment patterns for…

    486 GitHub stars~3.6k tokensUpdated today
    Auto-check passed
  • Aspnet Core

    managedcode/dotnet-skills

    Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging, and deployment patterns on current .NET.

    486 GitHub stars~2.1k tokensUpdated today
    Auto-check passed
  • Asynkron Profiler

    managedcode/dotnet-skills

    Use the open-source free Asynkron.Profiler dotnet tool for CLI-first CPU, allocation, exception, contention, and heap profiling of .NET commands or existing trace artifacts.

    486 GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • Azure Functions

    managedcode/dotnet-skills

    Build, review, or migrate Azure Functions in .NET with correct execution model, isolated worker setup, bindings, DI, and Durable Functions patterns.

    486 GitHub stars~2.6k tokensUpdated today
    Auto-check passed

Works with

Questions about Mvvm

What does Mvvm do?

Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit. Mvvm is an agent skill from managedcode/dotnet-skills.NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit.

When should I use Mvvm?

Mvvm fits situations like: : implementing UI separation with Model-View-ViewModel; using MVVM Toolkit (CommunityToolkit.Mvvm) for ViewModels; designing testable UI architecture; : unrelated stacks.

How do I install Mvvm in Claude Code?

Run `npx skills add managedcode/dotnet-skills --skill mvvm -a claude-code`. Or copy the skill folder (catalog/Libraries/MVVM-Toolkit/skills/mvvm in managedcode/dotnet-skills) into .claude/skills/mvvm in your project. Claude Code loads it when a task matches its description.

How do I install Mvvm in Codex?

Run `npx skills add managedcode/dotnet-skills --skill mvvm -a codex`. Or copy the skill folder (catalog/Libraries/MVVM-Toolkit/skills/mvvm in managedcode/dotnet-skills) into .agents/skills/mvvm in your project. Codex loads it when a task matches its description.

Can I use Mvvm in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add managedcode/dotnet-skills --skill mvvm -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mvvm, .gemini/skills/mvvm, .github/skills/mvvm and .opencode/skills/mvvm in your project.

What does Mvvm need to run?

SKILL.md names no scripts, command-line tools or credentials: Mvvm is instructions for the agent only. Compatibility (from SKILL.md): Applies to WPF, MAUI, WinUI, Uno Platform, Avalonia, and Blazor projects..

Does Mvvm access the network?

SKILL.md names 1 domain. As links in the text: learn.microsoft.com. This is read from the text; nothing was executed.

Is Mvvm safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Mvvm use?

Mvvm is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Mvvm use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.4k tokens, read only when the agent opens those files.

What are the alternatives to Mvvm?

Skills that share tags, products or a category with Mvvm: Repomix Codebase Explorer (yamadashy/repomix, 29k stars), Codebase Context (homarr-labs/homarr, 5k stars), tilth Code Reading CLI (jahala/tilth, 352 stars) and Brownfield Repo Scanner (Q00/ouroboros, 6.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Mvvm?

managedcode (a GitHub organization) maintains it in managedcode/dotnet-skills, which has 486 GitHub stars. The repository holds 81 skills in this directory. The repository was last updated on October 7, 2026.

Source: managedcode/dotnet-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.