Publishing Desktop Apps
This guide covers publishing Miko apps for Windows, macOS, and Linux using the Miko.Windowing desktop host.
Runtime vs self-contained
Miko desktop apps can be published in two modes:
- Framework-dependent — requires the .NET 10 runtime to be installed on the target machine. Produces a small binary (~few MB).
- Self-contained — bundles the .NET runtime with your app. No runtime installation required, but the binary is larger (~60–80 MB depending on platform and trimming).
Framework-dependent publish
dotnet publish MyApp.Desktop.csproj -c Release -r win-x64
dotnet publish MyApp.Desktop.csproj -c Release -r osx-arm64
dotnet publish MyApp.Desktop.csproj -c Release -r linux-x64The output is in bin/Release/net10.0/<RID>/publish/. Distribute the entire folder. Users need the .NET 10 runtime installed.
Self-contained publish
dotnet publish MyApp.Desktop.csproj -c Release -r win-x64 --self-contained
dotnet publish MyApp.Desktop.csproj -c Release -r osx-arm64 --self-contained
dotnet publish MyApp.Desktop.csproj -c Release -r linux-x64 --self-containedThe output includes the .NET runtime. No installation required on the target machine.
Platform-specific notes
Windows
The output is a .exe file plus supporting DLLs. Distribute the entire publish/ folder or package it as a zip / installer.
macOS
The output is a native Mach-O executable. For a proper .app bundle:
- Create
MyApp.app/Contents/MacOS/andMyApp.app/Contents/Resources/ - Copy the published executable and DLLs into
MacOS/ - Add an
Info.plistinContents/withCFBundleExecutableset to your executable name
For distribution outside the App Store, you must sign and notarize the app with a Developer ID certificate.
Linux
The output is a native ELF executable. Important: the SkiaSharp.NativeAssets.Linux package dependency ships libSkiaSharp.so. The target system must have:
- A working OpenGL driver (the desktop host renders with OpenGL on Windows and Linux, and with Metal on macOS)
- glibc (the library is not compatible with musl-based distros like Alpine)
Miko.Windowing depends on SkiaSharp.NativeAssets.Linux, so libSkiaSharp.so is included in the linux-x64 publish output automatically.
Trimming and Native AOT
Miko 1.0.0-preview.1 does not support trimming or Native AOT for desktop apps, and the templates do not enable PublishTrimmed or PublishAot. The desktop host (Silk.NET, Vortice) and some dependencies (Svg.Skia, ExCSS) still produce trim warnings. iOS and Android builds are trimmed and AOT-compiled by their SDKs.
DevTools in Release builds
The templates reference Miko.DevTools only in the Debug configuration:
<PackageReference Include="Miko.DevTools" Version="1.0.0-preview.1" Condition="'$(Configuration)' == 'Debug'" />And the startup code wraps AddDevTools() in #if DEBUG:
#if DEBUG
builder.AddDevTools();
#endifRelease builds therefore contain neither Miko.DevTools nor its F12 inspector. (Silk.NET and its GLFW native library are still in the output: they are the desktop host itself, Miko.Windowing.)
The template code uses //-:cnd:noEmit markers around #if DEBUG so that dotnet new keeps the directive; in your own app a plain #if DEBUG is enough.
Simulator and MCP server
The Miko.Simulator host and Miko.McpServer are development tools only. The MCP server listens on localhost:5800 without authentication and exposes DOM read, screenshot, and click simulation. Never ship these packages in a distributed app.
The templates reference them only from the Simulator head project, which is not meant for distribution.
What to distribute
For end users, distribute:
- The Desktop startup project published as shown above (framework-dependent or self-contained)
- Do not include the Simulator project or MCP server in distributed builds
Release builds of the Desktop head do not reference DevTools (the Condition shown above), so nothing has to be removed by hand.