MonacoEditor.WinUI3
0.5.0-monaco.0.55.1
dotnet add package MonacoEditor.WinUI3 --version 0.5.0-monaco.0.55.1
NuGet\Install-Package MonacoEditor.WinUI3 -Version 0.5.0-monaco.0.55.1
<PackageReference Include="MonacoEditor.WinUI3" Version="0.5.0-monaco.0.55.1" />
<PackageVersion Include="MonacoEditor.WinUI3" Version="0.5.0-monaco.0.55.1" />
<PackageReference Include="MonacoEditor.WinUI3" />
paket add MonacoEditor.WinUI3 --version 0.5.0-monaco.0.55.1
#r "nuget: MonacoEditor.WinUI3, 0.5.0-monaco.0.55.1"
#:package MonacoEditor.WinUI3@0.5.0-monaco.0.55.1
#addin nuget:?package=MonacoEditor.WinUI3&version=0.5.0-monaco.0.55.1&prerelease
#tool nuget:?package=MonacoEditor.WinUI3&version=0.5.0-monaco.0.55.1&prerelease
MonacoEditor.WinUI3
A NuGet package that wraps the Monaco Editor (the code editor that powers VS Code) as a WinUI 3 control using WebView2. Drop it into any WinUI 3 app and get a full-featured code editor with two-way data binding, IntelliSense, syntax highlighting for 70+ languages, and theming.
Features
- Two-way
Textbinding: bind the editor content to your ViewModel with{x:Bind Text, Mode=TwoWay} - Rich async API:
GetTextAsync,InsertTextAtCursorAsync,GetSelectedTextAsync,SetCursorPositionAsync,TriggerActionAsync, and more - Events:
EditorReady,TextChanged - Automatic layout: the editor resizes with its container
- Bundled by default: Monaco files are included in the package; no internet connection required. CDN loading is available as an opt-in.
Quick Start
1. Install
dotnet add package MonacoEditor.WinUI3 --prerelease
Or via NuGet Package Manager in Visual Studio, search for MonacoEditor.WinUI3.
--prerelease is required when installing this package. The Monaco Editor version is encoded in the prerelease tag of the package version. When using NuGet, make sure to enable Include Prerelease to see and install this package.
2. Add the namespace
To your Window or Page XAML open tag, add xmlns:monaco="using:MonacoEditor.WinUI3":
<Window
xmlns:monaco="using:MonacoEditor.WinUI3"
...>
3. Use the control
<monaco:MonacoEditorControl
Text="{x:Bind MyCode, Mode=TwoWay}"
EditorLanguage="csharp"
EditorTheme="vs-dark" />
That's it. The editor loads Monaco from bundled local files.
Full Example (MVVM)
<Page xmlns:monaco="using:MonacoEditor.WinUI3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<monaco:MonacoEditorControl
Text="{x:Bind ViewModel.SourceCode, Mode=TwoWay}"
EditorLanguage="{x:Bind ViewModel.Language, Mode=OneWay}"
EditorTheme="{x:Bind ViewModel.Theme, Mode=OneWay}"
IsReadOnly="{x:Bind ViewModel.IsReadOnly, Mode=OneWay}"
EditorReady="OnEditorReady"
TextChanged="OnTextChanged" />
<TextBlock Grid.Row="1"
Text="{x:Bind ViewModel.StatusMessage, Mode=OneWay}"
Padding="12,6" />
</Grid>
</Page>
public partial class EditorViewModel : ObservableObject
{
[ObservableProperty]
public partial string SourceCode { get; set; } = "// Hello, Monaco!";
[ObservableProperty]
public partial string Language { get; set; } = "javascript";
[ObservableProperty]
public partial string Theme { get; set; } = "vs-dark";
[ObservableProperty]
public partial bool IsReadOnly { get; set; } = false;
[ObservableProperty]
public partial string StatusMessage { get; set; } = "";
}
API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
Text |
string |
"" |
Full editor content. Supports two-way binding. |
EditorLanguage |
string |
"plaintext" |
Language mode for syntax highlighting. |
EditorTheme |
string |
"vs" |
Visual theme: vs, vs-dark, hc-black, hc-light. |
IsReadOnly |
bool |
false |
Toggle read-only mode. |
Options |
MonacoEditorOptions? |
null |
Typed editor options object. Changes to any property are automatically pushed to the editor. |
MonacoBaseUrl |
string? |
null |
Override the Monaco source URL. Set to a CDN URL to load remotely instead of using bundled files. |
Events
| Event | Args | Description |
|---|---|---|
EditorReady |
EventArgs |
Fired once when the editor is fully loaded and interactive. |
TextChanged |
MonacoTextChangedEventArgs |
Fired on each user-initiated content change. e.Text contains the full text. |
Async Methods
// Get/set text
Task<string> GetTextAsync()
// Editor options — typed overload or raw JSON
Task SetOptionsAsync(MonacoEditorOptions options)
Task SetOptionsAsync(string optionsJson)
// Cursor & selection
Task<(int Line, int Column)> GetCursorPositionAsync()
Task SetCursorPositionAsync(int lineNumber, int column)
Task<string> GetSelectedTextAsync()
Task InsertTextAtCursorAsync(string text)
// Focus & actions
Task FocusEditorAsync()
Task TriggerActionAsync(string actionId)
Example: Trigger Format Document
await Editor.TriggerActionAsync("editor.action.formatDocument");
Example: Custom Editor Options (raw JSON)
await Editor.SetOptionsAsync("""
{
"fontSize": 16,
"minimap": { "enabled": false },
"lineNumbers": "relative",
"wordWrap": "bounded",
"wordWrapColumn": 100
}
""");
Typed Editor Options
For a type-safe, IntelliSense-friendly alternative to raw JSON, use MonacoEditorOptions:
Editor.Options = new MonacoEditorOptions
{
FontSize = 16,
FontFamily = "Cascadia Code",
WordWrap = WordWrap.On,
Minimap = new MinimapOptions { Enabled = false, Side = MinimapSide.Left },
Scrollbar = new ScrollbarOptions { Vertical = ScrollbarVisibility.Hidden },
};
Or via the async method overload:
await Editor.SetOptionsAsync(new MonacoEditorOptions
{
LineNumbers = LineNumbers.Relative,
FontLigatures = true,
Suggest = new SuggestOptions { ShowSnippets = false },
});
XAML data binding
MonacoEditorOptions implements INotifyPropertyChanged, so you can bind it from XAML and mutate individual properties reactively:
<monaco:MonacoEditorControl
Options="{x:Bind ViewModel.EditorOptions, Mode=OneWay}" />
// Any property change is automatically pushed to the editor
ViewModel.EditorOptions.FontSize = 18;
ViewModel.EditorOptions.Minimap.Enabled = false;
String-union option types (e.g. WordWrap, CursorStyle, MinimapSide) have companion static classes with named constants so you never have to guess string values.
How It Works
┌─────────────────────────────────────┐
│ WinUI 3 Application │
│ │
│ ┌─────────────────────────────┐ │
│ │ MonacoEditorControl │ │
│ │ (TemplatedControl) │ │
│ │ │ │
│ │ DP: Text ←──TwoWay──→ VM │ │
│ │ DP: Language, Theme, ... │ │
│ │ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ WebView2 │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────────┐ │ │ │
│ │ │ │ Monaco Editor │ │ │ │
│ │ │ │ (index.html) │ │ │ │
│ │ │ └───────────────┘ │ │ │
│ │ └─────────────────────┘ │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
C# → JS: ExecuteScriptAsync("setText(...)")
JS → C#: chrome.webview.postMessage({ type, text })
- C# to JavaScript: The control calls
ExecuteScriptAsyncto invoke functions defined in the hosted HTML page (setText,setLanguage,setTheme, etc.) - JavaScript to C#: Monaco's
onDidChangeModelContentevent triggerspostMessageback to the C#WebMessageReceivedhandler, which updates theTextdependency property - Echo suppression: A flag prevents infinite update loops when the binding updates flow in both directions
Loading Modes
Bundled (default, zero config)
Monaco is bundled with the NuGet package and loaded from local files. No internet connection is needed, which is ideal for desktop and store-distributed apps.
CDN / Self-hosted
To load Monaco from a CDN or self-hosted URL instead of the bundled files, set MonacoBaseUrl explicitly:
<monaco:MonacoEditorControl
MonacoBaseUrl="https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min"
... />
This requires an internet connection at runtime.
Requirements
- .NET 8 or .NET 9 (multi-targeted)
- Windows App SDK 1.8+ (WinUI 3)
- WebView2 Runtime (ships with Windows 11; auto-installs with Edge on Windows 10)
- Windows 10 version 1809 (build 17763) or later
License
This project is MIT licensed, see LICENSE.
Monaco Editor itself is licensed under the MIT License by Microsoft.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows10.0.19041 is compatible. net9.0-windows was computed. net9.0-windows10.0.19041 is compatible. net10.0-windows was computed. |
-
net8.0-windows10.0.19041
- Microsoft.Web.WebView2 (>= 1.0.3179.45)
- Microsoft.Windows.SDK.BuildTools (>= 10.0.26100.7705)
- Microsoft.WindowsAppSDK (>= 1.8.260317003)
-
net9.0-windows10.0.19041
- Microsoft.Web.WebView2 (>= 1.0.3179.45)
- Microsoft.Windows.SDK.BuildTools (>= 10.0.26100.7705)
- Microsoft.WindowsAppSDK (>= 1.8.260317003)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.5.0-monaco.0.55.1 | 85 | 4/10/2026 |
| 0.4.1-monaco.0.55.1 | 53 | 4/9/2026 |
| 0.4.0 | 43 | 4/9/2026 |
| 0.3.0 | 111 | 4/9/2026 |
| 0.2.1 | 107 | 4/8/2026 |