Skip to content

Platform Differences

Mythetech.Framework supports both Desktop and WebAssembly platforms. This guide covers the key differences.

Feature Availability

FeatureDesktopWebAssembly
UI Components
MessageBus
Plugins (Dynamic Load)
Plugins (Static Reference)
MCP Tools
MCP stdio Transport
Persistent StorageLiteDBlocalStorage
File DialogsNativeWASM File API
Link OpeningNativeBrowser

Plugin Loading

Desktop

Plugins can be loaded dynamically at runtime:

csharp
// Load from directory
await app.Services.UsePluginsAsync("plugins");

This scans the directory, loads assemblies, and discovers plugins automatically.

WebAssembly

Dynamic assembly loading isn't supported in WASM. Plugins must be referenced at compile time:

csharp
// Add project reference in .csproj
<ProjectReference Include="..\MyPlugin\MyPlugin.csproj" />

// Load the referenced assembly
await app.Services.UsePluginAsync(typeof(MyPlugin.Manifest).Assembly);

Storage

Desktop (LiteDB)

  • File-based NoSQL database
  • Stored in application data directory
  • Supports complex object graphs
  • No size limits (filesystem limited)
  • Transactions supported
csharp
// Works with complex types
await storage.SetAsync("user", new User
{
    Profile = new Profile { /* nested data */ }
});

WebAssembly (localStorage)

  • Browser localStorage API
  • Serialized as JSON
  • ~5MB typical limit
  • No transactions
  • Cleared with browser data
csharp
// Same API, different implementation
await storage.SetAsync("user", simpleUserData);

WARNING

Keep WebAssembly storage data simple and small due to localStorage limitations.

File Operations

Desktop

Full access to native file dialogs:

csharp
// Open file dialog
var file = await fileService.OpenFileAsync(new OpenFileOptions
{
    Title = "Select a file",
    Filters = [new("Text Files", "*.txt")]
});

// Save file dialog
await fileSaveService.SaveFileAsync("output.txt", data);

WebAssembly

Uses browser File System Access API:

csharp
// Same interface, browser implementation
var file = await fileService.OpenFileAsync(options);

// Download-style save
await fileSaveService.SaveFileAsync("output.txt", data);

TIP

The WASM implementation uses KristofferStrube.Blazor.FileSystemAccess for File System Access API integration.

Desktop

Opens in system default browser:

csharp
linkOpenService.OpenUrl("https://example.com");
// Opens in Chrome, Firefox, Edge, etc.

WebAssembly

Opens in browser context:

csharp
linkOpenService.OpenUrl("https://example.com");
// Opens in new tab (same browser)

MCP

Desktop

Full MCP support with stdio transport:

csharp
builder.Services.AddMcp(options =>
{
    options.ServerName = "MyApp";
    options.ServerVersion = "1.0.0";
});

// Start MCP server
await messageBus.PublishAsync(new EnableMcpServerMessage());

WebAssembly

Tools can be registered but stdio transport isn't available:

csharp
// Tools can be registered
builder.Services.AddMcpTools();

// But no transport available (HTTP transport planned)

Detecting Platform

csharp
// Check runtime platform
if (OperatingSystem.IsBrowser())
{
    // WebAssembly-specific code
}
else
{
    // Desktop-specific code
}

Or use the Framework's platform service:

csharp
[Inject]
private IPlatformService Platform { get; set; }

if (Platform.IsDesktop)
{
    // Desktop features
}

Best Practices

  1. Check for null services — Platform-specific services may be null
  2. Use abstractions — Prefer ILinkOpenService over direct APIs
  3. Test on both platforms — Behavior can differ subtly
  4. Size storage carefully — WASM has limited localStorage
  5. Plan for missing features — Gracefully degrade when features aren't available
csharp
// Example: Graceful degradation
if (fileSaveService != null)
{
    await fileSaveService.SaveFileAsync(filename, data);
}
else
{
    // Fallback: show data in dialog for copy/paste
    await dialogService.ShowMessageBox("Export", dataAsString);
}