Set up a Windows app project for MSIX packaging, Windows SDK access, or Windows API usage. Use when adding Windows support to an Electron, .NET, C++, Rust, Flutter, or Tauri project, or restoring SDK packages after cloning.
Use this skill when:
Install the winapp CLI before running any commands:
# Via winget (recommended for non-Node projects)
winget install Microsoft.WinAppCli --source winget
# Via npm (recommended for Electron/Node projects — includes Node.js SDK)
npm install --save-dev @microsoft/winappcli
You need an existing app project — winapp init does not create new projects, it adds Windows platform files to your existing codebase.
<!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json --> <!-- auto-generated from cli-schema.json -->Already have a ? .NET projects that already have a packaging manifest (e.g., WinUI 3 apps or projects with an existing MSIX packaging setup) likely . Ensure your references the NuGet package and has the right properties for packaged builds (e.g., ). WinUI 3 apps created from Visual Studio templates are typically already fully configured — you can go straight to building and using or .
Package.appxmanifestwinapp init.csprojMicrosoft.WindowsAppSDK<WindowsPackageType>MSIX</WindowsPackageType>winapp runwinapp packageappxmanifest.xml is the most important file winapp creates — it declares your app's identity, capabilities, and visual assets. Most winapp commands require it (package, run, cert generate --manifest).
winapp.yaml is only needed for SDK version management via restore/update. Projects that already reference Windows SDK packages (e.g., via NuGet in a .csproj) can use winapp commands without it.
.winapp/ is the local folder where SDK packages and generated projections (e.g., CppWinRT headers) are stored. This folder is .gitignored — team members recreate it via winapp restore.
# Interactive — prompts for app name, publisher, SDK channel, etc.
winapp init .
# Non-interactive — accepts all defaults (stable SDKs, current folder name as app name)
winapp init --use-defaults
# Skip SDK installation (just manifest + config)
winapp init --use-defaults --setup-sdks none
# Install preview SDKs instead of stable
winapp init --use-defaults --setup-sdks preview
After init, your project will contain:
appxmanifest.xml — package identity and capabilitiesAssets/ — default app icons (Square44x44Logo, Square150x150Logo, etc.)winapp.yaml — SDK version pinning for restore/update.winapp/ — downloaded SDK packages and generated projections.gitignore update — excludes .winapp/ and devcert.pfx# Reinstall SDK packages from existing winapp.yaml (does not change versions)
winapp restore
# Restore into a specific directory
winapp restore ./my-project
Use restore when you clone a repo that already has winapp.yaml but no .winapp/ folder.
# Check for and install latest stable SDK versions
winapp update
# Switch to preview channel
winapp update --setup-sdks preview
This updates winapp.yaml with the latest versions and reinstalls packages.
# Register debug identity and launch app from build output
winapp run ./bin/Debug
# Launch with custom manifest and pass arguments to the app
winapp run ./dist --manifest ./out/AppxManifest.xml --args "--my-flag value"
# Register identity without launching (useful for attaching a debugger manually)
winapp run ./bin/Debug --no-launch
# Launch and capture OutputDebugString messages and first-chance exceptions
# Note: prevents other debuggers (VS, VS Code) from attaching — use --no-launch if you need those instead
winapp run ./bin/Debug --debug-output
Use winapp run during iterative development — it creates a loose layout package, registers a debug identity, and launches the app in one step. For identity-only registration without loose layout, use winapp create-debug-identity instead.
run and create-debug-identitywinapp run | create-debug-identity | |
|---|---|---|
| Registers | Full loose layout package (entire folder) | Sparse package (single exe) |
| App launch | Winapp launches via AUMID or alias | You launch the exe yourself |
| Simulates MSIX | Yes — closest to production | No — identity only |
| Files | Copied to AppX layout dir | Exe stays in place |
| Best for | Most frameworks (.NET, C++, Rust, Flutter, Tauri) | Electron, or F5 startup debugging |
Default to winapp run. Use create-debug-identity when you need your IDE to launch and debug the exe directly (startup debugging), or when the exe is separate from your source (Electron).
For console apps, add --with-alias to preserve stdin/stdout in the current terminal.
--debug-outputcaveat: CapturesOutputDebugStringbut attaches winapp as the debugger — you cannot also attach VS Code or WinDbg. Use--no-launchif you need your own debugger.
For full debugging scenarios and IDE setup, see the Debugging Guide.
winapp init --use-defaults in your existing projectappxmanifest.xml to add capabilities your app needs (e.g., runFullTrust, internetClient)winapp run ./bin/Debug to register identity and launch for debuggingwinapp package ./bin/Release --cert ./devcert.pfx to create MSIX--use-defaults (alias: --no-prompt) in CI/CD pipelines and scripts to avoid interactive promptsappxmanifest.xml without SDK setup, use winapp manifest generate instead of initwinapp init is idempotent for the config file — re-running it won't overwrite an existing winapp.yaml unless you use --config-onlynpm install --save-dev @microsoft/winappcli and use npx winapp init instead of the standalone CLIwinapp-manifest to customize your appxmanifest.xmlwinapp-package to create an MSIX installerwinapp-signing for certificate generationwinapp-troubleshoot for a command selection flowchart| Error | Cause | Solution |
|---|---|---|
| "winapp.yaml not found" | Running restore/update without config | Run winapp init first, or ensure you're in the right directory |
| "Directory not found" | Target directory doesn't exist | Create the directory first or check the path |
| SDK download fails | Network issue or firewall | Ensure internet access; check proxy settings |
init prompts unexpectedly in CI | Missing --use-defaults flag | Add --use-defaults to skip all prompts |
winapp initStart here for initializing a Windows app with required setup. Sets up everything needed for Windows app development: creates appxmanifest.xml with default assets, creates winapp.yaml for version management, and downloads Windows SDK and Windows App SDK packages and generates projections. Interactive by default (use --use-defaults to skip prompts). Use 'restore' instead if you cloned a repo that already has winapp.yaml. Use 'manifest generate' if you only need a manifest, or 'cert generate' if you need a development certificate for code signing.
| Argument | Required | Description |
|---|---|---|
<base-directory> | No | Base/root directory for the winapp workspace, for consumption or installation. |
| Option | Description | Default |
|---|---|---|
--config-dir | Directory to read/store configuration (default: current directory) | (none) |
--config-only | Only handle configuration file operations (create if missing, validate if exists). Skip package installation and other workspace setup steps. | (none) |
--ignore-config | Don't use configuration file for version management | (none) |
--no-gitignore | Don't update .gitignore file | (none) |
--setup-sdks | SDK installation mode: 'stable' (default), 'preview', 'experimental', or 'none' (skip SDK installation) | (none) |
--use-defaults | Do not prompt, and use default of all prompts | (none) |
winapp restoreUse after cloning a repo or when .winapp/ folder is missing. Reinstalls SDK packages from existing winapp.yaml without changing versions. Requires winapp.yaml (created by 'init'). To check for newer SDK versions, use 'update' instead.
| Argument | Required | Description |
|---|---|---|
<base-directory> | No | Base/root directory for the winapp workspace |
| Option | Description | Default |
|---|---|---|
--config-dir | Directory to read configuration from (default: current directory) | (none) |
winapp updateCheck for and install newer SDK versions. Updates winapp.yaml with latest versions and reinstalls packages. Requires existing winapp.yaml (created by 'init'). Use --setup-sdks preview for preview SDKs. To reinstall current versions without updating, use 'restore' instead.
| Option | Description | Default |
|---|---|---|
--setup-sdks | SDK installation mode: 'stable' (default), 'preview', 'experimental', or 'none' (skip SDK installation) | (none) |
winapp runCreates packaged layout, registers the Application, and launches the packaged application.
| Argument | Required | Description |
|---|---|---|
<input-folder> | Yes | Input folder containing the app to run |
| Option | Description | Default |
|---|---|---|
--args | Command-line arguments to pass to the application | (none) |
--debug-output | Capture OutputDebugString messages and first-chance exceptions from the launched application. Only one debugger can attach to a process at a time, so other debuggers (Visual Studio, VS Code) cannot be used simultaneously. Use --no-launch instead if you need to attach a different debugger. Cannot be combined with --no-launch or --json. | (none) |
--json | Format output as JSON | (none) |
--manifest | Path to the appxmanifest.xml (default: auto-detect from input folder or current directory) | (none) |
--no-launch | Only create the debug identity and register the package without launching the application | (none) |
--output-appx-directory | Output directory for the loose layout package. If not specified, a directory named AppX inside the input-folder directory will be used. | (none) |
--unregister-on-exit | Unregister the development package after the application exits. Only removes packages registered in development mode. | (none) |
--with-alias | Launch the app using its execution alias instead of AUMID activation. The app runs in the current terminal with inherited stdin/stdout/stderr. Requires a uap5:ExecutionAlias in the manifest. Use "winapp manifest add-alias" to add an execution alias to the manifest. | (none) |