Uno Platform WebAssembly and PWA
Patterns for building, debugging, optimizing, and deploying Uno Platform apps as WebAssembly applications and Progressive Web Apps.
Prerequisites
dotnet workload install wasm-tools
Verify: dotnet workload list should show wasm-tools installed.
Project Setup
The net9.0-browserwasm TFM is included by default in Uno Platform Single Project:
<TargetFrameworks>
net9.0-android;net9.0-ios;net9.0-browserwasm;net9.0-desktop;net9.0
</TargetFrameworks>
Enable PWA
Add via template or manually:
dotnet new unoapp -pwa
Or add manually:
<UnoFeatures>
<!-- other features -->
</UnoFeatures>
PWA manifest file (manifest.webmanifest) must have Content build action. Place in the WebAssembly platform folder or project root.
Bootstrapper (Uno.Wasm.Bootstrap 9.x)
Version 9.x targets .NET 9 and uses Microsoft.NET.Sdk.WebAssembly. Key changes from 8.x:
- •SDK changed from
Microsoft.NET.Sdk.WebtoMicrosoft.NET.Sdk.WebAssembly - •
Uno.Wasm.Bootstrap.DevServerpackage is no longer needed - •Compression handled by .NET SDK (not bootstrapper properties)
- •IDBFS not enabled by default; must be explicitly restored
Bootstrapper Version Mapping
| Bootstrapper | .NET Runtime |
|---|---|
| 9.x | .NET 9 |
| 10.x | .NET 10 |
| 8.x | .NET 8 |
Debugging
Visual Studio 2022
Ensure launchSettings.json contains the inspect URI in every profile:
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
Browser DevTools
- •Use browser F12 console for
Console.WriteLineoutput - •Source maps available in debug builds
- •Set breakpoints in browser Sources tab under
file://paths
Common Wasm Debug Issues
- •Blank screen: Check browser console for .NET runtime errors
- •Missing assets: Verify
Contentbuild action on static files - •CORS errors: Configure proper headers on hosting server
Hosting and Deployment
Azure Static Web Apps
# GitHub Actions workflow
- name: Publish
run: dotnet publish -c Release -f net9.0-browserwasm
- name: Deploy
uses: Azure/static-web-apps-deploy@v1
with:
app_location: "bin/Release/net9.0-browserwasm/publish/wwwroot"
Nginx
Required MIME types for Wasm:
types {
application/wasm wasm;
application/octet-stream clr;
application/json json;
application/javascript js;
}
# Enable compression
gzip on;
gzip_types application/wasm application/javascript application/json;
# Cache immutable assets
location /_framework/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
Local Testing
dotnet tool install -g dotnet-serve dotnet publish -c Debug -f net9.0-browserwasm dotnet serve -d bin/Debug/net9.0-browserwasm/publish/wwwroot -p 8000
Performance Optimization
AOT Compilation
Ahead-of-Time compilation improves runtime performance at the cost of larger payloads and longer builds.
<PropertyGroup Condition="'$(TargetFramework)' == 'net9.0-browserwasm'">
<RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>
Payload Size Reduction
- •Enable trimming (default in Release): removes unused code
- •Use Brotli compression on the web server
- •Lazy-load assemblies for large features not needed at startup
- •Minimize embedded resources: large images and assets inflate the initial download
Startup Optimization
- •Keep initial visual tree minimal (use
x:Loadfor deferred content) - •Defer non-critical service registration
- •Use splash screen during .NET runtime initialization
Threading
WebAssembly threading is not supported in Uno Platform on .NET 9. Microsoft's runtime changes prevent managed code from running on the main JavaScript thread. Support may return in future .NET 10 previews.
Workarounds:
- •Use
Task.Runfor CPU-bound work (runs on thread pool when available) - •Keep UI thread responsive with async/await
- •Avoid synchronous blocking calls
PWA Features
Service Worker
Configured automatically when PWA is enabled. Handles offline caching of app shell and assets.
Manifest
{
"name": "My Uno App",
"short_name": "UnoApp",
"start_url": "./",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#6200EE",
"icons": [
{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
Install Prompt
PWA install is handled by the browser. Ensure manifest and service worker are correctly configured for the browser to show the install prompt.
Common Mistakes
- •Forgetting
dotnet workload install wasm-toolsbefore building - •Using
Microsoft.NET.Sdk.Webinstead ofMicrosoft.NET.Sdk.WebAssemblywith bootstrapper 9.x - •Not setting proper MIME types on hosting server (especially
application/wasm) - •Expecting threading to work (not supported on .NET 9 Wasm)
- •Not adding
inspectUritolaunchSettings.jsonfor debugging - •Using deprecated bootstrapper properties from 8.x (see migration list in docs)
Detailed References
- •references/01-setup-bootstrapper.md - Read when setting up Wasm project or upgrading bootstrapper
- •references/02-debugging.md - Read when debugging Wasm apps in VS2022 or browser
- •references/03-hosting-deployment.md - Read when deploying to Azure, Nginx, Apache, or GitHub Pages
- •references/04-performance-pwa.md - Read when optimizing payload, startup, or adding PWA features