/maui-theming
Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding, ResourceDictionary theme switching, DynamicResource bindings, system theme detection, and user theme preferences. Use when: "dark mode", "light mode", "theming", "AppThemeBinding", "theme switching",
Claude Code
$ npx -y skills add dotnet/skills --skill maui-theming --agent claude-code
Codex
$ npx skills add dotnet/skills --skill maui-theming -a codex -y
Cursor
$ npx skills add dotnet/skills --skill maui-theming -a cursor -y
Gemini CLI
$ npx skills add dotnet/skills --skill maui-theming -a gemini-cli -y
GitHub Copilot
$ npx skills add dotnet/skills --skill maui-theming -a github-copilot -y
OpenCode
$ npx skills add dotnet/skills --skill maui-theming -a opencode -y
Windsurf
$ npx skills add dotnet/skills --skill maui-theming -a windsurf -y
SKILL.md
maui-theming.SKILL.mdname: maui-theming
description: >-
Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding,
ResourceDictionary theme switching, DynamicResource bindings, system theme
detection, and user theme preferences.
Use when: "dark mode", "light mode", "theming", "AppThemeBinding",
"theme switching", "ResourceDictionary theme", "dynamic resources",
"system theme detection", "color scheme", "app theme", "DynamicResource".
Do not use for: localization or language switching (see .NET MAUI localization
documentation), accessibility visual adjustments (see .NET MAUI accessibility
documentation), app icons or splash screens (see .NET MAUI app icons
documentation), or Bootstrap-style class theming (see Plugin.Maui.BootstrapTheme
NuGet package).
license: MIT
.NET MAUI Theming
Apply light/dark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.
When to Use
- Adding light and dark mode support to a .NET MAUI app
- Creating custom branded themes with ResourceDictionary
- Detecting and responding to system theme changes at runtime
- Letting users choose a preferred theme (light, dark, or system default)
- Combining OS-driven theme response with custom color palettes
When Not to Use
- Localization or language switching — see [.NET MAUI localization docs](https://learn.microsoft.com/dotnet/maui/fundamentals/localization)
- Accessibility-specific visual adjustments — see [.NET MAUI accessibility docs](https://learn.microsoft.com/dotnet/maui/fundamentals/accessibility)
- App icon or splash screen configuration — see [.NET MAUI app icon docs](https://learn.microsoft.com/dotnet/maui/user-interface/images/app-icons)
- Bootstrap-style class theming — see the `Plugin.Maui.BootstrapTheme` NuGet package
Inputs
- A .NET MAUI project targeting .NET 8 or later
- XAML pages or C# UI code that need theme-aware styling
Workflow
1. Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none). 2. Choose the appropriate strategy: AppThemeBinding for simple light/dark, ResourceDictionary swap for custom/multiple themes, or both combined. 3. Define theme resources — inline `AppThemeBinding` values or separate `ResourceDictionary` files with matching keys. 4. Replace hardcoded colors with `DynamicResource` bindings (or `AppThemeBinding` markup) throughout XAML pages. 5. Add system theme detection via `Application.Current.RequestedTheme` and the `RequestedThemeChanged` event. 6. Implement user preference persistence with `Preferences.Set` / `Preferences.Get` and apply on startup. 7. Verify Android `ConfigChanges.UiMode` is set on `MainActivity` to avoid activity restarts on theme change. 8. Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.
Rules That Change the Answer
Check these rules against the user's scenario, and apply **only** the ones that affect what they asked. `UiMode` and dictionary swapping matter for *runtime theme switching*; they are noise in a question about setting up `AppThemeBinding`.
**Answer narrowly, but completely.** Completeness means showing the code that implements *what you recommended* — not adding adjacent topics. If you recommend `DynamicResource`, show the dictionary swap that makes it update. If the user asks for light/dark colours in C#, show **both** `SetAppThemeColor` (colours) and the generic `SetAppTheme<T>` (any bindable property type), and prefer resource keys over scattered hardcoded colours. Do not tack on platform configuration the question didn't raise.
| Rule | Do this | Not this | Why | |---|---|---|---| | **Runtime-swapped values must be dynamic** | `{DynamicResource Key}` | `{StaticResource Key}` | `StaticResource` resolves once at load and never updates when dictionaries are swapped. | | **Android must declare `UiMode`** *(only for runtime/system theme switching)* | Include `ConfigChanges.UiMode` in the `ConfigurationChanges` list on `MainActivity` | Omitting it | Without it Android restarts the activity on theme change — navigation state is lost and it looks like a crash. Irrelevant to a static `AppThemeBinding` setup | | **Force a theme via `UserAppTheme`** | `Application.Current.UserAppTheme = AppTheme.Dark` | Manually re-assigning colors | `UserAppTheme` overrides the OS; `AppTheme.Unspecified` returns to following the system. |
**Do not** replace a working `AppThemeBinding` setup with ResourceDictionary swapping (or vice versa) unless the user needs what the other approach provides — more than two themes, or a user-selectable theme.
Choosing an Approach
| Approach | Best for | Limitation | |----------|----------|------------| | **AppThemeBinding** | Automatic light/dark with OS — minimal code | Only two themes (light + dark) | | **ResourceDictionary swap** | Custom branded themes, more than two themes, user preference | More setup; must use `DynamicResource` everywhere | | **Both combined** | OS-driven response plus custom theme colors | Most flexible but most complex |
AppThemeBinding (OS Light/Dark)
`AppThemeBinding` selects a value based on the current system theme. It supports `Light`, `Dark`, and an optional `Default` fallback.
Define the palette once — don't scatter literals
Putting `{AppThemeBinding Light=#333333, Dark=#FFFFFF}` on every element is the single most common theming mistake: the palette ends up duplicated across dozens of files and cannot be changed in one place. **Recommend this shape as the final answer**, not inline literals:
<!-- App.xaml — one source of truth for the whole app -->
<Application.Resources>
<ResourceDictionary>
<!-- 1. Raw palette -->
<Color x:Key="LightPageBackground">#FFFFFF</Color>
<Color x:Key="DarkPageBackground">#1E1E1E</Color>
<Color x:Key="LightPrimaryText">#333333</Color>
<Color x:KRead more
name: maui-theming description: >- Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding, ResourceDictionary theme switching, DynamicResource bindings, system theme detection, and user theme preferences. Use when: "dark mode", "light mode", "theming", "AppThemeBinding", "theme switching", "ResourceDictionary theme", "dynamic resources", "system theme detection", "color scheme", "app theme", "DynamicResource". Do not use for: localization or language switching (see .NET MAUI localization documentation), accessibility visual adjustments (see .NET MAUI accessibility documentation), app icons or splash screens (see .NET MAUI app icons documentation), or Bootstrap-style class theming (see Plugin.Maui.BootstrapTheme NuGet package). license: MIT
.NET MAUI Theming
Apply light/dark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.
When to Use
- Adding light and dark mode support to a .NET MAUI app
- Creating custom branded themes with ResourceDictionary
- Detecting and responding to system theme changes at runtime
- Letting users choose a preferred theme (light, dark, or system default)
- Combining OS-driven theme response with custom color palettes
When Not to Use
- Localization or language switching — see [.NET MAUI localization docs](https://learn.microsoft.com/dotnet/maui/fundamentals/localization)
- Accessibility-specific visual adjustments — see [.NET MAUI accessibility docs](https://learn.microsoft.com/dotnet/maui/fundamentals/accessibility)
- App icon or splash screen configuration — see [.NET MAUI app icon docs](https://learn.microsoft.com/dotnet/maui/user-interface/images/app-icons)
- Bootstrap-style class theming — see the `Plugin.Maui.BootstrapTheme` NuGet package
Inputs
- A .NET MAUI project targeting .NET 8 or later
- XAML pages or C# UI code that need theme-aware styling
Workflow
1. Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none). 2. Choose the appropriate strategy: AppThemeBinding for simple light/dark, ResourceDictionary swap for custom/multiple themes, or both combined. 3. Define theme resources — inline `AppThemeBinding` values or separate `ResourceDictionary` files with matching keys. 4. Replace hardcoded colors with `DynamicResource` bindings (or `AppThemeBinding` markup) throughout XAML pages. 5. Add system theme detection via `Application.Current.RequestedTheme` and the `RequestedThemeChanged` event. 6. Implement user preference persistence with `Preferences.Set` / `Preferences.Get` and apply on startup. 7. Verify Android `ConfigChanges.UiMode` is set on `MainActivity` to avoid activity restarts on theme change. 8. Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.
Rules That Change the Answer
Check these rules against the user's scenario, and apply **only** the ones that affect what they asked. `UiMode` and dictionary swapping matter for *runtime theme switching*; they are noise in a question about setting up `AppThemeBinding`.
**Answer narrowly, but completely.** Completeness means showing the code that implements *what you recommended* — not adding adjacent topics. If you recommend `DynamicResource`, show the dictionary swap that makes it update. If the user asks for light/dark colours in C#, show **both** `SetAppThemeColor` (colours) and the generic `SetAppTheme<T>` (any bindable property type), and prefer resource keys over scattered hardcoded colours. Do not tack on platform configuration the question didn't raise.
| Rule | Do this | Not this | Why | |---|---|---|---| | **Runtime-swapped values must be dynamic** | `{DynamicResource Key}` | `{StaticResource Key}` | `StaticResource` resolves once at load and never updates when dictionaries are swapped. | | **Android must declare `UiMode`** *(only for runtime/system theme switching)* | Include `ConfigChanges.UiMode` in the `ConfigurationChanges` list on `MainActivity` | Omitting it | Without it Android restarts the activity on theme change — navigation state is lost and it looks like a crash. Irrelevant to a static `AppThemeBinding` setup | | **Force a theme via `UserAppTheme`** | `Application.Current.UserAppTheme = AppTheme.Dark` | Manually re-assigning colors | `UserAppTheme` overrides the OS; `AppTheme.Unspecified` returns to following the system. |
**Do not** replace a working `AppThemeBinding` setup with ResourceDictionary swapping (or vice versa) unless the user needs what the other approach provides — more than two themes, or a user-selectable theme.
Choosing an Approach
| Approach | Best for | Limitation | |----------|----------|------------| | **AppThemeBinding** | Automatic light/dark with OS — minimal code | Only two themes (light + dark) | | **ResourceDictionary swap** | Custom branded themes, more than two themes, user preference | More setup; must use `DynamicResource` everywhere | | **Both combined** | OS-driven response plus custom theme colors | Most flexible but most complex |
AppThemeBinding (OS Light/Dark)
`AppThemeBinding` selects a value based on the current system theme. It supports `Light`, `Dark`, and an optional `Default` fallback.
Define the palette once — don't scatter literals
Putting `{AppThemeBinding Light=#333333, Dark=#FFFFFF}` on every element is the single most common theming mistake: the palette ends up duplicated across dozens of files and cannot be changed in one place. **Recommend this shape as the final answer**, not inline literals:
<!-- App.xaml — one source of truth for the whole app -->
<Application.Resources>
<ResourceDictionary>
<!-- 1. Raw palette -->
<Color x:Key="LightPageBackground">#FFFFFF</Color>
<Color x:Key="DarkPageBackground">#1E1E1E</Color>
<Color x:Key="LightPrimaryText">#333333</Color>
<Color x:KThis repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Other skills on skills.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about maui-theming.
- Which coding agents can use maui-theming?
- maui-theming installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

