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);
}