MonacoEditor.WinUI3
0.3.0
See the version list below for details.
dotnet add package MonacoEditor.WinUI3 --version 0.3.0
NuGet\Install-Package MonacoEditor.WinUI3 -Version 0.3.0
<PackageReference Include="MonacoEditor.WinUI3" Version="0.3.0" />
<PackageVersion Include="MonacoEditor.WinUI3" Version="0.3.0" />
<PackageReference Include="MonacoEditor.WinUI3" />
paket add MonacoEditor.WinUI3 --version 0.3.0
#r "nuget: MonacoEditor.WinUI3, 0.3.0"
#:package MonacoEditor.WinUI3@0.3.0
#addin nuget:?package=MonacoEditor.WinUI3&version=0.3.0
#tool nuget:?package=MonacoEditor.WinUI3&version=0.3.0
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
Or via NuGet Package Manager in Visual Studio, search for MonacoEditor.WinUI3.
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. |
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 (pass any Monaco IEditorOptions as JSON)
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
await Editor.SetOptionsAsync("""
{
"fontSize": 16,
"minimap": { "enabled": false },
"lineNumbers": "relative",
"wordWrap": "bounded",
"wordWrapColumn": 100
}
""");
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 |