# Run Windows

> Build, launch, and drive the notes app on Windows (React Native Web hosted in a WebView2 over the in-process .NET MAUI backend). Use when running or building the Windows app, or driving/screenshotting its UI.

- Skill: `vortiago/run-windows` (Agent Skill)
- Install (CLI): `npx skillmds@latest add vortiago/run-windows`
- Raw SKILL.md: https://api.skillmd.com/api/skills/vortiago/run-windows/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Vortiago (https://skillmd.com/u/vortiago)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/vortiago/run-windows

---


# Run on Windows

React Native Web hosted in a **WebView2** pointed at the in-process backend on `http://127.0.0.1:5001`,
which serves both the UI and `/api` same-origin. In effect: the web edition inside an embedded WebView2
(the noted exception to ADR-0001; see `docs/adr/0006-windows-webview2-not-native-rn.md`). Prereqs:
.NET 10 + the `maui-windows` workload, Node 22, the WebView2 Runtime (preinstalled on current Windows),
PowerShell 7, and a free `:5001`. Run from the repo root.

## Build and run

`./scripts/run-windows.ps1` builds the RN-Web bundle (`npm run build:web` -> `src/Backend.Web/wwwroot`),
builds the MAUI Windows app (`-p:BuildPlatform=windows`, RID `win-x64`), and launches the exe. Done when
the app window shows the notes screen. Add `-SkipBuild` to launch the already-built exe.

The csproj ships the built `wwwroot` next to the exe and fails loudly (`EnsureWebArtifacts`) if the bundle
is missing, naming `npm run build:web`.

## End-to-end test

`./scripts/e2e-windows.ps1` builds, launches the app with WebView2 remote debugging on port 9222, then
drives the REAL WebView2 (Playwright `connectOverCDP`) through empty -> add -> persist (relaunch). Done when
it prints `Windows end-to-end test PASSED`. Add `-SkipBuild` for fast local iteration.

## Drive or screenshot the running UI

The app is a WebView2, so Playwright drives it over CDP (not a fresh browser). Launch a **Debug** build
with `$env:WEBVIEW2_REMOTE_DEBUGGING_PORT='9222'` — the app applies the switch through
`CoreWebView2EnvironmentOptions`, since newer WebView2 Runtimes drop `--remote-debugging-port` from
`WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS`. Then `chromium.connectOverCDP('http://127.0.0.1:9222')` and
locate the page whose URL contains `127.0.0.1:5001`.
RN `testID` becomes a `data-testid`, so `getByTestId('notes.text.input')` / `getByTestId('notes.add.button')`
work directly; `page.screenshot({ path })` captures it. See `src/Client/e2e/windows-cdp.mjs`.

