microsoft / microsoft/WinAppVSCE

[Feature]: Hot Reload for WinUI

Open
#58 0 comments 0 reactions 1 assignee View on GitHub

@chiaramooney is already working on this.

Since Jul 20, 2026.

enhancement
Dominant language
TypeScript
Stars
13
Forks
3
Avg merge
6d 1h
Merged PRs (30d)
11

Description

1. Summary

Bring run + hot reload into the VS Code inner loop for WinUI/Windows apps: press F5 (or a Run button)
to launch the app with package identity then apply C# and XAML edits to the
running app without restarting
, preserving app state.

It extends the extension's existing winapp debug type and adds "apply on save" behavior and a Hot Reload toolbar/status.

Image

2. Problem / motivation

WinUI 3 has no XAML hot reload outside Visual Studio, and even C# hot reload in VS Code is limited for WinUI. Today the extension's F5 flow launches and attaches, but every code/XAML change requires a full rebuild + relaunch. Closing this gap would be a big productivity win.

3. Prior art & competitive analysis

Tool Approach
Visual Studio Hot Reload C# (EnC/MetadataUpdater) + XAML hot reload; deep runtime integration; WinUI supported.
dotnet watch C# hot reload from CLI; no XAML hot reload for WinUI 3; XAML change → rebuild.
C# Dev Kit (VS Code) C# hot reload in some scenarios; no WinUI XAML hot reload.
Uno Hot Reload (VS Code) Embeds a hot-reload agent in the app; editor relays XAML/C# deltas over a socket.

Takeaway: the C# side can leverage the .NET runtime's MetadataUpdater/EnC (as VS/dotnet watch
do); the XAML side needs a WinUI hot-reload agent in the app process (B3), Uno-style, that patches
the visual tree.

4. Goals / non-goals

Goals

  • One-gesture Run (F5 and a WinApp Run button/menu) that launches with identity via B2 and attaches
    the right debugger (reusing the existing winapp debug type).
  • Hot Reload on save (and an explicit "Apply Changes" command) for supported C# edits and XAML edits,
    with state preserved.
  • Clear status: a Hot Reload status-bar item + toolbar button (active/applying/failed), and a concise
    notification on apply or on rude-edit fallback.
  • Graceful degradation: when an edit can't be hot-reloaded (rude edit), offer a one-click Restart.
  • Optional auto-build integration so Run doesn't require a manual pre-build (addresses a known F5 gap).
  • Works in VS Code / Cursor / Windsurf.

Non-goals

  • The hot-reload runtime/agent itself (that's B3); C5 orchestrates and surfaces it.
  • Live visual-tree inspection / property editing (that's C6).
  • Edit-and-continue for native C++ beyond what the underlying debugger supports.

5. Proposed implementation

VS Code (C5)                         Running app (identity via B2)
  Run button / F5 ─▶ winapp run ────▶  app process ◀── B3 hot-reload agent (in-proc)
  file save ─▶ debounce ─▶ compute delta                 ▲
     ├─ C# delta ─▶ MetadataUpdater/EnC via debug session │ patch visual tree / apply IL
     └─ XAML delta ─▶ send to B3 agent ─────────────────────┘
  status bar / toolbar / notifications ◀── apply results (ok / rude edit / error)
  • Launch: reuse/extend the winapp debug type.
  • C# hot reload: drive via the .NET runtime update mechanism through the active debug session
    (coordinate with the C# extension / coreclr). Where the C# extension owns EnC, integrate rather than
    duplicate; otherwise apply MetadataUpdater deltas ourselves through B2/B3.
  • XAML hot reload: on XAML save, send the changed document (or delta) to the B3 agent in the app,
    which re-parses and patches the live visual tree (Uno-style). Preserve DataContext/state.
  • Change detection: watch dirty docs; debounce; classify edit → applicable vs rude; on rude edit,
    prompt Restart.
  • Feedback: status-bar item (🔥 Hot Reload), toolbar button in the debug toolbar, and Debug Console
    log lines mirroring what the CLI reports.

6. API / contribution surface

"contributes": {
  "commands": [
    { "command": "winapp.run", "title": "WinApp: Run Application", "category": "WinApp" },
    { "command": "winapp.hotReload.applyChanges", "title": "WinApp: Apply Hot Reload Changes", "category": "WinApp" },
    { "command": "winapp.hotReload.restart", "title": "WinApp: Restart (rude edit)", "category": "WinApp" },
    { "command": "winapp.hotReload.toggleOnSave", "title": "WinApp: Toggle Hot Reload on Save", "category": "WinApp" }
  ],
  "configuration": {
    "winapp.hotReload.enable": { "type": "boolean", "default": true },
    "winapp.hotReload.onSave": { "type": "boolean", "default": true },
    "winapp.hotReload.xaml": { "type": "boolean", "default": true },
    "winapp.hotReload.csharp": { "type": "boolean", "default": true },
    "winapp.run.autoBuild": { "type": "boolean", "default": true }
  },
  "debuggers": [{ "type": "winapp", "//": "extend existing with hotReload launch attrs" }]
}
  • New launch.json attrs (winapp debug type): hotReload: boolean, hotReloadOnSave: boolean.
  • Editor UI: debug-toolbar button + status-bar item + apply/rude-edit notifications.

7. Design tradeoffs & alternatives

  • Reuse C# extension's EnC vs own the C# delta path. Reuse avoids duplicating a mature EnC engine and
    reduces conflicts, but depends on that extension's public surface; owning it via B2/B3 is more control
    but more work and possible contention with the debugger. Prefer coordination; fall back to owning only
    if necessary.

8. Open questions

  1. Does B3 apply C# deltas itself, or do we route through the C# extension's EnC?
  2. What's the B3 XAML agent's protocol (whole-doc vs delta; what state survives)?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.