Design, build, and run .NET desktop apps β without ever leaving VS Code.
UI Maker is an open-source Visual Studio Code extension that brings a drag-and-drop form designer, one-click build/run/debug/release buttons, and project scaffolding for .NET desktop applications (WPF and Windows Forms, C# and Visual Basic) directly into the editor. No more switching to full Visual Studio just to lay out a window.
| Visual designer | Side panel |
|---|---|
![]() |
![]() |
The .NET CLI (dotnet) can create, build, and run desktop apps entirely from VS Code,
but there has never been a good visual way to design the UI here. Editing
MainWindow.xaml by hand is fine for experts β and a wall for everyone else.
UI Maker closes that gap:
| Pain point | UI Maker answer |
|---|---|
| Hand-writing XAML layout | Drag-and-drop visual designer with snap-to-grid canvas |
| Guessing property names | A real Properties window β categorized like Visual Studio's, with dropdowns, color pickers, Anchor toggles, and a description pane |
| Adding images and icons | Pick a file β it's imported into Resources/, registered in Resources.resx, and referenced from the Designer.cs β exactly like VS |
| Wiring events by hand | Events panel β one click writes the handler stub into the code-behind |
| Switching between design and markup | Split view: designer on one side, live XAML source on the other |
| CLI-only build workflow | Build / Run / Debug / Release buttons in the status bar and editor title |
| Starting a new app | "New .NET Desktop Project" scaffolds WPF, WinForms, or Console apps (C# or VB) via dotnet new |
| "Works on my machine" builds | Detects missing .NET Framework reference assemblies (MSB3644) and offers the fix; classic projects build through Visual Studio's MSBuild automatically |
Click the UI Maker icon in the activity bar (the window-with-controls glyph on the far left) to open the side panel:
- Actions β New Project, Build, Run, Debug, Release, App Settings, Open Working Folder, and the built-in Guide, one click away. Run and Debug are toggles: a green play button while idle that becomes a red stop button while your app is running. The first row shows the Working Folder β the one project that Run/Build/Debug/Release/App Settings and every file list target. It follows the file you are editing and is per-project (like SFTP configs), so opening a parent folder full of projects never lets one project's action touch another. Click the row to switch projects.
- Recent Projects β every .NET project you open or create, tagged with its
type (
WinForms Β· .NET 8,WPF Β· .NET Framework 4.7.2, β¦); click to switch. Hover a project for one-click Open in New Window, Open Folder in File Explorer, and Remove. - XAML Windows and WinForms Forms β every designable file in the
working project, C# (
*.Designer.cs) and Visual Basic (*.Designer.vb) alike; click one to open it straight in the visual designer. Use the + button on a group to add a new window/form, or a row's Duplicate action to copy an existing one (new class name, registered in the project, opened in the designer). The lists update automatically as files change. When the opened folder contains several projects, nothing is listed wholesale β the panel asks you to choose a working folder first, and build output / caches (bin,obj,packages,.vs,node_modules) are never scanned. Files with no visual surface (App.xaml, resource dictionaries, Designer.cs files withoutInitializeComponent) skip the designer and open straight in the code editor. - Project Files β everything else in the workspace, sorted into
solution-explorer-style categories: Code, Images & Icons,
Resources, Data & Config, Project & Solution, and Other,
with real file icons and click-to-open. The categories have inline οΌ
buttons: New Class File (a
.csor.vbstub matching the working project's language, registered in the project), Add Image, and Add Resource β files are imported intoResources/, registered inProperties/Resources.resxwith the right CLR type (Bitmap, Icon, String, or byte[]), and exposed through a regeneratedResources.Designer.cs, soProperties.Resources.namejust works.
Open any .xaml window in the UI Maker Designer:
- Toolbox with a search box and Visual Studio's sections. WPF: Button, Label, TextBox, TextBlock, CheckBox, RadioButton, ComboBox, ListBox, DataGrid, Image, ProgressBar, Slider, Border, GroupBox, DatePicker, and more. WinForms mirrors the VS toolbox: Common Controls (Button, Label, LinkLabel, TextBox, MaskedTextBox, RichTextBox, CheckBox, RadioButton, CheckedListBox, ComboBox, DomainUpDown, ListBox, ListView, TreeView, PictureBox, ProgressBar, TrackBar, NumericUpDown, DateTimePicker, MonthCalendar, HScrollBar, VScrollBar, WebBrowser, PropertyGrid), Containers (GroupBox, Panel, FlowLayoutPanel, TableLayoutPanel, SplitContainer, Splitter, TabControl), Menus & Toolbars, Data (DataGridView, BindingSource), Components, Dialogs, and Printing (PrintDialog, PrintDocument, PrintPreviewDialog, PageSetupDialog). Drag a tool onto the form or double-click it to add one at a default spot.
- Right-click context menus everywhere β on any control: Cut / Copy /
Paste / Duplicate / Delete, Bring to Front / Send to Back, Select
Parent, wire the default event, and jump to Properties/Events. Per-type
verbs match VS: Add Tab / Remove Tab on TabControls and tab pages,
Add Item / Edit Items⦠on MenuStrip/ToolStrip/StatusStrip, and Edit
Items⦠on ListBox, ComboBox, CheckedListBox, and DomainUpDown (one line
per item, written back as
Items.AddRange). Right-click the form or the component tray for their own menus. - Design canvas that mimics a real window (title bar, client area) with snap-to-grid placement, drag to move, 8-point resize handles β and grips on the window's own edges to resize the form/window itself.
- Properties window, Visual Studio style β properties grouped under
collapsible categories (Accessibility, Appearance, Behavior, Data, Design,
Focus, Layout, Window Style) with a Categorized / AβZ toggle and a
description pane at the bottom. Enums and booleans are dropdowns with their
defaults shown, colors get a picker + named/system color autocomplete,
fonts use the familiar
Segoe UI, 9pt, style=Boldformat, and WinFormsAnchoris edited with Top/Bottom/Left/Right toggle buttons. Explicitly-set values render bold, and clearing a value removes it from the file β exactly like VS. - Images and icons β
Image,BackgroundImage, and the formIcon(.png/.jpg/.gif/.bmp/.ico) are picked with a file dialog and imported the way Visual Studio does it: copied intoResources/, registered inProperties/Resources.resx, exposed through a regeneratedResources.Designer.cs, and referenced asProperties.Resources.namein the form code. Placement and scaling are full VS:ImageAlign,TextImageRelation,BackgroundImageLayout, and PictureBoxSizeModeβ all previewed live on the canvas. - Events panel β type a handler name (or accept the default) and UI Maker sets
the XAML attribute and generates the C# method stub in the
.xaml.cscode-behind. - Double-click a control to wire its default event, exactly like classic designers.
- Multi-select and alignment tools β Ctrl/Shift+click controls, drag the group, then use the toolbar to align edges, match sizes, or distribute evenly. β₯ Tab Order overlays TabIndex badges; click controls in sequence to re-number them (WinForms).
- Rename controls safely β edit
(Name)in the grid and, when the C# language service is installed, UI Maker performs a solution-wide symbol rename just like VS (with a safe Designer/code-behind fallback). Visual Basic renames are case-insensitive and updateHandlesclauses in the code-behind. Handler names and user-visible strings are kept. - Component tray β Timer, ToolTip, ContextMenuStrip, NotifyIcon, BackgroundWorker, ImageList, ErrorProvider, HelpProvider, BindingSource, FileSystemWatcher, Process, the file/color/font/folder dialogs, and the printing components drop into a tray below the form, VS-style, with their own properties and events (WinForms). Components that need extra NuGet packages on modern .NET (SerialPort, EventLog, PerformanceCounter, ServiceController, MessageQueue) are left out on purpose so generated code always compiles.
- Menus & status bars β MenuStrip, ToolStrip, and StatusStrip with an Items editor (one line per item) that generates the ToolStrip item classes in the Designer.cs; docked strips push each other for space like the real layout engine, and TabControl drops with two ready pages.
- Keyboard support: arrow keys nudge,
Shift+arrows move by grid,Deleteremoves,Ctrl+Dduplicates,Ctrl+X/Ctrl+C/Ctrl+Vcut, copy & paste β including onto a different form. Structural containers/items are guarded from shallow Cut/Duplicate operations until deep cloning can preserve their children.Esccloses menus and clears the selection.
The View Code button opens the raw XAML beside the designer. Edits flow both ways: change the markup and the canvas refreshes; move a control and the markup updates.
Status-bar buttons (and editor-title shortcuts) drive the .NET CLI for you:
- Build β builds with errors reported in the Problems panel.
- Run β builds and launches your app; the button turns into a red Stop while it runs and flips back when the app exits.
- Debug β builds, then attaches the right .NET debugger (
coreclrfor modern .NET,clrfor .NET Framework β uses the C# extension when installed; falls back to plain run otherwise). - Release β publishes a Release build, then jumps you to the output folder. Settings under UI Maker βΊ Publish turn this into a real installer-free distribution: Single File (one .exe), Self Contained (bundles the .NET runtime so the target PC needs nothing installed), and the target Runtime (win-x64 / win-x86 / win-arm64).
- Multi-target projects β Run, Debug, and Publish ask for the active target framework once and reuse it for the session; build/output discovery and the debugger all use that same TFM.
Builds are protected so they work on any dev machine: projects targeting
.NET Framework without the reference assemblies installed (error MSB3644) get
an offer to add the Microsoft.NETFramework.ReferenceAssemblies build helper,
and classic non-SDK projects are built with Visual Studio's MSBuild (found via
vswhere) since the dotnet CLI cannot load them. Apps whose manifest requests
administrator rights are detected too β Run builds them and launches the exe
through a UAC prompt instead of failing with "requires elevation".
UI Maker: New .NET Desktop Project asks for a template (WPF, Windows Forms,
or Console), a language (C# or Visual Basic), a target framework, a name, and
a folder β then generates a ready-to-run app and offers to open it.
Project Properties (side panel β Actions) is Visual Studio's Application
tab inside VS Code: output type, target framework (offering the SDKs actually
installed on your machine), assembly name, default namespace, startup object,
application icon and manifest (with Browse⦠pickers), plus the package/assembly
info (version, authors, product, description, copyright) for SDK-style
projects. Changes are written straight into the .csproj β an existing
property is updated in place, a cleared one is removed so the SDK default
applies again.
Old-format projects get a Convert to SDK style button right on this page β see below.
NuGet Packages (side panel β Actions) is the Manage NuGet Packages
window: Browse searches nuget.org (with an include prerelease toggle),
Installed lists the project's PackageReferences with one-click
uninstall, and Updates checks every installed package against the latest
stable release. Install/update/uninstall run dotnet add|remove package, so
the project file and restore stay consistent.
Old .NET Framework projects use a project format modern tooling can't load β
C# Dev Kit shows βThe project file is in unsupported formatβ. UI Maker:
Convert Project to SDK Style rewrites the .csproj as a minimal SDK-style
project with the same target framework, names, icon, manifest, and build
events; packages.config entries become PackageReferences; framework
references become implicit; Settings.settings/Resources.resx keep their
designers. The original file is kept as <name>.csproj.legacy.bak, so undoing
the conversion is a two-file rename.
App Settings (side panel β Actions) is the Visual Studio Project
Properties β Settings page, inside VS Code: a grid of settings your built app
remembers β name, type (string/int/bool/double/long/DateTime), User or
Application scope, and a default value. Saving writes the same
Properties/Settings.settings + Settings.Designer.cs pair Visual Studio
generates, so the project stays fully compatible with VS. In your app:
var name = Properties.Settings.Default.PlayerName; // read
Properties.Settings.Default.PlayerName = "Ada"; // change (User scope)
Properties.Settings.Default.Save(); // persist per userNew to .NET desktop apps? Guide β How to Build an App (side panel, the book
icon, or the Command Palette) opens an illustrated walkthrough: the workflow
from empty folder to shipped .exe, the full file tree of a WPF and a WinForms
project, which files are required / optional / generated, and what every single
file is for.
- Install the .NET SDK (8.0 or newer recommended).
- Install UI Maker (from source, see below β Marketplace listing planned).
- Run
UI Maker: New .NET Desktop Projectfrom the Command Palette (Ctrl+Shift+P), or open a folder that already contains a.csproj. - Click the UI Maker icon in the activity bar and pick a window under
XAML Windows β or right-click a
.xamlfile β Open Withβ¦ β UI Maker Designer (or click the designer icon in the editor title bar). - Drag controls from the toolbox, set properties, wire events.
- Hit βΆ Run in the status bar.
git clone <this repo>
cd uimaker
npm install
npm run compileBefore packaging or submitting a change, run the complete local gate:
npm run checkOpen the folder in VS Code and press F5 β an Extension Development Host window
launches with UI Maker loaded.
| Command | What it does |
|---|---|
UI Maker: New .NET Desktop Project |
Scaffold a WPF, WinForms, or Console app (C#/VB) via dotnet new |
UI Maker: New WPF Window |
Add a .xaml + code-behind pair (.xaml.cs / .xaml.vb) to the project |
UI Maker: New WinForms Form |
Add a Form in the project's language (.cs + .Designer.cs, or .vb + .Designer.vb) |
UI Maker: Open in Designer |
Open the current .xaml, *.Designer.cs, or *.Designer.vb file in the visual designer |
UI Maker: View XAML Source (Beside) |
Split view β XAML text editor next to the designer |
UI Maker: Build |
Build (Debug configuration) |
UI Maker: Run / Stop App |
Build and launch the app, or stop it if running |
UI Maker: Debug / Stop Debugging |
Build and debug the app, or stop the session |
UI Maker: Build Release (Publish) |
Publish a Release build (honors the single-exe settings) |
UI Maker: Stop Running App |
Terminate the app started by Run |
UI Maker: App Settings |
Grid editor for the settings your app remembers (Properties.Settings) |
UI Maker: Project Properties |
VS-style Application page β output type, framework, assembly name, icon, manifest, version info |
UI Maker: NuGet Packages |
Browse / install / update / remove nuget.org packages for the working project |
UI Maker: Convert Project to SDK Style |
Rewrite a classic .NET Framework .csproj in the modern SDK format (backup kept) |
UI Maker: Open Working Folder |
Show the current project folder in File Explorer |
UI Maker: Guide: How to Build an App |
Open the built-in guide (project anatomy, required vs. optional files) |
| Setting | Default | Description |
|---|---|---|
uimaker.gridSize |
8 |
Snap grid size in pixels on the design canvas |
uimaker.snapToGrid |
true |
Snap control positions/sizes to the grid |
uimaker.publish.singleFile |
false |
Build Release (Publish) produces one portable .exe |
uimaker.publish.selfContained |
false |
Bundle the .NET runtime so the target PC needs nothing installed |
uimaker.publish.runtime |
win-x64 |
Target runtime for single-file / self-contained publishing |
- The designer is a Custom Text Editor
bound to
*.xaml. It parses the XAML into a document model, renders an HTML approximation of each control on a canvas, and writes changes back as plain text β so the.xamlfile stays the single source of truth and normal git diffs still work. - Controls are positioned the same way Visual Studio's designer does it:
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="x,y,0,0"inside the rootGrid(orCanvas.Left/Canvas.Topwhen the root panel is aCanvas). - Build/Run/Release are thin, transparent wrappers over the
dotnetCLI β nothing proprietary, no lock-in, and everything it runs is visible in the terminal.
Files like MainWindow.xaml belong to WPF (or WinUI), the markup-based way
to build Windows desktop UIs. Windows Forms stores its layout in generated
code (*.Designer.cs in C#, *.Designer.vb in Visual Basic) instead β and UI
Maker designs all of them: open a .xaml window, a Form.Designer.cs, or a
Form.Designer.vb file in the designer and get the same drag-and-drop canvas,
properties panel, and event wiring. WinForms edits are surgical β only the
affected this.control.Prop = β¦; / Me.Control.Prop = β¦ statements change, so
diffs stay clean, and generated code follows the file's own dialect (Me. vs
this., qualified vs. implicit namespaces, VB literals like True and 9.75!).
Visual Basic events work the VB way: wiring an event writes a
Private Sub β¦ Handles Button1.Click into the code-behind (creating the stub
if needed), the events panel reads existing Handles clauses live, and
clearing an event removes just its Handles target β handler code is never
deleted.
- Nested layouts (Grid rows/columns, StackPanel, DockPanel, TabControl,
ScrollViewer, β¦) render faithfully, and any element can be selected,
resized, and edited in the panels β but drag-to-move is only offered for
Canvas children and absolutely-placed Grid children (
Left/Topalignment), because moving a stacked/docked child would rewrite its layout. - Styles are resolved for
{StaticResource}setters; templates, triggers, and bindings are ignored in the preview. - Images assigned in old projects as local form resources
(
resources.GetObject(...)with base64 in the form's.resx) render on the canvas when they are plain image bytes; BinaryFormatter-serialized ones cannot be previewed. Newly assigned images always use project resources. - Strip Items editing covers one level β nested sub-menus and per-item icons/events still need the code view (roadmapped).
- Structural WinForms containers can be deleted safely, but deep Cut/Copy/Duplicate of containers, generated menu items, and grid columns is intentionally disabled until every nested object can be cloned losslessly.
- Without the C# language service, control rename falls back to the Designer.cs/code-behind pair; project-wide references then need a manual rename.
- Visual Basic parity covers the WinForms designer (
*.Designer.vbround-tripping), Add Form/Window, Duplicate, New Class, event stubs withHandlesclauses, and control rename. Still C#-only for now: the App Settings editor, classicβSDK conversion, and importing new images as project resources in VB projects (My.Resourcesgeneration) β existing VB images render fine on the canvas. - The classic-project converter deliberately stops before writing when it finds custom imports/targets, conditional target frameworks, framework profiles, or package install-script/content semantics it cannot migrate safely.
- Saving from the designer normalizes the XAML formatting (like most visual designers).
- The visual preview is an approximation β always confirm with Run.
- Windows-only targets (WPF/WinForms are Windows frameworks).
- Windows Forms visual designer (
*.Designer.csround-tripping) - Nested layout rendering (StackPanel / DockPanel / Grid rows & columns / TabControl)
- Visual Studio-style categorized property grid (Anchor/Dock, colors, fonts, full form properties)
- Images & icons imported as project resources, with VS placement/scaling options
- Control renaming that safely updates the code-behind
- MenuStrip / ToolStrip / StatusStrip designers and a component tray (Timer, ToolTip, ContextMenuStrip, dialogs)
- Multi-select, alignment & distribution tools, tab-order view, copy/paste across forms
- Docked controls that push each other for space; TabControl and tab-page drops
- Visual Basic WinForms designer (
*.Designer.vbround-tripping,Handles-based events, VB scaffolding) - Remaining VB parity: App Settings editor, classicβSDK conversion,
My.Resourcesimage import - Sub-menu (nested menu item) designing and item icons
- Drag-reordering inside StackPanel / DockPanel children
- "Create an Installer" for multi-file releases (Inno Setup script generation)
- Style/resource editing and live theme preview
- Marketplace publishing and prebuilt VSIX releases
The long-term vision is a complete build-and-release studio, with a premium tier on top of the free core:
- Third-party UI library packs β design-time support for modern control suites like Guna UI, Telerik UI for WinForms, Krypton, and MaterialSkin: their controls in the toolbox, rendered previews, and the right NuGet references added automatically.
- Themed chrome presets β one-click looks such as Office-2007-style ribbons and menus, dark mode, and rounded "modern app" styling.
- One-click releasing β installer builds (Inno Setup), code signing, version bumping, and update feeds, from the same Release button.
Issues and pull requests are welcome. The codebase is intentionally small and heavily
commented β src/ holds the extension host code (TypeScript), media/ holds the
designer webview (plain JS/CSS).
MIT β see the LICENSE file.


